Document live GitOps production deployment
build / build (push) Successful in 2m48s

This commit is contained in:
2026-09-15 18:42:09 +02:00
parent 645c00d8de
commit 61d6d21d88
3 changed files with 37 additions and 8 deletions
+11 -6
View File
@@ -29,12 +29,17 @@ Docker runs alongside local dev on different ports:
The image does not set `BTCDATA_URL`; deployments must provide it. `BUILD_SHA` is embedded as The image does not set `BTCDATA_URL`; deployments must provide it. `BUILD_SHA` is embedded as
`APP_VERSION` and exposed at `/api/version`. The port in `CMD` is hardcoded to 4040. `APP_VERSION` and exposed at `/api/version`. The port in `CMD` is hardcoded to 4040.
## CI/CD ## CI/CD and production
`.gitea/workflows/build.yml` tests pushes to `main` and `v*` tags, then publishes immutable `.gitea/workflows/build.yml` tests pushes to `main` and `v*` tags on the `anvil` Gitea Actions
linux/amd64 images to `harbor.pmagnus.cloud/btcprice/btcprice`. It embeds the short Git SHA as runner, then publishes immutable linux/amd64 images to
`APP_VERSION`. CI has no Kubernetes credentials; the planned Flux deployment belongs in `harbor.pmagnus.cloud/btcprice/btcprice`. It embeds the short Git SHA as `APP_VERSION`.
`magnus/deploy` once the shared GitOps gate is complete.
Flux image automation updates the manifests in the separate `magnus/deploy` repository and Flux
reconciles k3s. CI has no Kubernetes credentials. Production runs two replicas—one on hostinger and
one on citadel—and is served at https://btcprice.k8s.pmagnus.cloud through ingress-nginx and
hostinger Traefik TLS. Deployment changes belong in `../deploy/apps/btcprice`; do not deploy with
Compose or manual `kubectl apply`.
## Legacy deployment ## Legacy deployment
@@ -46,7 +51,7 @@ Mirrors `../elprice/deploy-citadel.sh`; no registry.
- btcdata also runs on citadel, so both attach to the external `btc-network` there and - btcdata also runs on citadel, so both attach to the external `btc-network` there and
`BTCDATA_URL` is `http://btcdata:4102` (service name, not a LAN address). The deploy script `BTCDATA_URL` is `http://btcdata:4102` (service name, not a LAN address). The deploy script
creates the network on the remote if it is missing. creates the network on the remote if it is missing.
- Live at http://192.168.50.195:4041. - Temporary migration fallback at http://192.168.50.195:4041; it is not the production endpoint.
## Architecture ## Architecture
+21 -2
View File
@@ -52,6 +52,24 @@ SHA, available from `/api/version`.
The workflow requires the repository secrets `HARBOR_ROBOT_USER` and `HARBOR_ROBOT_TOKEN`. It only The workflow requires the repository secrets `HARBOR_ROBOT_USER` and `HARBOR_ROBOT_TOKEN`. It only
pushes images and intentionally has no Kubernetes credentials. pushes images and intentionally has no Kubernetes credentials.
## Production deployment
Production is GitOps-managed at **https://btcprice.k8s.pmagnus.cloud**:
```text
git push → Gitea Actions on anvil → Harbor → Flux → k3s → ingress-nginx → Traefik TLS
```
Flux image automation commits the newest approved `main-<UTC timestamp>` image to the separate
`magnus/deploy` repository. The manifests are in `../deploy/apps/btcprice`, and two replicas run with
one pod on each k3s node. CI never receives cluster credentials. Do not deploy production with
Docker Compose or manual `kubectl apply`; rollback by reverting the immutable image change in the
GitOps repository.
btcdata remains an external dependency running on citadel. Kubernetes represents it with a
selectorless Service and EndpointSlice, so pods use `http://btcdata:4102` without embedding its IP in
the Deployment.
## Legacy deployment (citadel) ## Legacy deployment (citadel)
```bash ```bash
@@ -64,8 +82,9 @@ architecture (citadel is x86_64 → `linux/amd64`), copies `docker-compose.citad
pipes the image over SSH with `docker save | docker load`, and runs pipes the image over SSH with `docker save | docker load`, and runs
`docker compose up -d --no-build`. No registry involved. `docker compose up -d --no-build`. No registry involved.
Deployed btcprice listens on **http://192.168.50.195:4041** and proxies to the btcdata running The temporary migration fallback listens on **http://192.168.50.195:4041** and proxies to the
on citadel as well. Both attach to the external `btc-network` there, so `BTCDATA_URL` is btcdata running on citadel as well. It is retained only for the validation/rollback window; the
Kubernetes hostname is the production endpoint. Both attach to the external `btc-network` there, so `BTCDATA_URL` is
`http://btcdata:4102` (set in `.env.citadel`) — the service name inside the network, not a LAN `http://btcdata:4102` (set in `.env.citadel`) — the service name inside the network, not a LAN
address. The deploy script creates `btc-network` on the host if it does not exist yet. address. The deploy script creates `btc-network` on the host if it does not exist yet.
+5
View File
@@ -1,5 +1,10 @@
# btcprice GitOps migration plan # btcprice GitOps migration plan
**Status (2026-09-15):** Phases 1–6 implemented and verified. The GitOps deployment is live with
one Ready replica on each k3s node, trusted TLS, working HTTP/WebSockets, and a successful unattended
source-to-production update. Compose remains online for the required 24-hour validation/rollback
window; Phase 7 is intentionally pending.
**Target path** **Target path**
```text ```text