Skip to content

Commit dadee08

Browse files
committed
ci: use Portainer git polling as primary CD; make API redeploy best-effort
Portainer host is behind a WAF that blocks GitHub-hosted runner IPs, so the direct API redeploy is marked continue-on-error and the stack's 5-minute git polling drives continuous deployment.
1 parent bdb9e33 commit dadee08

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ jobs:
6161
needs: build-and-push
6262
if: github.ref == 'refs/heads/main'
6363
runs-on: ubuntu-latest
64+
# Primary CD is Portainer's git polling (the stack pulls this repo every 5m and
65+
# redeploys on new commits). This job is a best-effort fast-path that pushes the
66+
# redeploy immediately; it is allowed to fail when the Portainer host sits behind
67+
# a WAF that blocks GitHub-hosted runner IPs.
68+
continue-on-error: true
6469
steps:
6570
- name: Trigger Portainer git redeploy
6671
env:

README.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,35 @@ docker compose up -d --build
134134

135135
## Deployment & CI/CD
136136

137+
The live instance runs as a **Portainer Git stack** that builds the image on the
138+
host from this repository.
139+
140+
**Continuous deployment** is driven by Portainer's Git polling: the stack checks
141+
this repo every 5 minutes and automatically rebuilds and redeploys whenever
142+
`main` advances. This needs no inbound connection to the host, so it works even
143+
when Portainer sits behind a WAF/Cloudflare.
144+
137145
Pushing to `main` runs [`deploy.yml`](.github/workflows/deploy.yml):
138146

139-
1. Builds a multi-arch image and pushes it to `ghcr.io/mroplus/sshid`.
140-
2. Calls the Portainer API to redeploy the stack with `PullImage: true`.
147+
1. **Build & push** a container image to `ghcr.io/mroplus/sshid` (published
148+
artifact, also usable with `docker-compose.prod.yml`).
149+
2. **Redeploy** — a best-effort call to the Portainer API for an immediate
150+
rollout. It is marked `continue-on-error` because GitHub-hosted runner IPs may
151+
be blocked by the host's WAF; Git polling remains the reliable fallback.
141152

142-
Required repository secrets:
153+
Required repository secrets (for the best-effort fast-path):
143154

144155
| Secret | Example |
145156
| ----------------------- | -------------------------------- |
146157
| `PORTAINER_URL` | `https://portainer.koorosh.me` |
147158
| `PORTAINER_API_KEY` | `ptr_…` |
148-
| `PORTAINER_STACK_ID` | `15` |
159+
| `PORTAINER_STACK_ID` | `16` |
149160
| `PORTAINER_ENDPOINT_ID` | `3` |
150161

151-
The live instance is published at **https://sshid.koorosh.me** through a
152-
Cloudflare Tunnel that maps the hostname to the container's host port.
162+
The instance is reached at **https://sshid.koorosh.me** through the host's
163+
Cloudflare Tunnel, which maps the public hostname to the container's host port
164+
(`3008`). Because `RP_ID`/`PUBLIC_ORIGIN` are domain-bound for WebAuthn, the
165+
public hostname must point at the container for passkeys to work.
153166

154167
## License
155168

0 commit comments

Comments
 (0)