Repository navigation
Expand file tree
/
Copy pathcompose.yaml
More file actions
127 lines (123 loc) · 6.2 KB
/
Copy pathcompose.yaml
File metadata and controls
127 lines (123 loc) · 6.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# Single-host Fleet Manager: the manager plus its Postgres.
#
# This is the supported topology for a small fleet. Everything the manager reads
# lives under /etc/cryptos/fleet on the host and is mounted read-only; see the
# README and docs/deploying-standalone.md.
#
# docker compose -f deploy/compose.yaml up -d
#
# Before the first start, on the host:
#
# sudo install -d -m 0755 /etc/cryptos/fleet
# sudo install -d -m 0700 /etc/cryptos/fleet/secrets
# sudo install -o 65532 -g 65532 -m 0400 config.yaml /etc/cryptos/fleet/config.yaml
# printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -base64 24)" \
# | sudo install -m 0400 /dev/stdin /etc/cryptos/fleet/secrets/postgres.env
#
# That is enough for day zero: with no tlsCert and no operatorCAPath in
# config.yaml the manager serves a self-signed certificate and prints a
# single-use bootstrap token in its log (docker compose logs manager), and
# first run registers your operator CA (docs/first-run.md).
#
# Optional, each with its mount uncommented below and its key set in
# config.yaml:
#
# # A real server certificate (tlsCert, tlsKey):
# sudo install -d -o 65532 -g 65532 -m 0750 /etc/cryptos/fleet/tls
# sudo install -o 65532 -g 65532 -m 0444 fullchain.pem /etc/cryptos/fleet/tls/tls.crt
# sudo install -o 65532 -g 65532 -m 0400 server.key /etc/cryptos/fleet/tls/tls.key
# # The operator CA from a file instead of first run (operatorCAPath):
# sudo install -d -o 65532 -g 65532 -m 0750 /etc/cryptos/fleet/operator-ca
# sudo install -o 65532 -g 65532 -m 0444 operator-ca.crt /etc/cryptos/fleet/operator-ca/operator-ca.pem
# # CRL files for that operator CA (operatorCRL path entries):
# sudo install -d -o 65532 -g 65532 -m 0750 /etc/cryptos/fleet/operator-crl
# sudo install -o 65532 -g 65532 -m 0444 operator-ca.crl /etc/cryptos/fleet/operator-crl/operator-ca.crl
#
# Two different readers, and mixing them up is the trap here:
#
# * config.yaml, tls/, operator-ca/ and operator-crl/ are read by the MANAGER, which is
# distroless nonroot, so they must be readable by uid 65532.
# * secrets/postgres.env is read by the COMPOSE CLI on the host before any
# container starts, so it must be readable by whoever runs `docker compose`
# -- root under sudo or systemd. Do NOT chown it to 65532: that only makes
# it unreadable to the thing that actually needs it, and `up` fails with
# "permission denied" on the env file.
#
# The parent /etc/cryptos/fleet stays root-owned and traversable so both readers
# can reach their own subdirectory; the secrets are protected by the 0700 on
# secrets/ rather than by the parent.
name: cryptos-fleet
services:
postgres:
# Pin the major version. A major upgrade needs a dump and restore, so
# letting this float would break a restart at an unpredictable moment.
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_DB: manager
POSTGRES_USER: manager
POSTGRES_INITDB_ARGS: "--data-checksums"
# POSTGRES_PASSWORD only, kept out of this file so the compose file is not
# a secret. It must match the password in the manager's database_url.
env_file:
- /etc/cryptos/fleet/secrets/postgres.env
volumes:
# /var/lib/postgresql, NOT /var/lib/postgresql/data. From 18 the image
# stores data in major-version-specific subdirectories so pg_upgrade can
# work across a single mount, and a volume on the old .../data path is
# rejected outright: "there appears to be PostgreSQL data in
# /var/lib/postgresql/data (unused mount/volume)".
- pgdata:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U manager -d manager"]
interval: 5s
timeout: 5s
retries: 30
manager:
# Pin a released tag in production; latest is here so the example runs
# before you have chosen a version. To run an image you built yourself,
# build it with deploy/build-image.sh (so /version reports it) and set
# MANAGER_IMAGE to its tag.
image: ${MANAGER_IMAGE:-ghcr.io/cryptos-pki/cryptos-manager:${MANAGER_VERSION:-latest}}
restart: unless-stopped
# Nothing in the image is written at runtime except the node-creds volume
# below, so the root filesystem is read-only and a stray write fails
# loudly instead of vanishing with the container. The health check comes
# from the image (the manager probes its own /healthz).
read_only: true
cap_drop: [ALL]
security_opt:
- no-new-privileges:true
depends_on:
postgres:
# Honoured by `up`, but NOT by `docker compose restart`, which is why
# the manager waits for Postgres itself at startup rather than relying
# on this. Both are kept: this orders the first boot, and the wait
# covers every restart path.
condition: service_healthy
ports:
# Published 80 and 443; the container listens on 8080 and 8443 because it
# runs unprivileged and cannot bind a low port. Port 80 only redirects to
# HTTPS. If you publish HTTPS on anything other than 443, set
# httpsPublicPort in config.yaml to the published port.
- "443:8443"
- "80:8080"
volumes:
# config.yaml holds the Postgres DSN, so it is a secret, not config.
- /etc/cryptos/fleet/config.yaml:/etc/cryptos/fleet/config.yaml:ro
# Optional, commented out for day zero. Uncomment each one together with
# its key in config.yaml: tls with tlsCert and tlsKey, operator-ca with
# operatorCAPath (which turns first run off), operator-crl with
# operatorCRL path entries (only with operatorCAPath). The manager
# re-reads CRL files on every refresh, so replacing one needs no restart.
# - /etc/cryptos/fleet/tls:/etc/cryptos/fleet/tls:ro
# - /etc/cryptos/fleet/operator-ca:/etc/cryptos/fleet/operator-ca:ro
# - /etc/cryptos/fleet/operator-crl:/etc/cryptos/fleet/operator-crl:ro
# The one writable path: the admin key the manager mints for each node it
# adopts. Lose it and the manager is locked out of every adopted node, so
# back this volume up with the database. On first use Docker copies the
# image's directory, owned by 65532, into the empty volume.
- node-creds:/var/lib/cryptos-manager/node-creds
volumes:
pgdata:
node-creds: