- Database nodes now join the Docker Swarm as workers with `role=db` labels, allowing Swarm to manage their dedicated services. - The `docker-stack-infra.yml` has been updated for production to focus solely on application-level infrastructure components. - Dedicated database services (PostgreSQL, MongoDB, Patroni-etcd) are now explicitly deployed in separate Swarm stacks on `iklim-db-XX` nodes. - Standardizes node naming conventions (`iklim-app-XX`, `iklim-db-XX`) across the production roadmap documentation. - Clarifies that the `etcd` service within `docker-stack-infra.yml` is exclusively for APISIX configuration, distinct from Patroni's etcd cluster.
76 lines
2.2 KiB
Markdown
76 lines
2.2 KiB
Markdown
# 01 — Docker Swarm Init (Test)
|
||
|
||
## Context
|
||
- **Repo:** `iklim.co` root
|
||
- **Environment:** test
|
||
- **Server:** single node — same machine is both Swarm manager and worker
|
||
- **Sizing:** Terraform test app node is `cpx42`; see `../../hetzner-sizing-report.md`
|
||
- Pipeline trigger: push to `test-env` branch → Gitea runner executes directly on the test server
|
||
- `init/swarm-init.sh` already exists in the repo and is called by the pipeline
|
||
|
||
## Prerequisites
|
||
- Docker Engine installed on test server
|
||
- User running the pipeline has Docker access (group `docker` or root)
|
||
|
||
## Step 1 — Verify / update `init/swarm-init.sh`
|
||
|
||
Check that the script handles idempotent init:
|
||
|
||
```bash
|
||
grep -n "swarm init" init/swarm-init.sh
|
||
```
|
||
|
||
The script must contain logic similar to:
|
||
|
||
```bash
|
||
if ! docker info --format '{{.Swarm.LocalNodeState}}' | grep -q "active"; then
|
||
docker swarm init --advertise-addr $(hostname -I | awk '{print $1}')
|
||
echo "✅ Swarm initialized"
|
||
else
|
||
echo "ℹ️ Swarm already active, skipping init"
|
||
fi
|
||
```
|
||
|
||
If this guard is missing, add it. Without it, the step fails on second deploy.
|
||
|
||
## Step 2 — Run via pipeline
|
||
|
||
The pipeline step `Initialize Docker Swarm` in `.gitea/workflows/deploy-test.yml` already calls:
|
||
|
||
```bash
|
||
/bin/bash init/swarm-init.sh
|
||
```
|
||
|
||
No manual action needed after the script is correct.
|
||
|
||
## Step 3 — Apply node label
|
||
|
||
The `type=service` label is required for placement constraints in `docker-stack-infra.yml`.
|
||
Run once after Swarm init (Ansible handles this in automated setup):
|
||
|
||
```bash
|
||
docker node update --label-add type=service $(docker node ls -q)
|
||
```
|
||
|
||
## Step 4 — Verify
|
||
|
||
SSH into the test server and run:
|
||
|
||
```bash
|
||
docker node ls
|
||
```
|
||
|
||
Expected: one node, `STATUS=Ready`, `AVAILABILITY=Active`, `MANAGER STATUS=Leader`.
|
||
|
||
```bash
|
||
docker node inspect self --format '{{.Spec.Labels}}'
|
||
```
|
||
|
||
Expected: `map[type:service]`.
|
||
|
||
## Notes
|
||
- Single-node Swarm: node is simultaneously manager and worker (`AVAILABILITY=Active`, not drained).
|
||
- Placement constraints `node.role == manager` and `node.labels.type == service` both resolve to this machine.
|
||
- No worker-join or manager-join steps needed for test.
|
||
- Docker Swarm overlay network `iklimco-net` is created automatically on first `docker stack deploy`.
|