-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
97 lines (85 loc) · 4.75 KB
/
Copy pathDockerfile
File metadata and controls
97 lines (85 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# syntax=docker/dockerfile:1.7-labs
# check=skip=InvalidDefaultArgInFrom
# meith-board's quick-start deploy image — built from source, with nothing to
# set up first.
#
# FROM node:26-alpine directly rather than a published Meith base image:
# Coolify (or a plain `docker build`) builds this from this repository, so
# there is no registry account, no image tag to paste anywhere, and no
# `.github/workflows/build.yml` run to wait on. The cost of that zero setup
# is that this installs the board's full dependency closure itself (see the
# `npm install` below), so a build here is heavier than `Dockerfile.prebuilt`'s
# thin delta — that image, pulled rather than built, is the trade the advanced
# path takes for a low-spec build server or a faster deploy (see `README.md`
# and, in the meith repository, docs/getting-started/deployment/docker-compose.md,
# "Custom boards").
#
# Two stages, not three: unlike the official image, this does not prune down
# to Next's own standalone output. The migrate role below runs `meith
# migrate`, and `meith` materializes @meith/cli's sources and runs them
# with tsx at the moment it runs (see the meith repository's
# docs/contributing/development.md, "Consuming the board from a workspace") — it needs
# the full, un-pruned node_modules tree this board installed, not what Next
# traced as reachable from the web server alone. The tick itself is driven
# by docker-compose.yaml's own `worker` service — a lightweight loop against
# /api/system/tick, not a compiled worker process, because @meith/worker is
# not published (see the meith repository's docs/contributing/release.md).
FROM node:26-alpine@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019 AS deps
WORKDIR /board
# This board's own manifest, cached independently of its source — editing
# meith.config.ts should not re-run npm install. Nothing warms node_modules
# ahead of this the way `Dockerfile.prebuilt`'s base image does: the full
# @meith/web, @meith/cli and @meith/theme-default closure this board depends
# on is installed here, from scratch, which is the heavier half of the
# quick-start trade.
COPY package.json ./
RUN npm install
FROM deps AS runtime
WORKDIR /board
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
# DATA_SOURCE is scoped to this one RUN, not declared with ENV — an ENV
# persists into every container started from this image afterward, and this
# Dockerfile has no later stage to reset it in (see "Two stages, not three"
# above). The build needs neither a database nor a production secret (see
# the meith repository's docs/contributing/development.md, "Fixture mode"), but baking
# DATA_SOURCE=fixture into the image itself would silently force fixture
# mode — and with it the in-memory queue driver — at runtime too, no matter
# what DATABASE_URL an operator supplies to `docker run`.
RUN DATA_SOURCE=fixture npx forum-web build
ENV PORT=3000
ENV HOSTNAME=0.0.0.0
EXPOSE 3000
# Uploaded files — avatars, board images, attachments — land here, and the
# compose file mounts the persistent "uploads" volume over this path. Creating
# it in the image, owned by node, is what lets the fresh volume inherit that
# ownership; UPLOADS_DIR gives the board an absolute path so the working
# directory never decides where uploads go. Without both, uploads land on the
# container's own layer and a redeploy discards them.
ENV UPLOADS_DIR=/app/.uploads
RUN mkdir -p /app/.uploads && chown node:node /app/.uploads
# The ring of backup bundles the admin panel's Backups screen writes, lists
# and prunes, and the postgres client tools `meith backup` and the panel's
# backups dump with. The compose file mounts the persistent "backups" volume
# over this path.
RUN apk add --no-cache postgresql18-client
ENV BACKUP_DIR=/backups
RUN mkdir -p /backups && chown node:node /backups
# `meith <command>` on PATH runs this board's own operator CLI — the same one
# node_modules/.bin/meith is — so a Coolify terminal or `docker compose exec web
# meith ...` needs no path. It cd's to /board so the CLI finds this board's
# config, and overrides any wrapper an inherited base image installed, which
# would target the board that image was built from, not this one.
RUN printf '#!/bin/sh\ncd /board\nexec node_modules/.bin/meith "$@"\n' > /usr/local/bin/meith \
&& chmod +x /usr/local/bin/meith
# node:alpine already carries a non-root "node" user; the board's own files
# are copied in as root above, so they need handing over before this drops
# privilege.
RUN chown -R node:node /board
USER node
COPY --chown=node:node docker-entrypoint.sh docker-healthcheck.sh ./
RUN chmod +x docker-entrypoint.sh docker-healthcheck.sh
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD ["./docker-healthcheck.sh"]
ENTRYPOINT ["./docker-entrypoint.sh"]