asxpio/docker-compose.yml
Sergei Poljanski 0cc3e1dece
All checks were successful
Build and Deploy to Production / test (push) Successful in 26s
Build and Deploy to Production / build (push) Successful in 1m11s
Build and Deploy to Production / deploy (push) Successful in 37s
bingo: add a reachability monitor for the status page
datacenterbingo gets a public page showing whether each datacenter's
network answers. The probing lives here, next to the schema and the
admin, since the public site only has a read-only role.

bin/monitor runs as a second container from the same image. Once a
minute it opens one TCP connection to every active target (a handshake
or a refusal both count as answered) and folds the results into
5-minute rows per datacenter, plus a per-bucket row for control hosts in
Russia, so a lost vantage point isn't mistaken for dark sites. Rows are
kept 30 days. Targets are managed at /admin/bingo/monitor; only hosts a
public source ties to that one site belong there.

Migration 017 also grants the new tables to the bingo role, so the
public site can read them without a storage redeploy.

Assisted-by: Claude:opus-5-5
2026-10-18 10:31:00 +04:00

45 lines
1.4 KiB
YAML

services:
asxpio:
# Image will be dynamically updated during deployment
# Format: registry.example.com/user/asxpio:sha_tag
build: .
image: asxpio:latest
container_name: asxpio
restart: unless-stopped
env_file: .env
networks:
- traefik
- storage
labels:
- "traefik.enable=true"
- "traefik.http.routers.asxpio.rule=Host(`asxp.io`) || Host(`www.asxp.io`)"
- "traefik.http.routers.asxpio.entrypoints=websecure"
- "traefik.http.routers.asxpio.tls=true"
- "traefik.http.routers.asxpio.tls.certresolver=letsencrypt"
- "traefik.http.routers.asxpio.service=asxpio"
- "traefik.http.services.asxpio.loadbalancer.server.port=3000"
# Reachability worker for datacenterbingo's status page (bin/monitor).
# Same image; the deploy's sed sets both image lines.
asxpio-monitor:
image: asxpio:latest
container_name: asxpio-monitor
restart: unless-stopped
env_file: .env
command: ["ruby", "bin/monitor"]
networks:
- storage # postgres; not internal, so probes reach the internet
mem_limit: 256m
healthcheck:
# The worker touches its heartbeat after every round (60 s).
test: ["CMD", "ruby", "-e", "exit(Time.now - File.mtime('/tmp/monitor.heartbeat') < 300 ? 0 : 1)"]
interval: 60s
timeout: 10s
start_period: 120s
retries: 3
networks:
traefik:
external: true
storage:
external: true