3.9 KiB
Armandine
Static gallery site served by Nginx. Runs as a repository-based container; image is built and pushed via Woodpecker CI/CD from this repo.
Stack
- Site: Static HTML/CSS/JS in
src/, copied into the image. - Runtime:
nginx:alpine(seeDockerfile). - Registry: Gitea at
git.mifi.dev→ imagegit.mifi.dev/mifi-holdings/armandine. - Deploy: Portainer on Linode; stack uses this image (no volume for site content).
Local development
# Install dev dependencies (ESLint, Prettier, Stylelint)
pnpm install
# Lint JS and CSS
pnpm lint
# Check formatting (CI uses this)
pnpm format:check
# Fix formatting
pnpm format
# Preview site locally (serves src/ on http://localhost:3000)
pnpm serve
Dev container
Open the repo in a dev container (VS Code/Cursor: Dev Containers: Reopen in Container) for a consistent environment:
- Node 22 (matches CI), with
pnpm installrun after create - Docker (outside of Docker) – uses the host Docker socket so you can run
pnpm buildand test the image inside the dev container - ESLint, Prettier, Stylelint extensions plus format-on-save and fix-on-save
Port 3000 is forwarded for pnpm serve; port 80 is forwarded if you run the built Nginx container locally.
Manual build and push
When you want to build and push the image yourself (e.g. before CI was set up, or for a one-off deploy):
-
Log in to the Gitea container registry:
docker login git.mifi.devUse your Gitea username and a token with package permissions.
-
Build the image (tags as
latest):pnpm buildThis runs:
docker build -t git.mifi.dev/mifi-holdings/armandine:latest . -
Push to the registry:
pnpm pushThen on the server, redeploy the stack (e.g. Portainer “Pull and redeploy” or your webhook).
Woodpecker CI/CD
Three pipelines (see .woodpecker/):
| Pipeline | When | What |
|---|---|---|
| ci | Every push to main, every PR |
Lint (ESLint + Stylelint) and Prettier check |
| build | Push/tag/manual on main only (after ci) |
Build Docker image, push to git.mifi.dev/mifi-holdings/armandine |
| deploy | After build | Trigger Portainer stack redeploy via webhook |
Order: ci → build → deploy.
Secrets (Woodpecker)
Configure in the repo’s Woodpecker secrets:
gitea_registry_username– Gitea user for registry logingitea_package_token– Gitea token with package read/writeportainer_webhook_url– Portainer stack webhook URL for redeploydiscord_webhook_url– (optional) Discord notifications for build/deploy status
Server / Portainer
- Stack is defined by
docker-compose.ymlin this repo. - Compose uses the image from the registry (
git.mifi.dev/mifi-holdings/armandine:latest); no volume for site content (it’s inside the image). - Ensure the server can pull from
git.mifi.dev(login or registry access). After a push, either let the deploy pipeline trigger the Portainer webhook or manually “Pull and redeploy” the stack.
Project layout
├── src/ # Static site (copied into image)
│ ├── index.html
│ └── assets/
│ ├── css/
│ ├── js/
│ └── media/
├── Dockerfile # nginx:alpine + COPY src → /usr/share/nginx/html
├── docker-compose.yml # Stack for Portainer (Traefik, healthcheck)
├── package.json # Scripts: build, push, lint, format, serve (pnpm)
├── .devcontainer/ # Dev container (Node 22, Docker, lint/format tools)
├── .woodpecker/
│ ├── ci.yaml # Lint + format check (PR + main)
│ ├── build.yaml # Build image, push to registry
│ └── deploy.yaml # Portainer webhook
└── README.md # This file
Version
package.json version: 1.0.0 (bump when you want to track releases).