Skip to content

Docker Compose setup

Host Silex using Docker and Docker Compose with minimal configuration.

Overview

The simplest way to self-host Silex is using Docker. The official Docker image (silexlabs/silex-platform) includes the Node.js server, all connectors (filesystem, GitLab, FTP), and the web editor pre-configured. You manage the instance through environment variables and Docker Compose, with no need to write code.

Docker Compose also lets you add reverse proxies (Nginx, Caddy), SSL termination, and link external services (PostgreSQL for CMS backends).

Prerequisites

  • Docker and Docker Compose installed
  • Basic understanding of environment variables and port forwarding
  • A domain name (optional, for custom domains)

Setup

1. Create a docker-compose.yml file

Create a new directory for your Silex instance:

mkdir silex-instance && cd silex-instance
touch docker-compose.yml .env

2. Add the Silex service

Paste this into your docker-compose.yml:

version: '3.8'

services:
  silex:
    image: silexlabs/silex-platform:latest
    container_name: silex
    ports:
      - "6805:6805"
    environment:
      SILEX_PORT: 6805
      SILEX_HOST: localhost
      SILEX_PROTOCOL: http
      SILEX_SESSION_SECRET: ${SILEX_SESSION_SECRET}
      SILEX_URL: http://localhost:6805
      STORAGE_CONNECTORS: fs
      HOSTING_CONNECTORS: fs,download
    volumes:
      - ./silex-storage:/silex/storage
      - ./silex-hosting:/silex/hosting
    restart: unless-stopped

3. Set environment variables

Edit .env:

SILEX_SESSION_SECRET=your-random-secret-here-min-32-chars

Generate a secure secret:

openssl rand -base64 32

4. Start the instance

docker-compose up -d

Silex is now running at http://localhost:6805.

5. Access Silex

Open your browser to http://localhost:6805. You'll see the dashboard with an empty list of websites.

Environment variables

Variable Default Purpose
SILEX_PORT 6805 Internal port the Node server listens on
SILEX_HOST localhost Internal hostname (keep as localhost in Docker)
SILEX_PROTOCOL http Protocol before reverse proxy (http or https)
SILEX_URL http://localhost:6805 Public URL users visit (update for production)
SILEX_SESSION_SECRET (none) Session encryption key; must be random and min 32 chars
SILEX_SESSION_NAME silex-session Session cookie name
SILEX_DEBUG false Set to true to reload config files on each request (dev only)
STORAGE_CONNECTORS fs Comma-separated: fs, gitlab, ftp
HOSTING_CONNECTORS fs,download Comma-separated: fs, gitlab, ftp, download
SILEX_FS_ROOT /silex/storage Path for filesystem storage connector
SILEX_FS_HOSTING_ROOT /silex/hosting Path for filesystem hosting connector

Express request limits

If you upload large files or use large JSON payloads:

Variable Default Purpose
SILEX_EXPRESS_JSON_LIMIT 100kb Max JSON request body
SILEX_EXPRESS_TEXT_LIMIT 1mb Max text request body
SILEX_EXPRESS_URLENCODED_LIMIT 100kb Max URL-encoded request body

Increase for large assets or data imports:

environment:
  SILEX_EXPRESS_JSON_LIMIT: 50mb
  SILEX_EXPRESS_TEXT_LIMIT: 50mb

GitLab connectors

To enable GitLab storage and hosting:

environment:
  STORAGE_CONNECTORS: fs,gitlab
  HOSTING_CONNECTORS: fs,download,gitlab
  GITLAB_DISPLAY_NAME: GitLab.com
  GITLAB_CLIENT_ID: your-oauth-app-id
  GITLAB_CLIENT_SECRET: your-oauth-app-secret
  GITLAB_DOMAIN: gitlab.com

For a second GitLab instance (e.g., self-hosted), add:

environment:
  STORAGE_CONNECTORS: fs,gitlab,gitlab2
  HOSTING_CONNECTORS: fs,download,gitlab,gitlab2
  GITLAB_DISPLAY_NAME: GitLab.com
  GITLAB_CLIENT_ID: your-app-id
  GITLAB_CLIENT_SECRET: your-app-secret
  GITLAB_DOMAIN: gitlab.com
  GITLAB2_DISPLAY_NAME: Company GitLab
  GITLAB2_CLIENT_ID: your-second-app-id
  GITLAB2_CLIENT_SECRET: your-second-app-secret
  GITLAB2_DOMAIN: gitlab.mycompany.com

See Storage connectors for OAuth setup.

FTP connectors

To use FTP for storage or hosting:

environment:
  STORAGE_CONNECTORS: ftp
  HOSTING_CONNECTORS: ftp
  FTP_STORAGE_PATH: /public_html
  FTP_HOSTING_PATH: /public_html

Users authenticate with FTP credentials via the UI.

Reverse proxy with Nginx

Run Silex behind Nginx for SSL termination and custom domains:

version: '3.8'

services:
  silex:
    image: silexlabs/silex-platform:latest
    expose:
      - 6805
    environment:
      SILEX_URL: https://my-silex.example.com
      SILEX_PROTOCOL: https
      SILEX_PORT: 6805
      SILEX_SESSION_SECRET: ${SILEX_SESSION_SECRET}
      STORAGE_CONNECTORS: fs
      HOSTING_CONNECTORS: fs,download
    volumes:
      - ./silex-storage:/silex/storage
      - ./silex-hosting:/silex/hosting
    restart: unless-stopped

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - silex
    restart: unless-stopped

Create nginx.conf:

events {
  worker_connections 1024;
}

http {
  upstream silex {
    server silex:6805;
  }

  server {
    listen 80;
    server_name my-silex.example.com;
    return 301 https://$server_name$request_uri;
  }

  server {
    listen 443 ssl;
    server_name my-silex.example.com;

    ssl_certificate /etc/nginx/certs/cert.pem;
    ssl_certificate_key /etc/nginx/certs/key.pem;

    location / {
      proxy_pass http://silex;
      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;
    }
  }
}

Point your domain's A record to your server's IP, then generate SSL certificates using Let's Encrypt:

certbot certonly --standalone -d my-silex.example.com

Copy the certificates to ./certs/:

sudo cp /etc/letsencrypt/live/my-silex.example.com/fullchain.pem ./certs/cert.pem
sudo cp /etc/letsencrypt/live/my-silex.example.com/privkey.pem ./certs/key.pem

Reverse proxy with Caddy

Caddy auto-manages SSL certificates:

caddy:
  image: caddy:latest
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./Caddyfile:/etc/caddy/Caddyfile:ro
    - caddy-data:/data
  depends_on:
    - silex

volumes:
  caddy-data:

Create a Caddyfile:

my-silex.example.com {
  reverse_proxy silex:6805
}

Volumes and data persistence

The default docker-compose.yml mounts two volumes:

  • ./silex-storage: Where websites are stored (HTML, CSS, assets)
  • ./silex-hosting: Where published sites are deployed

These persist across container restarts. Back them up regularly:

docker-compose exec silex tar czf /silex/storage-backup.tar.gz /silex/storage
docker cp silex:/silex/storage-backup.tar.gz ./backup/

Updating the Docker image

Pull the latest version:

docker-compose pull
docker-compose up -d

Troubleshooting

Container fails to start

Check logs:

docker-compose logs silex

Common issues: - Port 6805 already in use: Change ports: ["6805:6805"] to ["8080:6805"] - SILEX_SESSION_SECRET too short: Must be at least 32 characters - Permission denied on volumes: Run chmod 777 silex-storage silex-hosting

Websites stored locally but not accessible

The filesystem hosting connector stores files in the container's /silex/hosting directory, not web-served. To serve published sites:

  1. Use the download connector to get a ZIP
  2. Deploy to a separate static web server
  3. Use GitLab Pages or FTP hosting instead

See Deploying to other hosting platforms.

CORS errors

If the editor and API are on different domains, set:

environment:
  SILEX_CORS_URL: https://your-domain.com

See also

Edit this page on GitLab