Deploying Element
Introduction
Element is a feature-rich, open-source messaging and collaboration client built on the Matrix protocol. It provides end-to-end encrypted communication, voice and video calls, file sharing, and seamless integration with Matrix homeservers. Element combines the security and privacy of decentralized communication with a modern, user-friendly interface that makes it ideal for teams, communities, and organizations.
Deploying Element on Klutch.sh provides you with a scalable, secure, and production-ready infrastructure for your communication platform. With automated Dockerfile detection, persistent storage support, and seamless GitHub integration, Klutch.sh makes it simple to deploy and manage your Element instance. This guide walks you through the complete deployment process, from initial setup to production configuration, ensuring your messaging platform is reliable, performant, and ready to scale.
Whether you’re deploying Element for the first time or migrating an existing instance, this comprehensive guide covers everything you need: Dockerfile configuration, Matrix homeserver connection, persistent storage, environment variables, and production best practices for secure team communication.
Prerequisites
Before deploying Element on Klutch.sh, ensure you have the following:
- A Klutch.sh account
- A GitHub repository for your Element deployment project
- A Matrix homeserver (such as Synapse or Dendrite) already deployed and accessible
- Basic knowledge of Docker and containerization concepts
- Understanding of the Matrix protocol and configuration
- (Optional) Custom domain for your Element instance
Project Structure
A typical Element deployment repository should contain:
element-docker/├─ Dockerfile├─ config.json├─ nginx.conf├─ docker-entrypoint.sh├─ .env.example└─ README.mdFor development, you may also include Docker Compose files for local testing, though Klutch.sh does not support Docker Compose for deployment. The compose file would only be used for local development workflows.
1. Prepare Your Element Repository
Setting Up Your Repository
-
Create a new repository on GitHub for your Element deployment, or fork an existing Element Web repository.
-
Create a Dockerfile in the root of your repository (see detailed examples in the next section).
-
Prepare configuration files: Create a
config.jsonfile with your Matrix homeserver details. Keep sensitive credentials out of your Git repository—use environment variables instead. -
Connect your repository to GitHub: Push your code to GitHub, which is the supported Git source for Klutch.sh.
For detailed information on repository setup and GitHub integration, see the Klutch.sh Quick Start Guide.
2. Creating a Production-Ready Dockerfile
Klutch.sh automatically detects a Dockerfile if present in the root directory of your repository. When a Dockerfile is detected, Klutch.sh will use it to build your container image, eliminating the need to manually specify Docker as a deployment option.
Basic Dockerfile for Element
Here’s a foundational Dockerfile for deploying Element Web:
FROM node:18-alpine AS builder
# Set working directoryWORKDIR /app
# Install dependenciesRUN apk add --no-cache git python3 make g++
# Clone Element Web repositoryRUN git clone --depth 1 --branch v1.11.50 https://github.com/vector-im/element-web.git .
# Install dependenciesRUN yarn install --frozen-lockfile
# Build Element WebRUN yarn build
# Production stageFROM nginx:alpine
# Copy built Element Web filesCOPY --from=builder /app/webapp /usr/share/nginx/html
# Copy nginx configurationCOPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy Element configurationCOPY config.json /usr/share/nginx/html/config.json
# Expose portEXPOSE 80
# Start nginxCMD ["nginx", "-g", "daemon off;"]Production-Optimized Dockerfile with Custom Configuration
For a more robust production deployment with configurable Matrix homeserver:
FROM node:18-alpine AS builder
# Set working directoryWORKDIR /app
# Install build dependenciesRUN apk add --no-cache \ git \ python3 \ make \ g++ \ curl
# Clone Element Web at specific versionARG ELEMENT_VERSION=v1.11.50RUN git clone --depth 1 --branch ${ELEMENT_VERSION} https://github.com/vector-im/element-web.git .
# Install dependenciesRUN yarn install --frozen-lockfile --network-timeout 100000
# Build Element Web with optimizationsENV NODE_ENV=productionRUN yarn build
# Production stageFROM nginx:alpine
# Install runtime dependenciesRUN apk add --no-cache \ bash \ curl \ envsubst
# Create directory structureRUN mkdir -p /usr/share/nginx/html /etc/nginx/conf.d
# Copy built Element Web filesCOPY --from=builder /app/webapp /usr/share/nginx/html
# Copy configuration filesCOPY nginx.conf /etc/nginx/conf.d/default.confCOPY config.json /usr/share/nginx/html/config.json
# Copy entrypoint script for configuration templatingCOPY docker-entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Create non-root user for nginx (if not already exists)RUN addgroup -g 101 -S nginx 2>/dev/null || true && \ adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx 2>/dev/null || true
# Set proper permissionsRUN chown -R nginx:nginx /usr/share/nginx/html && \ chown -R nginx:nginx /var/cache/nginx && \ chown -R nginx:nginx /var/log/nginx && \ chown -R nginx:nginx /etc/nginx/conf.d && \ touch /var/run/nginx.pid && \ chown -R nginx:nginx /var/run/nginx.pid
# Switch to non-root userUSER nginx
# Expose portEXPOSE 8080
# Use entrypoint for configurationENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
# Start nginxCMD ["nginx", "-g", "daemon off;"]Dockerfile with Multi-Homeserver Support
For advanced deployments supporting multiple Matrix homeservers:
FROM node:18-alpine AS builder
WORKDIR /app
# Install build dependenciesRUN apk add --no-cache \ git \ python3 \ make \ g++ \ curl \ jq
# Clone Element WebARG ELEMENT_VERSION=v1.11.50RUN git clone --depth 1 --branch ${ELEMENT_VERSION} https://github.com/vector-im/element-web.git .
# Install and buildRUN yarn install --frozen-lockfile --network-timeout 100000 && \ NODE_ENV=production yarn build
# Production stageFROM nginx:alpine
# Install runtime utilitiesRUN apk add --no-cache \ bash \ curl \ jq \ gettext
WORKDIR /usr/share/nginx/html
# Copy built applicationCOPY --from=builder /app/webapp .
# Copy configuration templateCOPY config.template.json /usr/share/nginx/html/config.template.json
# Copy nginx configurationCOPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy entrypoint scriptCOPY docker-entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Expose portEXPOSE 8080
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]CMD ["nginx", "-g", "daemon off;"]3. Configuration Files
Element config.json
Create a config.json file with your Matrix homeserver configuration:
{ "default_server_config": { "m.homeserver": { "base_url": "https://matrix.example.com", "server_name": "example.com" }, "m.identity_server": { "base_url": "https://vector.im" } }, "brand": "Element", "integrations_ui_url": "https://scalar.vector.im/", "integrations_rest_url": "https://scalar.vector.im/api", "integrations_widgets_urls": [ "https://scalar.vector.im/_matrix/integrations/v1", "https://scalar.vector.im/api", "https://scalar-staging.vector.im/_matrix/integrations/v1", "https://scalar-staging.vector.im/api", "https://scalar-staging.riot.im/scalar/api" ], "hosting_signup_link": "https://element.io/matrix-services?utm_source=element-web&utm_medium=web", "bug_report_endpoint_url": "https://element.io/bugreports/submit", "uisi_autorageshake_app": "element-auto-uisi", "showLabsSettings": true, "roomDirectory": { "servers": [ "matrix.org", "gitter.im", "libera.chat" ] }, "enable_presence_by_hs_url": { "https://matrix.org": false, "https://matrix-client.matrix.org": false }, "terms_and_conditions_links": [ { "url": "https://element.io/privacy", "text": "Privacy Policy" }, { "url": "https://element.io/terms-of-service", "text": "Terms of Service" } ], "privacy_policy_url": "https://element.io/privacy", "jitsi": { "preferred_domain": "meet.element.io" }, "element_call": { "url": "https://call.element.io", "use_exclusively": false, "participant_limit": 8, "brand": "Element Call" }, "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=YOUR_MAPTILER_KEY"}Nginx Configuration
Create an nginx.conf file for serving Element:
server { listen 8080; server_name _;
root /usr/share/nginx/html; index index.html;
# Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://matrix.org https://*.matrix.org wss://*.matrix.org; media-src 'self' https://matrix.org https://*.matrix.org; frame-src 'self' https://www.recaptcha.net https://recaptcha.net;" always;
# Gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_vary on; gzip_min_length 1000;
# Main application location / { try_files $uri $uri/ /index.html; }
# Element config.json location = /config.json { alias /usr/share/nginx/html/config.json; add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; }
# Static assets with long cache location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; }
# Health check endpoint location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; }
# Deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; }}Docker Entrypoint Script
Create a docker-entrypoint.sh script for dynamic configuration:
#!/bin/bashset -e
# Replace environment variables in config.jsonif [ -n "$MATRIX_HOMESERVER_URL" ]; then echo "Configuring Matrix homeserver: $MATRIX_HOMESERVER_URL"
# Create config.json from template or environment variables cat > /usr/share/nginx/html/config.json <<EOF{ "default_server_config": { "m.homeserver": { "base_url": "${MATRIX_HOMESERVER_URL}", "server_name": "${MATRIX_SERVER_NAME:-matrix.org}" }, "m.identity_server": { "base_url": "${MATRIX_IDENTITY_SERVER_URL:-https://vector.im}" } }, "brand": "${ELEMENT_BRAND:-Element}", "integrations_ui_url": "${INTEGRATIONS_UI_URL:-https://scalar.vector.im/}", "integrations_rest_url": "${INTEGRATIONS_REST_URL:-https://scalar.vector.im/api}", "showLabsSettings": ${SHOW_LABS_SETTINGS:-true}, "jitsi": { "preferred_domain": "${JITSI_DOMAIN:-meet.element.io}" }, "element_call": { "url": "${ELEMENT_CALL_URL:-https://call.element.io}", "use_exclusively": ${ELEMENT_CALL_EXCLUSIVE:-false}, "participant_limit": ${ELEMENT_CALL_LIMIT:-8} }}EOFfi
# Verify config.json existsif [ ! -f /usr/share/nginx/html/config.json ]; then echo "ERROR: config.json not found!" exit 1fi
echo "Element configuration ready"echo "Starting nginx..."
# Execute the main commandexec "$@"4. Persistent Storage Configuration
Element is a static web application, but you may want persistent storage for custom themes, configuration backups, or logs.
Recommended Volume Mount Points
Configure the following persistent volumes in the Klutch.sh dashboard if needed:
-
Custom Themes: Mount path
/usr/share/nginx/html/themesfor custom Element themes. Recommended size: 1 GB -
Logs: Mount path
/var/log/nginxfor nginx access and error logs. Recommended size: 5 GB -
Configuration Backups: Mount path
/config-backupfor storing configuration file backups. Recommended size: 1 GB
Setting Up Volumes in Klutch.sh
When creating your app in the Klutch.sh dashboard:
- Navigate to the volume configuration section during app creation
- Click “Add Volume” for each mount path you need
- Specify the mount path (e.g.,
/var/log/nginx) - Select the appropriate size for your expected usage
- The volumes will be created and mounted automatically during deployment
For more details on volume management, see the Klutch.sh Volumes Guide.
5. Environment Variables Configuration
Element’s configuration is primarily managed through the config.json file, but you can use environment variables with the entrypoint script for dynamic configuration.
Essential Environment Variables
# Matrix Homeserver ConfigurationMATRIX_HOMESERVER_URL=https://matrix.example.comMATRIX_SERVER_NAME=example.comMATRIX_IDENTITY_SERVER_URL=https://vector.im
# BrandingELEMENT_BRAND=Element
# IntegrationsINTEGRATIONS_UI_URL=https://scalar.vector.im/INTEGRATIONS_REST_URL=https://scalar.vector.im/api
# FeaturesSHOW_LABS_SETTINGS=true
# Jitsi Configuration (for video calls)JITSI_DOMAIN=meet.jit.si
# Element Call ConfigurationELEMENT_CALL_URL=https://call.element.ioELEMENT_CALL_EXCLUSIVE=falseELEMENT_CALL_LIMIT=8Optional Environment Variables
# Analytics (if using self-hosted analytics)ANALYTICS_ID=your-analytics-id
# Custom IntegrationsINTEGRATIONS_WIDGETS_URL=https://your-widgets.example.com
# Bug ReportingBUG_REPORT_ENDPOINT=https://your-bugreport-endpoint.example.com
# Map ConfigurationMAPTILER_API_KEY=your-maptiler-api-keySetting Environment Variables in Klutch.sh
- In the Klutch.sh dashboard, navigate to your app settings
- Find the “Environment Variables” section
- Add each variable with its corresponding value
- Mark sensitive values (API keys, tokens) as “Secret” to encrypt them
- Save your changes and redeploy if necessary
Security Best Practices:
- Never commit API keys or sensitive tokens to your Git repository
- Use the secret/encrypted option in Klutch.sh for all sensitive values
- Regularly review and rotate API keys
- Use HTTPS for all Matrix homeserver connections
6. Deploying to Klutch.sh
Step-by-Step Deployment Process
-
Push your repository to GitHub: Ensure your Dockerfile, nginx.conf, config.json, and docker-entrypoint.sh are committed and pushed to your GitHub repository.
-
Create a new app in Klutch.sh: Log in to the Klutch.sh dashboard and click “Create New App”.
-
Connect your GitHub repository: Select your Element repository from the list. Klutch.sh will automatically detect the Dockerfile in your root directory.
-
Configure your app:
- App Name: Choose a descriptive name for your Element instance (e.g., “element-chat”)
- Branch: Select the branch to deploy (typically
mainorproduction) - Region: Choose the region closest to your users for optimal performance
- Internal Port: Set to
8080(or the port specified in your nginx.conf)
-
Select traffic type: Choose HTTP for Element web traffic. This allows Klutch.sh to route incoming HTTP/HTTPS requests to your container on the internal port you specified.
-
Configure compute resources: Select the appropriate instance size based on your expected usage:
- Small: 0.5 CPU, 512 MB RAM (small teams, testing)
- Medium: 1 CPU, 1 GB RAM (medium-sized teams)
- Large: 2 CPU, 2 GB RAM (large organizations)
- X-Large: 4 CPU, 4 GB RAM (high traffic deployments)
-
Add persistent volumes (optional): Configure volumes if you need custom themes or log persistence:
/var/log/nginx- Nginx logs/usr/share/nginx/html/themes- Custom themes
-
Set environment variables: Add all required environment variables from section 5, particularly:
MATRIX_HOMESERVER_URL- Your Matrix homeserver URLMATRIX_SERVER_NAME- Your Matrix server name- Other configuration variables as needed
-
Deploy: Click “Create” to start the deployment. Klutch.sh will:
- Clone your repository
- Build the Docker image using your Dockerfile
- Create the container with your configuration
- Mount any persistent volumes
- Start your application
-
Verify deployment: Once deployment completes, access your Element instance at the provided URL (e.g.,
https://example-app.klutch.sh). You should see the Element login page.
Deployment Notes
- Automatic Dockerfile detection: Klutch.sh automatically detects and uses your Dockerfile when present in the root directory. You don’t need to specify Docker as a deployment method.
- Build time: Initial deployment may take 5-10 minutes depending on the Element version and network speed (building Element Web can take several minutes).
- Zero-downtime deployments: Subsequent deployments use rolling updates to ensure your app remains available.
7. Matrix Homeserver Setup
Element requires a Matrix homeserver to function. You have several options:
Using an Existing Homeserver
If you already have a Matrix homeserver (Synapse, Dendrite, or Conduit):
- Verify homeserver accessibility: Ensure your homeserver is accessible via HTTPS
- Configure CORS: Make sure your homeserver allows CORS requests from your Element domain
- Update config.json: Set the
MATRIX_HOMESERVER_URLenvironment variable to your homeserver’s URL - Test connection: After deploying Element, try to log in with an existing Matrix account
Deploying Synapse on Klutch.sh
To deploy a Synapse homeserver alongside Element:
- Create a separate app for Synapse on Klutch.sh
- Use the Synapse Docker image: Deploy using the official
matrixdotorg/synapse:latestimage - Configure persistent volumes: Mount
/datafor Synapse’s database and media storage - Set up PostgreSQL: For production, use PostgreSQL instead of SQLite
- Configure environment variables:
- Connect Element to Synapse: Use the Synapse app’s URL as your
MATRIX_HOMESERVER_URL
SYNAPSE_SERVER_NAME=example.comSYNAPSE_REPORT_STATS=noPOSTGRES_PASSWORD=your-secure-passwordFor a detailed Synapse deployment guide, refer to the official Matrix documentation.
Federation Considerations
If you want your Matrix homeserver to federate with others:
- Ensure your homeserver is accessible on port 8448 or has proper SRV records
- Configure TLS certificates properly
- Set up proper DNS records for federation
- For Matrix homeserver deployments (not Element itself), consider using TCP traffic type in Klutch.sh if you need direct access to federation port 8448. Element Web uses HTTP traffic type since it’s a web application served over HTTP/HTTPS
8. Getting Started with Element
Once your Element instance is deployed and accessible, follow these steps to get started:
Initial Setup
-
Access your instance: Navigate to your Element URL (e.g.,
https://example-app.klutch.sh) -
Verify homeserver connection: You should see the Element login page with your homeserver pre-configured
-
Create or log in with an account:
- If you have an existing Matrix account, log in with your credentials
- If you’re using a new homeserver, register a new account
-
Test messaging: Create a room and send a test message to verify everything works
-
Invite team members: Share your Element URL with your team and have them create accounts
Sample Custom Theme Configuration
To customize Element’s appearance, create a custom theme file:
{ "name": "Custom Theme", "is_dark": false, "colors": { "accent": "#0DBD8B", "primary": "#368bd6", "warning": "#ff5b55", "alert": "#ff5b55", "sidebar": "#27303a", "roomlist-background": "#181b21", "roomlist-text-primary-color": "#ffffff", "roomlist-text-secondary-color": "#b9bec6", "timeline-background": "#ffffff", "timeline-text-color": "#2e2f32" }, "fonts": { "faces": [], "general": "Inter, Twemoji, 'Apple Color Emoji', 'Segoe UI Emoji', Arial, Helvetica, Sans-Serif", "monospace": "'Inconsolata', monospace" }}Save this as custom-theme.json in your themes directory if you’ve mounted a volume for custom themes.
9. Production Best Practices
Performance Optimization
-
Use CDN: Consider using a CDN for static assets to reduce load times globally
-
Enable HTTP/2: Ensure nginx is configured to use HTTP/2 for improved performance. Note that HTTP/2 typically requires TLS, which Klutch.sh handles at the load balancer level. For the internal container, the standard configuration in this guide is sufficient
-
Optimize caching: Configure appropriate cache headers for static assets (already in the nginx.conf example)
-
Monitor resource usage: Use the Klutch.sh dashboard to track CPU, memory, and network usage
Security Hardening
-
Use HTTPS exclusively: Klutch.sh automatically provides TLS/SSL for your apps. Ensure your Matrix homeserver also uses HTTPS
-
Configure Content Security Policy: The nginx configuration includes CSP headers. Review and adjust based on your integrations
-
Regular updates: Keep Element updated by regularly rebuilding with the latest version:
-
Secure homeserver communication: Ensure all communication between Element and your Matrix homeserver is encrypted
-
Implement rate limiting: Add nginx rate limiting to prevent abuse:
ARG ELEMENT_VERSION=v1.11.50 # Update this regularlylimit_req_zone $binary_remote_addr zone=element_limit:10m rate=10r/s;limit_req zone=element_limit burst=20 nodelay;Scaling Considerations
-
Horizontal scaling: Element is a static web application, so you can easily run multiple instances behind a load balancer
-
Separate homeserver: Always run your Matrix homeserver as a separate service for better resource management
-
Media repository: Consider using an external object storage (S3-compatible) for Matrix media to reduce storage costs
-
Database optimization: If running your own Synapse homeserver, use PostgreSQL with proper indexing and connection pooling
10. Monitoring and Logging
Application Logs
Access your nginx logs through the Klutch.sh dashboard or mounted volumes:
- Navigate to your app in the Klutch.sh dashboard
- Click on “Logs” to view real-time nginx output
- Filter logs by time range or search for specific events
- Download logs for offline analysis if needed
Health Checks
The nginx configuration includes a health check endpoint at /health:
# Test health endpointcurl https://example-app.klutch.sh/health# Should return: healthyMonitoring Metrics
Monitor key metrics:
- Response times for page loads
- nginx connection counts
- CPU and memory utilization
- Disk space (if using persistent volumes)
- Matrix homeserver health and response times
11. Troubleshooting Common Issues
Element Won’t Load
- Check logs: Review nginx logs in the Klutch.sh dashboard for errors
- Verify config.json: Ensure the config.json file is valid JSON and accessible
- Test homeserver: Verify your Matrix homeserver is accessible from Element:
- Check port configuration: Ensure the internal port in Klutch.sh matches your nginx configuration
curl https://matrix.example.com/_matrix/client/versionsUnable to Connect to Homeserver
- Verify homeserver URL: Double-check the
MATRIX_HOMESERVER_URLenvironment variable - Check CORS configuration: Ensure your homeserver allows CORS requests from your Element domain
- Test homeserver federation: Use the Matrix Federation Tester
- Review firewall rules: Ensure no firewall is blocking communication between Element and the homeserver
Login Issues
- Verify credentials: Ensure you’re using the correct username and password format
- Check homeserver registration: Confirm that registration is enabled if you’re creating a new account
- Review homeserver logs: Check Synapse/Dendrite logs for authentication errors
- Clear browser cache: Sometimes cached credentials can cause issues
Performance Problems
- Scale resources: Increase CPU and memory allocation in the Klutch.sh dashboard
- Check homeserver performance: Element performance is often dependent on homeserver speed
- Enable compression: Ensure gzip compression is working (check nginx configuration)
- Monitor network: Use browser DevTools to identify slow-loading resources
12. Backup and Disaster Recovery
Configuration Backups
-
Version control: Keep your config.json and Dockerfile in Git for easy recovery
-
Export configuration: Regularly backup your current config.json by keeping it in version control and documenting any runtime changes
-
Document customizations: Maintain documentation of any custom themes or integrations
Disaster Recovery Plan
- Document configuration: Keep a copy of all environment variables and settings
- Repository backup: Ensure your GitHub repository is backed up
- Homeserver backup: Maintain regular backups of your Matrix homeserver database
- Recovery procedure: Document steps to restore from backup
- Test recovery: Periodically test your recovery process in a staging environment
13. Migrating from Another Platform
If you’re migrating an existing Element instance to Klutch.sh:
-
Backup existing configuration: Export your current config.json and any customizations
-
Document environment: Note all current settings, domains, and integrations
-
Deploy on Klutch.sh: Follow the deployment steps in section 6 to create your new instance
-
Transfer custom themes: If using custom themes, upload them to your persistent volume
-
Update DNS: Point your domain to the new Klutch.sh deployment
-
Test thoroughly: Verify all functionality before switching over:
- Login/registration
- Room creation and messaging
- Voice/video calls
- File uploads
- Integrations
-
Monitor: Watch logs and performance during the first few days
14. Custom Domain Configuration
To use a custom domain with your Element deployment:
-
Add domain in Klutch.sh: Navigate to your app settings and add your custom domain (e.g.,
chat.yourdomain.com) -
Update DNS records: Configure your DNS provider:
- Add an A record pointing to the Klutch.sh provided IP, or
- Add a CNAME record as instructed by the dashboard
-
Update configuration: Update your
config.jsonif needed to reflect the custom domain -
SSL/TLS: Klutch.sh automatically provisions and manages SSL certificates for your custom domain
-
Verify: Access your Element instance via the custom domain to confirm everything works
-
Update homeserver: If your homeserver needs to know about the Element URL, update its configuration accordingly
For more details, see the Klutch.sh Custom Domains guide.
15. Example: Complete Quickstart
Here’s a complete, copy-paste quickstart to get Element running on Klutch.sh:
1. Create Repository
mkdir element-dockercd element-dockergit init2. Create Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
RUN apk add --no-cache git python3 make g++
RUN git clone --depth 1 --branch v1.11.50 https://github.com/vector-im/element-web.git .
RUN yarn install --frozen-lockfile && yarn build
FROM nginx:alpine
RUN apk add --no-cache bash
COPY --from=builder /app/webapp /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.confCOPY config.json /usr/share/nginx/html/config.jsonCOPY docker-entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]CMD ["nginx", "-g", "daemon off;"]3. Create nginx.conf
server { listen 8080; root /usr/share/nginx/html; index index.html;
location / { try_files $uri $uri/ /index.html; }
location = /config.json { add_header Cache-Control "no-cache"; }
location /health { return 200 "healthy\n"; }}4. Create config.json
{ "default_server_config": { "m.homeserver": { "base_url": "https://matrix.org", "server_name": "matrix.org" } }}5. Create docker-entrypoint.sh
#!/bin/bashset -e
if [ -n "$MATRIX_HOMESERVER_URL" ]; then cat > /usr/share/nginx/html/config.json <<EOF{ "default_server_config": { "m.homeserver": { "base_url": "${MATRIX_HOMESERVER_URL}", "server_name": "${MATRIX_SERVER_NAME:-matrix.org}" } }}EOFfi
exec "$@"6. Commit and Push
git add .git commit -m "Initial Element Docker setup"git remote add origin https://github.com/yourusername/element-docker.gitgit push -u origin main7. Deploy on Klutch.sh
- Go to Klutch.sh dashboard
- Click “Create New App”
- Connect your GitHub repository
- Set internal port to
8080 - Select HTTP traffic type
- Add environment variables:
MATRIX_HOMESERVER_URL=https://matrix.orgMATRIX_SERVER_NAME=matrix.org
- Click “Create”
Your Element instance will be live in 5-10 minutes at https://example-app.klutch.sh!
Resources
- Element Official Website
- Element Web on GitHub
- Matrix Protocol Documentation
- Synapse Homeserver Setup
- Klutch.sh Quick Start Guide
- Klutch.sh Volumes Guide
- Klutch.sh Custom Domains
- Klutch.sh Networking Guide