Files
mangaBookmark/docker-compose.prod.yml
T
sulthan 15382eb603 Fix review findings from the browser relocation (#46)
Compose merges `networks:` across override files rather than replacing them,
so the prod override's claim that it must re-name every network was false —
and the rationale built on it ("proxy carries the poller's egress") was false
too. Verified against `docker compose config`: the API renders on db, default
and proxy with only `proxy` named here. Egress comes from `default`, which is
now the thing a maintainer must not tidy away.

chrome/.env.example shipped BROWSER_BIND_ADDR=100.x.y.z as a live value, so
`cp .env.example .env && docker compose up` failed with Docker rejecting an
invalid IP instead of the guard message both troubleshooting tables promise.
Commented out, so the promised message is what you actually get.

DEPLOY §7 gains the two steps that were asserted but never instructed: a
Tailscale ACL, without which "Tailscale identity is the access control" is
aspirational and 9222 is open to every device on the tailnet; and a VPS
`free -m` reading before and after, without which the memory this move
reclaims cannot be shown.

Also drops a change-narration comment and three restatements of measured facts
that already have a canonical home.
2026-08-09 15:24:22 +07:00

54 lines
2.7 KiB
YAML

# Production override: join an existing Traefik network and let Traefik route
# bookmark-api.<domain> -> this service with TLS. No host port published.
#
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
#
# Set in .env:
# BOOKMARK_API_HOST=bookmark-api.example.com # your subdomain (required)
# BOOKMARK_WEB_HOST=bookmark.example.com # browser UI subdomain, same container (required)
# PROXY_NETWORK=proxy # Traefik's network name, if not "proxy"
# TRAEFIK_ENTRYPOINT=websecure # your HTTPS entrypoint name
# TRAEFIK_CERTRESOLVER=le # your ACME/cert resolver name
#
# The network must already exist and Traefik must watch it:
# docker network create proxy # if it doesn't yet
services:
bookmark-api:
# Traffic arrives over the Traefik network, not a published port.
ports: !reset []
# Compose *merges* this list with the base file's, so the service ends up on
# `default`, `db` and `proxy` — only the addition is named here. Do not
# "tidy" the base file down to `db` on the strength of `proxy` being present:
# `db` is `internal: true`, and egress comes from `default`.
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=${PROXY_NETWORK:-proxy}"
- "traefik.http.routers.bmapi.rule=Host(`${BOOKMARK_API_HOST:?set BOOKMARK_API_HOST in .env}`)"
- "traefik.http.routers.bmapi.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
- "traefik.http.routers.bmapi.tls=true"
- "traefik.http.routers.bmapi.tls.certresolver=${TRAEFIK_CERTRESOLVER:-le}"
- "traefik.http.services.bmapi.loadbalancer.server.port=8080"
# Second hostname for the browser UI, same container. Traefik needs the
# service named explicitly once more than one router targets it.
- "traefik.http.routers.bmapi.service=bmapi"
- "traefik.http.routers.bmweb.rule=Host(`${BOOKMARK_WEB_HOST:?set BOOKMARK_WEB_HOST in .env}`)"
- "traefik.http.routers.bmweb.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
- "traefik.http.routers.bmweb.tls=true"
- "traefik.http.routers.bmweb.tls.certresolver=${TRAEFIK_CERTRESOLVER:-le}"
- "traefik.http.routers.bmweb.service=bmapi"
# No browser service here. It runs on the home machine as its own unit
# (chrome/docker-compose.yml) and is reached over the tailnet — see
# docs/adr/0006-browser-on-the-home-machine.md. It must never be given a
# service on this host: `proxy` is shared with whatever else sits behind
# Traefik, and an unauthenticated CDP endpoint on it is remote code
# execution for any of them.
networks:
proxy:
external: true
name: ${PROXY_NETWORK:-proxy}