This guide walks you through deploying a complete Fluxer instance using Docker Compose. You’ll have a working installation with messaging, search, and optional voice/video support.
Prerequisites
Docker & Docker Compose Docker Engine 24.0+ and Docker Compose v2.20+
Domain Name A domain pointing to your server (e.g., chat.example.com)
Install Docker
If you don’t have Docker installed: # Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
# Add your user to docker group
sudo usermod -aG docker $USER
newgrp docker
Step 1: Download Fluxer
Clone the Fluxer repository or download the compose file:
mkdir fluxer && cd fluxer
curl -O https://raw.githubusercontent.com/fluxerapp/fluxer/main/compose.yaml
curl -O https://raw.githubusercontent.com/fluxerapp/fluxer/main/config/config.production.template.json
Step 2: Create Configuration
Create a config directory and configuration file:
mkdir -p config
cp config.production.template.json config/config.json
Edit config/config.json with your settings:
{
"$schema" : "../packages/config/src/ConfigSchema.json" ,
"env" : "production" ,
"domain" : {
"base_domain" : "chat.example.com" , // Your domain
"public_scheme" : "https" ,
"public_port" : 443
},
"database" : {
"backend" : "sqlite" ,
"sqlite_path" : "./data/fluxer.db"
},
"internal" : {
"kv" : "redis://valkey:6379/0" ,
"kv_mode" : "standalone"
},
"s3" : {
"access_key_id" : "YOUR_S3_ACCESS_KEY" ,
"secret_access_key" : "YOUR_S3_SECRET_KEY" ,
"endpoint" : "http://127.0.0.1:8080/s3"
},
"services" : {
"server" : {
"port" : 8080 ,
"host" : "0.0.0.0"
},
"media_proxy" : {
"secret_key" : "GENERATE_A_64_CHAR_HEX_SECRET"
},
"admin" : {
"secret_key_base" : "GENERATE_A_64_CHAR_HEX_SECRET" ,
"oauth_client_secret" : "GENERATE_A_64_CHAR_HEX_SECRET"
},
"marketing" : {
"enabled" : true ,
"secret_key_base" : "GENERATE_A_64_CHAR_HEX_SECRET"
},
"gateway" : {
"port" : 8082 ,
"admin_reload_secret" : "GENERATE_A_64_CHAR_HEX_SECRET" ,
"media_proxy_endpoint" : "http://127.0.0.1:8080/media"
}
},
"auth" : {
"sudo_mode_secret" : "GENERATE_A_64_CHAR_HEX_SECRET" ,
"connection_initiation_secret" : "GENERATE_A_64_CHAR_HEX_SECRET" ,
"vapid" : {
"public_key" : "YOUR_VAPID_PUBLIC_KEY" ,
"private_key" : "YOUR_VAPID_PRIVATE_KEY"
}
},
"integrations" : {
"search" : {
"engine" : "meilisearch" ,
"url" : "http://meilisearch:7700" ,
"api_key" : "YOUR_MEILISEARCH_API_KEY"
}
}
}
Use these commands to generate secure random secrets: # Generate 64-character hex secrets
openssl rand -hex 32
# Generate VAPID keys for push notifications
npx web-push generate-vapid-keys
Replace all GENERATE_A_64_CHAR_HEX_SECRET placeholders with unique values.
Step 3: Review Docker Compose File
The provided compose.yaml includes these services:
services :
valkey :
image : valkey/valkey:8.0.6-alpine
container_name : valkey
restart : unless-stopped
command : [ 'valkey-server' , '--appendonly' , 'yes' , '--save' , '60' , '1' ]
volumes :
- valkey_data:/data
healthcheck :
test : [ 'CMD' , 'valkey-cli' , 'ping' ]
interval : 10s
timeout : 5s
retries : 5
fluxer_server :
image : ghcr.io/fluxerapp/fluxer-server:stable
container_name : fluxer_server
restart : unless-stopped
init : true
environment :
FLUXER_CONFIG : /usr/src/app/config/config.json
NODE_ENV : production
ports :
- '8080:8080'
depends_on :
valkey :
condition : service_healthy
volumes :
- ./config:/usr/src/app/config:ro
- fluxer_data:/usr/src/app/data
healthcheck :
test : [ 'CMD-SHELL' , 'curl -fsS http://127.0.0.1:8080/_health || exit 1' ]
interval : 15s
timeout : 5s
retries : 5
meilisearch :
image : getmeili/meilisearch:v1.14
container_name : meilisearch
profiles : [ 'search' ]
restart : unless-stopped
environment :
MEILI_ENV : production
MEILI_MASTER_KEY : ${MEILI_MASTER_KEY}
ports :
- '7700:7700'
volumes :
- meilisearch_data:/meili_data
volumes :
valkey_data :
fluxer_data :
meilisearch_data :
The meilisearch service uses Docker profiles. Enable it with --profile search when starting.
Step 4: Set Environment Variables
Create a .env file for secrets:
# Meilisearch master key (used for search API)
MEILI_MASTER_KEY = your-secure-meilisearch-master-key-min-16-chars
# Optional: Override default ports
FLUXER_HTTP_PORT = 8080
MEILI_PORT = 7700
Step 5: Start Fluxer
Start the core services:
# Start Fluxer without search
docker compose up -d
# Or start with search enabled
docker compose --profile search up -d
Check service health:
docker compose ps
docker compose logs -f fluxer_server
Fluxer requires a reverse proxy with TLS termination. Here’s an example Nginx configuration:
/etc/nginx/sites-available/fluxer
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name chat.example.com;
ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;
# WebSocket support
proxy_http_version 1.1 ;
proxy_set_header Upgrade $ http_upgrade ;
proxy_set_header Connection "upgrade" ;
# Headers
proxy_set_header Host $ host ;
proxy_set_header X-Real-IP $ remote_addr ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
# Increase timeouts for long-polling
proxy_read_timeout 3600 ;
proxy_send_timeout 3600 ;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
chat.example.com {
reverse_proxy localhost:8080
}
Add labels to your Docker Compose service: fluxer_server :
# ... existing config ...
labels :
- "traefik.enable=true"
- "traefik.http.routers.fluxer.rule=Host(`chat.example.com`)"
- "traefik.http.routers.fluxer.tls.certresolver=letsencrypt"
- "traefik.http.services.fluxer.loadbalancer.server.port=8080"
Step 7: Access Your Instance
Navigate to https://chat.example.com in your browser. You should see the Fluxer registration page.
Create Admin Account
Register the first user account. This becomes the instance administrator.
Access Admin Panel
Visit https://chat.example.com/admin to configure instance settings.
Create a Community
Set up your first community (guild) and invite users.
Optional: Enable Voice & Video
To enable voice and video calls, you need to set up LiveKit:
# Add LiveKit to compose.yaml with the voice profile
docker compose --profile voice up -d
Create config/livekit.yaml:
port : 7880
keys :
'<your-api-key>' : '<your-api-secret>'
rtc :
tcp_port : 7881
turn :
enabled : true
udp_port : 3478
room :
auto_create : true
max_participants : 100
empty_timeout : 300
Update your config.json to enable voice:
"integrations" : {
"voice" : {
"enabled" : true ,
"api_key" : "<your-api-key>" ,
"api_secret" : "<your-api-secret>" ,
"url" : "wss://chat.example.com/livekit" ,
"webhook_url" : "https://chat.example.com/api/webhooks/livekit"
}
}
LiveKit requires UDP ports 3478, 7881, and 50000-50100 to be accessible from the internet. Configure your firewall accordingly.
See the Voice Setup Guide for detailed LiveKit configuration.
Maintenance
Backups
Back up these critical directories:
# Backup script
#!/bin/bash
BACKUP_DIR = "/backup/fluxer-$( date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# Stop containers
docker compose stop
# Backup volumes
docker run --rm -v fluxer_fluxer_data:/data \
-v $BACKUP_DIR :/backup alpine \
tar czf /backup/fluxer_data.tar.gz -C /data .
docker run --rm -v fluxer_valkey_data:/data \
-v $BACKUP_DIR :/backup alpine \
tar czf /backup/valkey_data.tar.gz -C /data .
# Restart containers
docker compose start
Updates
# Pull latest images
docker compose pull
# Recreate containers
docker compose up -d
# Clean up old images
docker image prune -f
Logs
# View all logs
docker compose logs -f
# View specific service
docker compose logs -f fluxer_server
# Export logs
docker compose logs --no-color > fluxer-logs- $( date +%Y%m%d ) .txt
Troubleshooting
Connection refused or 502 errors
Check if the container is running and healthy: docker compose ps
docker compose logs fluxer_server
Verify the health endpoint: curl http://localhost:8080/_health
Database initialization failed
The SQLite database is created automatically on first run. Check permissions: docker compose exec fluxer_server ls -la /usr/src/app/data/
If needed, reset the database: docker compose down -v # Warning: deletes all data
docker compose up -d
Ensure Meilisearch is running and configured: docker compose --profile search ps meilisearch
curl http://localhost:7700/health
Verify the API key in config.json matches MEILI_MASTER_KEY in .env.
Adjust Node.js memory limits: fluxer_server :
environment :
NODE_OPTIONS : "--max-old-space-size=4096" # 4GB limit
Next Steps
Configuration Explore all configuration options and advanced settings
Architecture Understand Fluxer’s system components and design
Voice Setup Configure LiveKit for voice and video calls
Scaling Scale to thousands of concurrent users