Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ TICK_SECRET=
# Generate with: openssl rand -hex 32
# POSTGRES_PASSWORD=

# Only read by the compose files: each long-running container's memory and CPU
# ceiling. The defaults suit a small VPS; a larger machine raises them here, so
# the compose file itself is never edited and an upgrade's `git checkout` has
# nothing of yours to collide with — see docs/self-hosting.md § Start it.
# WEB_MEM_LIMIT=1g
# WEB_CPUS=2
# POSTGRES_MEM_LIMIT=1g
# POSTGRES_CPUS=1
# WORKER_MEM_LIMIT=768m
# WORKER_CPUS=1
# REDIS_MEM_LIMIT=256m
# REDIS_CPUS=0.5

# The board's absolute public origin, used for e-mail links, feeds and canonical
# URLs. Optional, like MAIL_DRIVER and for the same reason: the installer asks
# for it — prefilled from the address you load /install at — and stores it as
Expand Down
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ updates:
directory: /docker
schedule:
interval: weekly

- package-ecosystem: docker-compose
directory: /docker
schedule:
interval: weekly
30 changes: 15 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ jobs:
name: Static checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

# No `version:` — action-setup reads `packageManager` from package.json,
# so CI, the Docker image and a developer machine all run one pnpm. They
# ran three (9, 11.x-latest and 10.6) until the image job made that
# visible by failing.
- uses: pnpm/action-setup@v6
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6

- uses: actions/setup-node@v7
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand Down Expand Up @@ -148,13 +148,13 @@ jobs:
name: Production build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# No `version:` — action-setup reads `packageManager` from package.json,
# so CI, the Docker image and a developer machine all run one pnpm. They
# ran three (9, 11.x-latest and 10.6) until the image job made that
# visible by failing.
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand Down Expand Up @@ -200,7 +200,7 @@ jobs:
--health-cmd pg_isready --health-interval 10s
--health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Build the image
run: docker build -f docker/Dockerfile -t forum:ci .
Expand Down Expand Up @@ -309,7 +309,7 @@ jobs:
name: The site image serves meith.dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Build the site image
run: docker build -f docker/Dockerfile.site -t meith-site:ci .
Expand Down Expand Up @@ -353,7 +353,7 @@ jobs:
run:
working-directory: docker
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

# Both compose files parse before either is run, so a syntax error is one
# clear failure rather than a confusing one 500 seconds into a build. The
Expand Down Expand Up @@ -587,13 +587,13 @@ jobs:
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# No `version:` — action-setup reads `packageManager` from package.json,
# so CI, the Docker image and a developer machine all run one pnpm. They
# ran three (9, 11.x-latest and 10.6) until the image job made that
# visible by failing.
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand Down Expand Up @@ -624,13 +624,13 @@ jobs:
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# No `version:` — action-setup reads `packageManager` from package.json,
# so CI, the Docker image and a developer machine all run one pnpm. They
# ran three (9, 11.x-latest and 10.6) until the image job made that
# visible by failing.
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/cut-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ jobs:
# to the built-in Actions app, and a deploy-key push triggers the
# Release workflow where a GITHUB_TOKEN push would be swallowed by
# GitHub's recursion guard.
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: main
ssh-key: ${{ secrets.RELEASE_DEPLOY_KEY }}

- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
name: The tag and the tree agree
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- run: node scripts/release-check.mjs --tag "$GITHUB_REF_NAME"

# One job per architecture, on that architecture's own runner — no QEMU, so
Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
--health-cmd pg_isready --health-interval 10s
--health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Build the image, stamped
run: |
Expand Down Expand Up @@ -124,7 +124,7 @@ jobs:
if: always()
run: docker rm -f meith-web meith-worker 2>/dev/null || true

- uses: docker/login-action@v4
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down Expand Up @@ -153,9 +153,9 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 26
cache: pnpm
Expand All @@ -174,11 +174,11 @@ jobs:
# release branch needs that branch's current commit present locally, or
# the git client refuses with "fetch first" before the server can even
# check the fast-forward.
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0

- uses: docker/login-action@v4
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# ---------------------------------------------------------------------------
# deps: install with the lockfile, cached independently of source changes.
# ---------------------------------------------------------------------------
FROM node:26-alpine AS deps
FROM node:26-alpine@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 AS deps
WORKDIR /repo

# Node no longer bundles Corepack — install it before enabling it.
Expand Down Expand Up @@ -73,7 +73,7 @@ RUN pnpm --filter @meith/cli build
# ---------------------------------------------------------------------------
# runtime: standalone output only.
# ---------------------------------------------------------------------------
FROM node:26-alpine AS runtime
FROM node:26-alpine@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 AS runtime
WORKDIR /app

# Stamped by the release workflow (see docs/release.md); a local build leaves
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.site
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# meith.dev itself — the landing page and the documentation (`@meith/site`).
# Nothing in the self-hosting path uses this; Dockerfile builds the board.

FROM node:26-alpine AS deps
FROM node:26-alpine@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 AS deps
WORKDIR /repo

# Node no longer bundles Corepack — install it before enabling it.
Expand All @@ -25,7 +25,7 @@ ENV SITE_STANDALONE=1

RUN pnpm --filter @meith/site build

FROM node:26-alpine AS runtime
FROM node:26-alpine@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 AS runtime
WORKDIR /app

ENV NODE_ENV=production
Expand Down
23 changes: 22 additions & 1 deletion docker/compose.coolify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@

services:
postgres:
image: postgres:16-alpine
image: postgres:16-alpine@sha256:cf78e76683b9ca8c5733cbbdce6c9262b45b6767934dd0a95e671f9a0fc20685
restart: unless-stopped
mem_limit: ${POSTGRES_MEM_LIMIT:-1g}
cpus: ${POSTGRES_CPUS:-1}
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
POSTGRES_USER: community
# Generated by Coolify, once, and reused by every service below.
Expand Down Expand Up @@ -91,6 +98,13 @@ services:
web:
image: ${MEITH_IMAGE:-ghcr.io/meith-dev/meith:0.12.0}
restart: unless-stopped
mem_limit: ${WEB_MEM_LIMIT:-1g}
cpus: ${WEB_CPUS:-2}
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
# Ask Coolify for a domain on port 3000, then hand the board the same
# thing with a scheme in front. Without APP_URL, every link in an e-mail
Expand Down Expand Up @@ -137,6 +151,13 @@ services:
worker:
image: ${MEITH_IMAGE:-ghcr.io/meith-dev/meith:0.12.0}
restart: unless-stopped
mem_limit: ${WORKER_MEM_LIMIT:-768m}
cpus: ${WORKER_CPUS:-1}
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
- COMMUNITY_ROLE=worker
- DATABASE_URL=postgres://community:$SERVICE_PASSWORD_POSTGRES@postgres:5432/community
Expand Down
25 changes: 23 additions & 2 deletions docker/compose.demo.coolify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@

services:
postgres:
image: postgres:16-alpine
image: postgres:16-alpine@sha256:cf78e76683b9ca8c5733cbbdce6c9262b45b6767934dd0a95e671f9a0fc20685
restart: unless-stopped
mem_limit: 1g
cpus: 1
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
POSTGRES_USER: community
POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES
Expand Down Expand Up @@ -71,6 +78,13 @@ services:
context: .
dockerfile: docker/Dockerfile
restart: unless-stopped
mem_limit: 1g
cpus: 2
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
- SERVICE_FQDN_WEB_3000
- APP_URL=$SERVICE_URL_WEB
Expand Down Expand Up @@ -107,8 +121,15 @@ services:
# A board normally runs `compose.coolify.yml`'s worker for this. A demo
# cannot: see the note at the top of this file.
ticker:
image: curlimages/curl:8.11.1
image: curlimages/curl:8.11.1@sha256:c1fe1679c34d9784c1b0d1e5f62ac0a79fca01fb6377cdd33e90473c6f9f9a69
restart: unless-stopped
mem_limit: 64m
cpus: 0.25
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
environment:
- TICK_SECRET=$SERVICE_BASE64_64_TICK
# `--max-time 300` because one tick an hour is the reset, and that one drops
Expand Down
2 changes: 1 addition & 1 deletion docker/compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

services:
postgres:
image: postgres:16-alpine
image: postgres:16-alpine@sha256:cf78e76683b9ca8c5733cbbdce6c9262b45b6767934dd0a95e671f9a0fc20685
# A fixed name so `docker exec forum-pg psql …` works without looking it up,
# and so the container is recognisable among a machine's other databases.
container_name: forum-pg
Expand Down
Loading