Skip to main content

Adding Services Beside an Existing Bot

Prefer one Compose project per independently operated application:

/srv/discord-bot/{compose.yaml,.env,data/}
/srv/rsshub/{compose.yaml,.env}
/srv/infohub/{compose.yaml,data/}
/srv/caddy/{compose.yaml,Caddyfile}

Compose normally derives the project name from the directory, isolating resource names and default networks. A top-level name: can make it explicit. Separate projects let a Bot update without recreating RSSHub; combine components only when they genuinely share deployment and rollback.

A Discord Gateway Bot usually initiates an outbound WebSocket and needs no published inbound port:

name: discord-bot
services:
bot:
image: ghcr.io/example/discord-bot:<pinned-version>
restart: unless-stopped
env_file: [.env]
volumes: [./data:/app/data]

Bots receiving HTTP interactions or webhooks do need an inbound route. For public web apps, prefer Caddy as the single 80/443 entry instead of publishing arbitrary application ports. Admin-only services can bind to loopback or Tailscale. Databases and caches should remain on internal project networks.

For cross-project proxying, create an explicit external network such as docker network create ingress, declare it external: true, and attach only proxy-facing services.

Treat DISCORD_TOKEN as a secret: keep it in a mode-600 ignored .env or a secret manager, never commit or paste expanded Compose output, and rotate it in the developer portal after suspected exposure.

Repeatable addition workflow

docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
docker network ls; docker volume ls
ss -lntup; free -h; df -h /

mkdir -p /srv/new-service/data
cd /srv/new-service
docker compose config --quiet
docker compose config --services
docker compose config --images
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail 100

docker compose config may expand secrets, so do not share its full output. Pin versions or digests rather than blindly relying on latest. A running container is not a health check: verify that the Bot connects and responds, or that the web service works through Caddy and writes to the expected volume.

Record the old image and Compose diff before updates. To update one service:

cd /srv/discord-bot
docker compose pull bot
docker compose up -d --no-deps bot
docker compose ps
docker compose logs --tail 100 bot

Check dependency and database-migration requirements before using --no-deps. Avoid running docker compose down from an ambiguous directory and never use docker system prune -a as routine troubleshooting. Clear ownership boundaries matter more than saving a few YAML files.