fix(deploy): rework prod artifacts to match the actual Hetzner box
Server recon (read-only SSH) showed the box already runs ~8 apps behind a host-level nginx, with Gitea + an Actions runner. The host-networking design collided with contentra on port 3001. - docker-compose.prod.yml: bridge networking + per-app network, house style; api/web/postgres/redis publish to 127.0.0.1 on verified-free ports (4000/4001/5440/6390); only the generator keeps host networking (no listening port, needs the host namespace for runner-port probing). - Drop the Traefik config; the box uses a host nginx. Add a ready nginx vhost in infra/nginx/buildmymcpserver.conf (listen 80, Cloudflare TLS). - Add .gitea/workflows/deploy.yml mirroring the buildmydiscord pipeline. - Narrow the generated-MCP port range to 4400-4900 (clear of screencraft on 4321). - .env.production.example + DEPLOY.md rewritten for buildmymcpserver.com and the real topology. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,25 +1,27 @@
|
||||
# Production stack for buildmymcp.com — Linux host only.
|
||||
# Production stack for buildmymcpserver.com — Linux host only.
|
||||
#
|
||||
# Run with:
|
||||
# docker compose --env-file .env.production -f docker-compose.prod.yml up -d --build
|
||||
#
|
||||
# Topology notes:
|
||||
# - api / web / generator use host networking. The generator allocates host
|
||||
# ports (4100-4999) for generated MCP containers and probes them with a local
|
||||
# socket bind — that probe is only correct in the host network namespace.
|
||||
# Host networking also keeps every service on one address space (127.0.0.1).
|
||||
# - postgres / redis stay on the compose bridge network and publish to loopback
|
||||
# only, so the host-networked services reach them at 127.0.0.1.
|
||||
# - api and generator mount the Docker socket: the API removes containers, the
|
||||
# generator builds + runs them. Generated MCP containers are host siblings.
|
||||
# - Nothing here binds 0.0.0.0:80/443. Front this with the box's existing
|
||||
# reverse proxy, or the optional one in infra/traefik/. See DEPLOY.md.
|
||||
# Topology — matches the house pattern on the shared Hetzner box:
|
||||
# - Bridge networking + per-app network, like every other app on the box.
|
||||
# - api / web / postgres / redis publish to 127.0.0.1 only. The host nginx
|
||||
# reverse-proxies the public domains to these loopback ports. Nothing here
|
||||
# binds 0.0.0.0:80/443 — the box's existing nginx owns those.
|
||||
# - generator uses host networking: it has no listening port of its own (no
|
||||
# collision risk) and it must allocate + probe host ports for the MCP
|
||||
# containers it spawns, which is only correct in the host namespace.
|
||||
# - api + generator mount the Docker socket: the API removes generated
|
||||
# containers, the generator builds + runs them as host siblings.
|
||||
#
|
||||
# Ports are picked to not collide with the other apps already on this box.
|
||||
|
||||
name: buildmymcp
|
||||
name: buildmymcpserver
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: bmm-postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-bmm}
|
||||
@@ -29,6 +31,7 @@ services:
|
||||
- "127.0.0.1:${POSTGRES_PORT:-5440}:5432"
|
||||
volumes:
|
||||
- bmm_pg:/var/lib/postgresql/data
|
||||
networks: [bmm-network]
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-bmm} -d ${POSTGRES_DB:-bmm}"]
|
||||
interval: 5s
|
||||
@@ -37,12 +40,14 @@ services:
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: bmm-redis
|
||||
restart: unless-stopped
|
||||
command: ["redis-server", "--appendonly", "yes"]
|
||||
ports:
|
||||
- "127.0.0.1:${REDIS_PORT:-6390}:6379"
|
||||
volumes:
|
||||
- bmm_redis:/data
|
||||
networks: [bmm-network]
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
@@ -53,28 +58,15 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/api/Dockerfile
|
||||
container_name: bmm-api
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
env_file: .env.production
|
||||
ports:
|
||||
- "127.0.0.1:${API_PORT:-4000}:4000"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- bmm_keys:/app/apps/api/keys
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
||||
generator:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/generator/Dockerfile
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
env_file: .env.production
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- bmm_build_context:/app/build-context
|
||||
networks: [bmm-network]
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
@@ -87,11 +79,40 @@ services:
|
||||
dockerfile: apps/web/Dockerfile
|
||||
args:
|
||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:?set NEXT_PUBLIC_API_URL in .env.production}
|
||||
container_name: bmm-web
|
||||
restart: unless-stopped
|
||||
env_file: .env.production
|
||||
ports:
|
||||
- "127.0.0.1:${WEB_PORT:-4001}:3001"
|
||||
networks: [bmm-network]
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
generator:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/generator/Dockerfile
|
||||
container_name: bmm-generator
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
env_file: .env.production
|
||||
environment:
|
||||
# Host networking — reach the DBs via their published loopback ports
|
||||
# instead of the compose-network service names.
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-bmm}:${POSTGRES_PASSWORD}@127.0.0.1:${POSTGRES_PORT:-5440}/${POSTGRES_DB:-bmm}
|
||||
REDIS_URL: redis://127.0.0.1:${REDIS_PORT:-6390}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- bmm_build_context:/app/build-context
|
||||
depends_on:
|
||||
- api
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
bmm-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
bmm_pg:
|
||||
|
||||
Reference in New Issue
Block a user