# Production reference: the fleet server behind Caddy.
#
# Caddy terminates TLS on 443 with a publicly trusted certificate and renews
# it automatically (ACME). The dashboard and enrolment endpoint are reachable
# only through it, port 3000 stays on the compose network and is never
# published. Plain HTTP is the tyre-kicking path in `docker-compose.yml`, for
# a server on your own machine; HTTP in production is unsupported.
#
#   1. cp Caddyfile.example Caddyfile, put your domain in it and in
#      NF_STREAM_SAN below (DNS for the name must point at this host, with
#      80 and 443 reachable for the ACME challenge).
#   2. Set NF_STREAM_SAN in the environment BEFORE the first start.
#   3. docker compose -f docker-compose.production.yml up -d
#   4. Create the first user to require dashboard sign-in:
#        docker compose -f docker-compose.production.yml exec nf-server \
#            nf-server create-operator --username admin --role owner

services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"     # ACME challenge + redirect to HTTPS
      - "443:443"   # dashboard + enrolment, publicly trusted certificate
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config

  nf-server:
    # Pulls the published server image (pushed by every release, :latest =
    # the current release). To build from this tree instead, swap in:
    #   build: { context: ., target: server }
    image: registry.nexustelemetry.com/nf-server:latest
    restart: unless-stopped
    # The collector mTLS stream is published directly and must NOT pass
    # through Caddy or any other terminating proxy: the collector verifies
    # this port against the fleet server's own private chain, pinned at
    # enrolment, and will refuse Caddy's publicly trusted certificate.
    #
    # No dashboard port here, on purpose, 3000 is reachable only on the
    # compose network, through Caddy. Never publish it alongside.
    ports:
      - "9443:9443"
    environment:
      # The public name collectors dial. Set BEFORE the first start: it is
      # baked into the stream certificate when the server first runs.
      # Required, from the environment (compose refuses to start without it):
      #   NF_STREAM_SAN=fleet.example.com docker compose -f docker-compose.production.yml up -d
      NF_STREAM_SAN: "${NF_STREAM_SAN:?required, see the comment above}"
      # NF_INITIAL_ADMIN_PASSWORD: "change-me"  # seed an admin on first run
      # NF_LOG_FORMAT: "pretty"                 # json is the default
    volumes:
      - nf-data:/var/lib/nexus-fleet
    # HEALTHCHECK is defined in the image (GET /health).
    stop_grace_period: 20s

volumes:
  nf-data:
  caddy-data:
  caddy-config:
