Environment_Infrastructure/roadmap/test-env/03-infra-stack-changes.md
Murat ÖZDEMİR fd6a0b4f46 docs: fix roadmap inconsistencies between test-env and prod-env
Corrects six documentation files to match the actual deployed pipeline
behavior and align test/prod approaches where they share the same code.

prod-env/02-godaddy-credentials.md
- Step 1: correct secret file from .env.secrets.shared to .env.secrets.swag;
  add clarifying note that .env.secrets.shared holds AppRole/DB secrets
  and must not be used for GoDaddy credentials.
- Step 4: document that GoDaddy A records are now managed automatically
  by the pipeline's 'Update DNS Records' step via the GoDaddy API;
  reference the Gitea variable PROD_FLOATING_IP that must be set once.

prod-env/08-deploy-pipeline-update.md
- Add Step 2 documenting the new 'Update DNS Records' pipeline step
  (GoDaddy API, idempotent check-before-update, requires jq and
  vars.PROD_FLOATING_IP).
- Renumber subsequent steps 3-8 to accommodate the new step.
- Fix DB hostnames in Step 7 (Run Database Init Scripts) from
  iklimco_postgresql/iklimco_mongodb to postgresql/mongodb, matching
  how Swarm overlay DNS resolves service names inside iklimco-net.
- Update context block: correct DB hostname description, replace
  outdated storagebox path note with env-var approach, list new steps.
- Update final step order to 24 steps including the DNS step and
  Release Deploy Lock; mark Wait for etcd as NEW.

prod-env/09-verify.md
- Insert check #2 for the precipitation image directory
  (/mnt/storagebox/precipitation/images) and iklimco_image-data volume
  bind mount, mirroring the equivalent check in test-env/08-verify.md.
- Renumber all subsequent checks (3-12) to maintain sequential ordering.

test-env/03-infra-stack-changes.md
- Update SWAG service volume snippet: replace hardcoded paths
  (swag-vl:/config, /opt/iklimco/swag/dns-conf, /opt/iklimco/swag/site-confs)
  with env-var forms (${SWAG_CONFIG_DIR:-swag-vl}, ${SWAG_DNS_CONF_DIR:-...},
  ${SWAG_SITE_CONFS_DIR:-...}) to match docker-stack-infra.yml.
- Update cert-reloader volume snippet: replace swag-vl and /opt/iklimco/ssl
  with ${SWAG_CONFIG_DIR:-swag-vl} and ${SWAG_CERT_DIR:-/opt/iklimco/ssl},
  enabling StorageBox override in prod without changing the base file.

test-env/04-swag-nginx-configs.md
- Replace RESTRICTED_IP_1/RESTRICTED_IP_2 individual env vars with
  RESTRICTED_IPS (comma-separated CIDR list) in the required-vars section,
  matching env-test/.env and the actual pipeline.
- Update all three IP-restricted template examples (apigw, rabbitmq,
  grafana) from allow ${RESTRICTED_IP_1}; allow ${RESTRICTED_IP_2}; to
  ${RESTRICTED_IPS_BLOCK}, matching the actual .conf.tpl files in the repo.
- Rewrite the deploy step section to match the real pipeline: docker run
  alpine for file writing, RESTRICTED_IPS_BLOCK generation via sed, and
  envsubst with explicit SWAG_VARS filter to protect nginx $upstream_* vars.

test-env/07-deploy-pipeline-update.md
- Step 2 (Prepare SWAG Directories): replace sudo-tee approach with the
  actual docker-run-alpine method used in deploy-test.yml; add nginx
  reload block; update notes to reflect RESTRICTED_IPS_BLOCK generation.
- Step 4 (Re-order): correct step numbering to match actual pipeline
  (21 steps); mark 'Wait for etcd' as already present in pipeline rather
  than a new addition; add Bootstrap Vault TLS Placeholder which was
  missing from the documented order.
2026-05-16 16:52:48 +03:00

241 lines
6.1 KiB
Markdown

# 03 — docker-stack-infra.yml Changes (Test)
## Context
- **File:** `docker-stack-infra.yml` (repo root)
- **Goal:** Add SWAG as TLS-terminating reverse proxy; remove all published ports from internal
services (they become reachable only via SWAG through the `iklimco-net` overlay network);
remove Vault's external port entirely.
## Changes Summary
| Service | Before | After |
|---------|--------|-------|
| **swag** | does not exist | add: ports 80+443, manager-pinned |
| **cert-reloader** | does not exist | add: manager-pinned, Docker socket |
| **vault** | publishes 8200 | no published port |
| **apisix** | publishes 8080, 8443, 9180 | no published ports |
| **rabbitmq** | publishes 5672, 15672, 61613, 15674 | no published ports |
| **prometheus** | publishes 9090 | no published port |
| **grafana** | publishes 3000 | no published port |
| **apisix-dashboard** | publishes 9000 | no published port |
> **RabbitMQ STOMP note:** Ports 61613 (STOMP) and 15674 (WebSocket STOMP) are removed because
> APISIX already proxies WebSocket STOMP to RabbitMQ via the overlay network. Verify that
> APISIX has a stream/WebSocket route for STOMP before removing these if external clients
> connect to STOMP directly (not via APISIX).
## Step 1 — Add `swag` service
Add after the `apisix-dashboard` service block:
```yaml
swag:
image: lscr.io/linuxserver/swag:latest
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Istanbul
- URL=iklim.co
- SUBDOMAINS=wildcard
- VALIDATION=dns
- DNSPLUGIN=godaddy
- ONLY_SUBDOMAINS=false
- EMAIL=muratozdemir@tarla.io
- DNSPROPAGATION=90
volumes:
- ${SWAG_CONFIG_DIR:-swag-vl}:/config
- ${SWAG_DNS_CONF_DIR:-/opt/iklimco/swag/dns-conf}:/config/dns-conf
- ${SWAG_SITE_CONFS_DIR:-/opt/iklimco/swag/site-confs}:/config/nginx/site-confs
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
delay: 5s
labels:
project: co.iklim
```
## Step 2 — Add `cert-reloader` service
Add after the `swag` service block:
```yaml
cert-reloader:
image: docker:27-cli
volumes:
- ${SWAG_CONFIG_DIR:-swag-vl}:/swag-config:ro
- ${SWAG_CERT_DIR:-/opt/iklimco/ssl}:/host-ssl
- /var/run/docker.sock:/var/run/docker.sock
entrypoint: ["/bin/sh", "-c"]
command:
- |
CERT_DIR=/swag-config/etc/letsencrypt/live/iklim.co
HOST_DIR=/host-ssl
LAST_HASH=""
echo "[cert-reloader] started"
while true; do
if [ -f "$$CERT_DIR/fullchain.pem" ]; then
CURR=$$(md5sum "$$CERT_DIR/fullchain.pem" | cut -d' ' -f1)
if [ "$$CURR" != "$$LAST_HASH" ]; then
echo "[cert-reloader] cert changed — copying and reloading Vault"
cp "$$CERT_DIR/fullchain.pem" "$$HOST_DIR/STAR.iklim.co.full.crt"
cp "$$CERT_DIR/privkey.pem" "$$HOST_DIR/STAR.iklim.co_key.pem"
docker service update --force iklimco_vault
LAST_HASH="$$CURR"
echo "[cert-reloader] done"
fi
fi
sleep 3600
done
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
delay: 10s
labels:
project: co.iklim
```
> `$$` is required in Docker Swarm YAML to escape `$` and prevent host-side variable expansion.
## Step 3 — Remove `vault` published port
Find the `vault` service `ports:` block and **delete it entirely**:
```yaml
# DELETE this entire block from vault service:
ports:
- target: 8200
published: 8200
protocol: tcp
mode: host
```
Vault remains reachable within `iklimco-net` via the overlay alias `vault.iklim.co:8200`.
The `VAULT_LOCAL_CONFIG` `api_addr` and `networks.default.aliases` entries stay unchanged.
## Step 4 — Remove `apisix` published ports
Find the `apisix` service `ports:` block and **delete it entirely**:
```yaml
# DELETE this entire block from apisix service:
ports:
- target: 9080
published: 8080
protocol: tcp
mode: host
- target: 9443
published: 8443
protocol: tcp
mode: host
- target: 9180
published: 9180
protocol: tcp
mode: host
```
APISIX admin API (9180) access: use `docker exec` or SSH tunnel.
APISIX is reachable from SWAG via `http://apisix:9080` on the overlay network.
## Step 5 — Remove `apisix-dashboard` published port
```yaml
# DELETE from apisix-dashboard:
ports:
- target: 9000
published: 9000
protocol: tcp
mode: host
```
## Step 6 — Remove `rabbitmq` published ports
```yaml
# DELETE from rabbitmq:
ports:
- target: 5672
published: 5672
protocol: tcp
mode: host
- target: 15672
published: 15672
protocol: tcp
mode: host
- target: 61613
published: 61613
protocol: tcp
mode: host
- target: 15674
published: 15674
protocol: tcp
mode: host
```
## Step 7 — Remove `prometheus` published port
```yaml
# DELETE from prometheus:
ports:
- target: 9090
published: 9090
protocol: tcp
mode: host
```
## Step 8 — Remove `grafana` published port
```yaml
# DELETE from grafana:
ports:
- target: 3000
published: 3000
protocol: tcp
mode: host
```
## Step 9 — Add `swag-vl` volume
In the `volumes:` section at the bottom of the file, add:
```yaml
swag-vl:
labels:
project: co.iklim
```
## Verification
After deploy:
```bash
docker service ls --filter label=project=co.iklim
```
Confirm `iklimco_swag` and `iklimco_cert-reloader` appear in the list.
```bash
docker service ps iklimco_swag
docker service ps iklimco_cert-reloader
```
Both should show `Running`.