# 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` (see `Dockerfile`). - **Registry:** Gitea at `git.mifi.dev` → image `git.mifi.dev/mifi-holdings/armandine`. - **Deploy:** Portainer on Linode; stack uses this image (no volume for site content). ## Local development ```bash # 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 install` run after create - **Docker (outside of Docker)** – uses the host Docker socket so you can run `pnpm build` and 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): 1. Log in to the Gitea container registry: ```bash docker login git.mifi.dev ``` Use your Gitea username and a token with package permissions. 2. Build the image (tags as `latest`): ```bash pnpm build ``` This runs: `docker build -t git.mifi.dev/mifi-holdings/armandine:latest .` 3. Push to the registry: ```bash pnpm push ``` Then 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 login - `gitea_package_token` – Gitea token with package read/write - `portainer_webhook_url` – Portainer stack webhook URL for redeploy - `discord_webhook_url` – (optional) Discord notifications for build/deploy status ## Server / Portainer - Stack is defined by `docker-compose.yml` in 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).