deploy Production setup

Production setup

Run socAdmin behind HTTPS with a fixed secret, a locked-down container and registration turned off.

socAdmin gives access to your databases, so treat it like an admin panel: never expose it directly to the internet.

Checklist

  • Set JWT_SECRET to a random string of 32+ characters. Generate one with openssl rand -base64 32.
  • Use a strong ADMIN_PASSWORD.
  • Set REGISTRATION_ENABLED=false so only admins add users.
  • Serve it over HTTPS, through a reverse proxy or with TLS_CERT / TLS_KEY.
  • Set SECURE_COOKIES=true when HTTPS ends at the proxy.
  • Set TRUSTED_PROXY to your proxy’s IP or subnet so rate limiting sees real client IPs.
  • Don’t publish port 8080 to the internet. Bind it to 127.0.0.1 or keep it on the internal network.
  • Mount /data on a persistent volume and back it up.

This runs the container with a read-only filesystem and only exposes it to the host itself, for a reverse proxy on the same machine.

services:
  socadmin:
    image: soleilclems/socadmin
    read_only: true
    tmpfs:
      - /tmp
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - socadmin-data:/data
    environment:
      - JWT_SECRET=${JWT_SECRET:?Set a random string of at least 32 characters}
      - ADMIN_EMAIL=${ADMIN_EMAIL}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - REGISTRATION_ENABLED=false
      - SECURE_COOKIES=true
      # Requests from a proxy on the host reach the container through the Docker bridge
      - TRUSTED_PROXY=172.16.0.0/12
    restart: unless-stopped

volumes:
  socadmin-data:

Put the secrets in a .env file next to it, not in the Compose file.

Behind Nginx

server {
    listen 443 ssl;
    server_name db.example.com;

    ssl_certificate     /etc/ssl/certs/cert.pem;
    ssl_certificate_key /etc/ssl/private/key.pem;

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

Behind Traefik

services:
  socadmin:
    image: soleilclems/socadmin
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.socadmin.rule=Host(`db.example.com`)"
      - "traefik.http.routers.socadmin.tls.certresolver=letsencrypt"
      - "traefik.http.services.socadmin.loadbalancer.server.port=8080"
    volumes:
      - socadmin-data:/data
    environment:
      - JWT_SECRET=${JWT_SECRET}
      - ADMIN_EMAIL=${ADMIN_EMAIL}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - REGISTRATION_ENABLED=false
      - SECURE_COOKIES=true

HTTPS without a proxy

socAdmin can serve HTTPS itself. Mount the certificate and key, then point to them:

-e TLS_CERT=/data/certs/cert.pem \
-e TLS_KEY=/data/certs/key.pem

With TLS on, socAdmin also starts a listener that redirects plain HTTP to HTTPS, on port 80 by default. The container runs as a non-root user and can’t bind port 80, so set HTTP_REDIRECT_PORT to a port above 1024 (for example 8081) and publish it.

Restrict by IP

Admins can turn on an IP whitelist from the security settings in socAdmin. When it’s on, only listed IP addresses can reach the interface. Behind a proxy, set TRUSTED_PROXY first, or the whitelist only sees the proxy’s address.