mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-12 16:04:25 +00:00
89 lines
3.2 KiB
YAML
89 lines
3.2 KiB
YAML
# The bus box: NATS JetStream and Redis, reachable by the control plane on one
|
|
# host and the fleet on others.
|
|
#
|
|
# Run this on a machine of its own once you have more than one worker. The
|
|
# whole control plane depends on it, so it should not also be the box you
|
|
# restart when you redeploy a worker.
|
|
#
|
|
# Before the first start:
|
|
# 1. point bus.example.com at this machine
|
|
# 2. get a certificate for it (certbot certonly --standalone -d bus.example.com)
|
|
# 3. groupadd -g 2000 warmbly-certs, the group that may read the private key
|
|
# 4. install certbot-deploy-hook.sh so renewals land in /opt/warmbly/certs
|
|
# 5. write .env next to this file with NATS_TOKEN and REDIS_PASSWORD
|
|
#
|
|
# NATS_TOKEN=$(openssl rand -hex 32)
|
|
# REDIS_PASSWORD=$(openssl rand -hex 32)
|
|
|
|
services:
|
|
nats:
|
|
image: nats:2.10-alpine
|
|
restart: unless-stopped
|
|
# Only the config file. Passing -js/-sd/-m as well duplicates what
|
|
# nats.conf already sets, and NATS refuses to start on a duplicate
|
|
# rather than picking one.
|
|
command: ["-c", "/etc/nats/nats.conf"]
|
|
environment:
|
|
NATS_TOKEN: ${NATS_TOKEN:?set NATS_TOKEN in .env}
|
|
# The private key is 0640 and owned by this group, so neither container
|
|
# needs it world-readable and nothing else on the box can read it.
|
|
group_add:
|
|
- "${WARMBLY_CERT_GID:-2000}"
|
|
volumes:
|
|
- ./nats.conf:/etc/nats/nats.conf:ro
|
|
- ${WARMBLY_CERT_DIR:-/opt/warmbly/certs}:/certs:ro
|
|
- nats_data:/data
|
|
ports:
|
|
- "4222:4222"
|
|
healthcheck:
|
|
# 127.0.0.1, not localhost: nats.conf binds the monitor to IPv4
|
|
# loopback, and `localhost` resolves to ::1 first in a container, so the
|
|
# check never reaches it and the service sits unhealthy while serving
|
|
# traffic perfectly well.
|
|
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8222/healthz"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
restart: unless-stopped
|
|
# Pinned so the entrypoint never runs as root. Left as root it drops to
|
|
# uid 999 with gosu, which resets supplementary groups and throws away the
|
|
# group_add below, and then it cannot read the private key.
|
|
user: "999:999"
|
|
# TLS is not optional on this box. Redis holds each organization's
|
|
# decrypted data key for the life of its cache entry, so a plaintext
|
|
# connection across the internet publishes key material. The password
|
|
# protects access; only TLS protects the traffic.
|
|
#
|
|
# 6379 stays open for containers on this host and is never published;
|
|
# 6380 is the port the control plane connects to.
|
|
command: >
|
|
redis-server
|
|
--port 6379
|
|
--tls-port 6380
|
|
--tls-cert-file /certs/fullchain.pem
|
|
--tls-key-file /certs/privkey.pem
|
|
--tls-ca-cert-file /certs/chain.pem
|
|
--tls-auth-clients no
|
|
--requirepass ${REDIS_PASSWORD:?set REDIS_PASSWORD in .env}
|
|
--appendonly yes
|
|
--maxmemory-policy noeviction
|
|
group_add:
|
|
- "${WARMBLY_CERT_GID:-2000}"
|
|
volumes:
|
|
- ${WARMBLY_CERT_DIR:-/opt/warmbly/certs}:/certs:ro
|
|
- redis_data:/data
|
|
ports:
|
|
- "6380:6380"
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
volumes:
|
|
nats_data:
|
|
redis_data:
|