# Hetzner VPS (junior.gib, rootless podman): ~/Server/Gbrown_Agent/compose.yml. # Follows ~/Server/AGENTS.md. AGENT_INGEST_SECRET lives in ./.env (never # committed). Started by podman-gbrown-agent.service, never by hand. # # SELinux: # - The podman socket is mounted with no relabel flag, ever (AGENTS.md §6). # - Reading it needs `label:disable`, the same exception portainer and uptime # have as container-management tooling. # - Because labeling is off, the NPM logs mount also takes no :z or :Z. # NPM mounts its data dir with :Z (a private MCS pair), so relabeling it here # would lock NPM out of its own data. networks: nginx-bridge: external: true services: gbrown-agent: image: git.gbrown.org/gib/gbrown-agent:latest container_name: gbrown-agent hostname: gbrown-agent networks: ['nginx-bridge'] environment: - TZ=America/New_York - HOST_ID=vps - INGEST_URL=https://convex.gbrown.org/ingest - AGENT_INGEST_SECRET=${AGENT_INGEST_SECRET} # Reach Convex over WireGuard, not Cloudflare: pin the hostname to the # Home Server's proxy (192.168.1.2, routed via the `Home` interface). The # URL stays https with the real hostname, so SNI and the certificate check # are unchanged. extra_hosts: - 'convex.gbrown.org:192.168.1.2' # The image runs as uid 1000 (bun). keep-id maps it to gib, who owns the # podman socket and the NPM logs (AGENTS.md §3.2). Never `user: 1000:1000`. userns_mode: 'keep-id:uid=1000,gid=1000' volumes: - /run/user/1000/podman/podman.sock:/var/run/docker.sock # no :Z, ever - /home/gib/Server/Nginx_Proxy_Manager/volumes/data/logs:/npm-logs:ro security_opt: ['label:disable', 'no-new-privileges:true'] read_only: true cap_drop: [ALL] restart: unless-stopped stop_grace_period: 10s