Update readme, fix docker-compose typo, add pipelines
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/build unknown status
ci/woodpecker/push/deploy unknown status

This commit is contained in:
2026-02-13 15:33:02 -03:00
parent 26c31fded6
commit 2452b3dec4
5 changed files with 393 additions and 26 deletions

View File

@@ -1,6 +1,6 @@
# mifi.holdings — Landing Page
Static landing site for **mifi.holdings** (and www). Plain HTML/CSS, no framework; served by **nginx** in Docker behind **Traefik**, with CI/CD via **Woodpecker** and deployment via **Portainer**.
Static landing site for **mifi.holdings** (and www). Plain HTML/CSS/JS source; a **build step** produces minified assets and inlines critical CSS. Served by **nginx** in Docker behind **Traefik**, with CI/CD via **Woodpecker** and deployment via **Portainer**.
---
@@ -14,6 +14,7 @@ Static landing site for **mifi.holdings** (and www). Plain HTML/CSS, no framewor
| **CI/CD** | Woodpecker (ci → build → deploy) |
| **Registry** | `git.mifi.dev/mifi-holdings/landing` |
| **Package manager** | pnpm |
| **Build output** | `dist/` (gitignored) |
---
@@ -28,11 +29,11 @@ Static landing site for **mifi.holdings** (and www). Plain HTML/CSS, no framewor
│ Docker container │ mifi-holdings-landing
│ nginx:alpine │ port 80
│ /usr/share/ │
│ nginx/html ← │ static files from image
│ nginx/html ← │ built output from dist/
└─────────────────┘
```
- **Build**: Docker image = `nginx:alpine` + project `nginx/conf.d/` + `src/` copied into `/usr/share/nginx/html`.
- **Build**: `pnpm build` copies `src/``dist/`, minifies JS/CSS, inlines critical CSS (Critters). Docker image = `nginx:alpine` + `nginx/conf.d/` + **`dist/`** into `/usr/share/nginx/html`.
- **Run**: Single service on external network `marina-net`; Traefik routes `mifi.holdings` and `www.mifi.holdings` to this container (HTTPS, `security-prison@file` middleware).
---
@@ -41,52 +42,70 @@ Static landing site for **mifi.holdings** (and www). Plain HTML/CSS, no framewor
```
.
├── src/ # Static site (served as-is)
├── src/ # Source (HTML, CSS, JS)
│ ├── index.html
│ └── css/
── style.css
│ └── assets/
── css/style.css
│ ├── js/ga-init.js
│ └── images/ # favicon, etc.
├── scripts/
│ └── build.js # Build: copy, minify, inline critical CSS
├── dist/ # Build output (gitignored)
├── nginx/
│ └── conf.d/
│ └── default.conf # nginx server config (cache rules, SPA fallback)
├── .woodpecker/
│ ├── ci.yml # Lint + format check (PR + push to main)
│ ├── build.yml # Build image, push to registry (main)
│ ├── ci.yml # Lint, format, build check (PR + push to main)
│ ├── build.yml # Site build → Docker image push (main)
│ └── deploy.yml # Trigger Portainer redeploy (main)
├── docker-compose.yml # Service + Traefik labels for production
├── Dockerfile # nginx + config + src
├── package.json # pnpm scripts: format, lint, docker build/push
├── Dockerfile # nginx + config + dist (not src)
├── package.json # pnpm scripts: build, format, lint, docker
└── README.md
```
---
## Build (pnpm build)
- **Output**: `dist/` (gitignored). Do not edit `dist/`; it is generated.
- **Steps** (see `scripts/build.js`):
1. Clean and copy `src/``dist/`.
2. Minify all `.js` (terser) and `.css` (clean-css).
3. Inline critical CSS with **Critters** (lazy-loads the rest; no browser required, so it works in CI).
- **When**: Run before `docker build`. CI and the build pipeline both run `pnpm build` before packaging.
---
## Tech stack
- **Frontend**: Static HTML + CSS only (no JS build step).
- **Frontend**: Static HTML + CSS + JS in `src/`; production build minifies and inlines critical CSS.
- **Server**: nginx (Alpine) in Docker.
- **Tooling**: **pnpm** (format with Prettier, lint with yamllint for `.woodpecker/*.yml` and `docker-compose.yml`).
- **Deployment**: Docker image → Gitea registry → Portainer stack redeploy.
- **Tooling**: **pnpm**; Prettier (format); ESLint (JS), Stylelint (CSS), yamllint (YAML); **terser**, **clean-css**, **critters** (build).
- **Deployment**: Docker image (from `dist/`) → Gitea registry → Portainer stack redeploy.
---
## Local development
- **Dependencies**: `pnpm install` (only devDependencies: Prettier, yaml-lint).
- **Dependencies**: `pnpm install`.
- **Format**: `pnpm format` / `pnpm format:check`.
- **Lint**: `pnpm lint` (yamllint on Woodpecker and docker-compose YAML).
- **Lint**: `pnpm lint` (ESLint for `src/**/*.js`, Stylelint for `src/**/*.css`, yamllint for Woodpecker + docker-compose). Use `pnpm lint:fix` to auto-fix where supported.
- **Build**: `pnpm build` → produces `dist/`. Required before building the Docker image.
- **Run locally (Docker)**:
- Build: `pnpm docker:build` (or `docker build --platform linux/amd64 -t git.mifi.dev/mifi-holdings/landing:latest .`).
- Build site: `pnpm build`.
- Image: `pnpm docker:build` (or `docker build --platform linux/amd64 -t git.mifi.dev/mifi-holdings/landing:latest .`).
- Run: use `docker-compose up` **only** on a host that has `marina-net` and Traefik; otherwise run the image with a port map and open `http://localhost:<port>`.
There is no dev server in this repo; edit `src/` and refresh the browser or rebuild the image to test.
No dev server; edit `src/` and run `pnpm build` (and optionally `docker run` or a local static server on `dist/`) to test.
---
## Docker
- **Dockerfile**: Copies `nginx/conf.d/` and `src/` into an `nginx:alpine` image. No multi-stage build; the image is the final runtime.
- **Dockerfile**: Copies `nginx/conf.d/` and **`dist/`** (not `src/`) into an `nginx:alpine` image. Run `pnpm build` first so `dist/` exists.
- **Image**: Tagged as `git.mifi.dev/mifi-holdings/landing:latest` (and `:<commit-sha>` in CI).
- **Local build/push**: `pnpm docker:build`, `pnpm docker:push` (requires login to `git.mifi.dev`).
- **Local build/push**: `pnpm build``pnpm docker:build` `pnpm docker:push` (requires login to `git.mifi.dev`).
---
@@ -96,11 +115,11 @@ Three pipelines:
1. **ci** (`.woodpecker/ci.yml`)
- **When**: Every PR and every push to `main`.
- **Steps**: Install deps → Prettier format check → yamllint (Woodpecker + docker-compose). Mattermost notifications on success/failure.
- **Steps**: Install deps → Prettier format check → lint (ESLint, Stylelint, yamllint) → **Build** (`pnpm build`). Mattermost notifications on success/failure.
2. **build** (`.woodpecker/build.yml`)
- **When**: Push/tag/manual on `main` (and deployment to production); **depends_on: ci**.
- **Steps**: Build Docker image (linux/amd64, up to 3 retries) → push `:latest` and `:<CI_COMMIT_SHA>` to `git.mifi.dev/mifi-holdings/landing`. Mattermost notifications.
- **Steps**: **Site build** (`pnpm install`, `pnpm build`) → Docker image build (linux/amd64, up to 3 retries) → push `:latest` and `:<CI_COMMIT_SHA>` to `git.mifi.dev/mifi-holdings/landing`. Mattermost notifications.
3. **deploy** (`.woodpecker/deploy.yml`)
- **When**: Same as build (main / production deploy); **depends_on: ci**.
@@ -128,7 +147,7 @@ To deploy manually: pull the latest image and redeploy the stack in Portainer, o
## nginx behavior
- **Root**: `/usr/share/nginx/html` (contents of `src/`).
- **Root**: `/usr/share/nginx/html` (contents of **`dist/`** after build).
- **HTML**: `Cache-Control: public, no-cache` so updates are visible quickly.
- **JS/CSS**: Long cache, `immutable` for hashed/versioned assets.
- **Images/fonts**: Cached (30d / 1y).
@@ -138,6 +157,6 @@ To deploy manually: pull the latest image and redeploy the stack in Portainer, o
## Summary
- **What it is**: Static landing for mifi.holdings.
- **How it runs**: nginx in Docker, fronted by Traefik on `marina-net`.
- **How its updated**: Push to `main` → Woodpecker runs ci, build (image + push), deploy (Portainer webhook); Mattermost reports status.
- **What it is**: Static landing for mifi.holdings; source in `src/`, built output in `dist/`.
- **How it runs**: nginx in Docker serving `dist/`, fronted by Traefik on `marina-net`.
- **How its updated**: Push to `main` → Woodpecker runs ci (lint, format, **build**), then build pipeline (**site build** → Docker image push), then deploy (Portainer webhook); Mattermost reports status.