- Drop 'set -euo pipefail' from the redeploy step so the auto-discovery
loop and the diagnostic echos can run to completion even if a probe
fails or a command returns empty output.
- On failure to find Portainer, also print the container's hostname,
hostname -I, and ip route to stderr. This is what we'll need if the
host-net job container approach doesn't work and we need to debug
further.
Adds Step 0a that prints hostname -I, ip route, and a direct curl to
192.168.1.30:9000. This is to verify whether the runner external (in
network_mode: host) is actually propagating host networking to the job
containers it spawns. Symptom: deploy step fails with 'Failed to
connect to 192.168.1.30 port 9000' even from the external runner.
To be removed once we know.
The act_runner on the QNAP creates an ephemeral docker bridge per job.
That network can't always reach the canonical PORTAINER_URL
(http://192.168.1.30:9000) — first deploy run failed with
'Failed to connect to 192.168.1.30 port 9000 after 130317 ms'.
New step 0 probes several candidate URLs (container's own IPs, default
gateways, then the secret value as fallback) against /api/status and
uses the first one that returns 200. The reachable host is then reused
for the DELETE+CREATE calls and the smoke-test on :3001.
Documents the current pipeline anatomy, the metrics to capture on the
first real run, hypothesised bottlenecks, and ranked optimisation
proposals. Placeholders for real numbers; to be filled in after the
first deploy lands.
Companion to the Portainer redeploy step in .gitea/workflows/ci-cd.yaml
on the same branch.
- Build pushes both :latest and :0.0.1 tags so the redeploy step uses the
pinned version regardless of how the runner happened to be tagged before.
- Add a 4th step 'Redeploy stack on Portainer' that runs ONLY when the
workflow is manually dispatched with deploy=true.
- Step does idempotent DELETE+CREATE on the existing stack via Portainer REST
(PUT-edit would require more plumbing for a single-service stack).
- Smoke-tests http://<host>:3001/ after the stack recreates; logs the code
but does not hard-fail the job (network-proxy reachable via NPM upstream).
Required new secrets (in addition to existing DOCKER_USERNAME/DOCKER_PASSWORD):
- PORTAINER_URL e.g. http://192.168.1.30:9000
- PORTAINER_TOKEN API access token from a Portainer user
- PORTAINER_ENDPOINT_ID numeric endpoint ID (usually 1)
- PORTAINER_STACK_ID numeric stack ID to delete before recreating
Apply the same concurrency pattern used in the python-project-template:
- cancel-in-progress: false prevents the shared act_runner from
cancelling in-progress steps when a new push lands
- pull_request trigger ensures PRs are validated before merge
- workflow_dispatch allows manual re-runs
- Homepage with hero, featured projects, latest posts sections
- Content collections config (blog + projects schemas)
- Date formatting and reading time utilities
- Sample blog post and project for validation
- Add base layouts (BaseLayout, BlogLayout, ProjectLayout)
- Add UI components (Header, Footer, Navigation, Card, Tag)
- Add About page with personal story
- Add Projects pages (index, detail)
- Add homepage content
- Add SEO files (robots.txt, webmanifest)
Work was done by agents in isolated workspaces.
Consolidated into main repo for proper git tracking.