-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathDockerfile.server
More file actions
188 lines (158 loc) · 9.5 KB
/
Copy pathDockerfile.server
File metadata and controls
188 lines (158 loc) · 9.5 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# Hyperia — full-stack Docker image (game server + web client)
#
# Build from repo root:
# docker build --platform linux/amd64 -f Dockerfile.server -t ghcr.io/alternatefutures/hyperia:v12 .
#
# Issues this Dockerfile works around:
# 1. better-sqlite3 — node-gyp fails under QEMU (stripped before install)
# 2. Bun workspace links — Docker COPY flattens symlinks; recreated manually
# 3. Bun per-package node_modules — not hoisted to root; copied explicitly
# 4. procgen tsc — type errors cause partial emit; build continues with || true
# ─── Builder ────────────────────────────────────────────────────────────────
FROM node:22-bookworm-slim AS node-build-tools
FROM oven/bun:1.1.38-debian AS builder
RUN apt-get update && apt-get install -y \
python3 make g++ pkg-config \
libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev \
ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV CI=true \
SKIP_ASSETS=true \
HYPERIA_SKIP_BROWSER_INSTALL=true
# Vite 8 requires Node 20.19+ or 22.12+. Bun 1.1.38 reports Node 22.6.0 when
# running Vite-backed scripts, so copy in a current real Node binary for those
# build steps while keeping Bun pinned for installs and the rest of the build.
COPY --from=node-build-tools /usr/local/bin/node /usr/local/bin/node
# Root manifests.
COPY package.json bun.lock turbo.json tsconfig.json ./
# Workspace package manifests (determines dependency graph).
COPY packages/physx-js-webidl/package.json ./packages/physx-js-webidl/
COPY packages/decimation/package.json ./packages/decimation/
COPY packages/impostors/package.json ./packages/impostors/
COPY packages/procgen/package.json ./packages/procgen/
COPY packages/shared/package.json ./packages/shared/
COPY packages/plugin-hyperia/package.json ./packages/plugin-hyperia/
COPY packages/web3/package.json ./packages/web3/
COPY packages/server/package.json ./packages/server/
COPY packages/client/package.json ./packages/client/
# Install hook scripts + PhysX WASM prebuilts.
COPY scripts ./scripts
COPY packages/client/public/web/physx-js-webidl.js ./packages/client/public/web/
COPY packages/client/public/web/physx-js-webidl.wasm ./packages/client/public/web/
# Workspace sources.
COPY packages/physx-js-webidl ./packages/physx-js-webidl
COPY packages/decimation ./packages/decimation
COPY packages/impostors ./packages/impostors
COPY packages/procgen ./packages/procgen
COPY packages/shared ./packages/shared
COPY packages/plugin-hyperia ./packages/plugin-hyperia
COPY packages/web3 ./packages/web3
COPY packages/server ./packages/server
COPY packages/client ./packages/client
# better-sqlite3's node-gyp build segfaults under QEMU cross-compilation.
# The project uses bun:sqlite / PostgreSQL, so it's safe to remove.
RUN bun -e " \
const fs = require('fs'); \
for (const f of ['packages/shared/package.json', 'package.json']) { \
const p = JSON.parse(fs.readFileSync(f)); \
delete p.dependencies?.['better-sqlite3']; \
delete p.devDependencies?.['better-sqlite3']; \
fs.writeFileSync(f, JSON.stringify(p, null, 2)); \
}"
# Match CI's stable install mode. `--trust` can hang in container builds,
# while the frozen install path already passes in CI.
RUN bun install --frozen-lockfile
# Bun may hoist workspace deps without materializing per-package node_modules.
# Create every runtime COPY source explicitly so missing dirs don't break builds.
RUN mkdir -p \
packages/server/node_modules \
packages/shared/node_modules \
packages/procgen/node_modules \
packages/impostors/node_modules \
packages/plugin-hyperia/node_modules \
packages/web3/node_modules \
packages/client/node_modules
# Download game asset manifests (bypass CDN reliance on boot).
RUN rm -rf packages/server/world/assets && bun scripts/ensure-assets.mjs
# Build workspace packages in dependency order.
RUN cd /app/packages/physx-js-webidl && bun run build && \
cd /app/packages/decimation && bun run build && \
cd /app/packages/impostors && node ../../node_modules/typescript/bin/tsc --project tsconfig.build.json && \
node ../../node_modules/vite/bin/vite.js build --config vite.lib.config.ts && \
cd /app/packages/procgen && (bun run build || true) && \
cd /app/packages/shared && bun run build && \
cd /app/packages/plugin-hyperia && bun run build && \
cd /app/packages/web3 && bun run build && \
cd /app/packages/server && bun run build && \
cd /app/packages/client && NODE_OPTIONS='--max-old-space-size=4096' \
node ../../node_modules/vite/bin/vite.js build
# ─── Runtime ────────────────────────────────────────────────────────────────
#
# The production server must run under real Node.js, not Bun. The bundled
# server loads uWebSockets.js native bindings, which depend on Node's N-API
# and fail under Bun's `node` compatibility shim.
FROM node:22-trixie-slim AS runtime
RUN apt-get update && apt-get install -y \
libcairo2 libpango-1.0-0 libpangocairo-1.0-0 \
libjpeg62-turbo libgif7 librsvg2-2 \
ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV NODE_ENV=production \
CI=true \
SKIP_ASSETS=true \
HYPERIA_SKIP_BROWSER_INSTALL=true
# Package manifests from builder (has better-sqlite3 stripped).
COPY --from=builder /app/package.json /app/bun.lock ./
COPY --from=builder /app/packages/physx-js-webidl/package.json ./packages/physx-js-webidl/
COPY --from=builder /app/packages/decimation/package.json ./packages/decimation/
COPY --from=builder /app/packages/impostors/package.json ./packages/impostors/
COPY --from=builder /app/packages/procgen/package.json ./packages/procgen/
COPY --from=builder /app/packages/shared/package.json ./packages/shared/
COPY --from=builder /app/packages/plugin-hyperia/package.json ./packages/plugin-hyperia/
COPY --from=builder /app/packages/web3/package.json ./packages/web3/
COPY --from=builder /app/packages/server/package.json ./packages/server/
COPY --from=builder /app/packages/client/package.json ./packages/client/
# ── node_modules ──
# Bun 1.3 uses per-package node_modules (not flat hoisting). Docker COPY
# also destroys workspace symlinks. We need three things:
# 1. Root node_modules (with .bun cache containing all resolved packages)
# 2. Manual workspace symlinks (@hyperforge/* -> packages/*)
# 3. Per-package node_modules for every workspace member used at runtime
COPY --from=builder /app/node_modules ./node_modules
RUN mkdir -p node_modules/@hyperia && \
ln -s ../../packages/physx-js-webidl node_modules/@hyperforge/physx-js-webidl && \
ln -s ../../packages/decimation node_modules/@hyperforge/decimation && \
ln -s ../../packages/impostors node_modules/@hyperforge/impostor && \
ln -s ../../packages/procgen node_modules/@hyperforge/procgen && \
ln -s ../../packages/shared node_modules/@hyperforge/shared && \
ln -s ../../packages/plugin-hyperia node_modules/@hyperforge/plugin-hyperia && \
ln -s ../../packages/web3 node_modules/@hyperforge/web3 && \
ln -s ../../packages/server node_modules/@hyperforge/server && \
ln -s ../../packages/client node_modules/@hyperforge/client
COPY --from=builder /app/packages/server/node_modules ./packages/server/node_modules
COPY --from=builder /app/packages/shared/node_modules ./packages/shared/node_modules
COPY --from=builder /app/packages/procgen/node_modules ./packages/procgen/node_modules
COPY --from=builder /app/packages/impostors/node_modules ./packages/impostors/node_modules
COPY --from=builder /app/packages/plugin-hyperia/node_modules ./packages/plugin-hyperia/node_modules
COPY --from=builder /app/packages/web3/node_modules ./packages/web3/node_modules
COPY --from=builder /app/packages/client/node_modules ./packages/client/node_modules
# ── Build artifacts ──
COPY --from=builder /app/packages/physx-js-webidl/dist ./packages/physx-js-webidl/dist
COPY --from=builder /app/packages/decimation/dist ./packages/decimation/dist
COPY --from=builder /app/packages/impostors/dist ./packages/impostors/dist
COPY --from=builder /app/packages/procgen/dist ./packages/procgen/dist
COPY --from=builder /app/packages/shared/build ./packages/shared/build
COPY --from=builder /app/packages/plugin-hyperia/dist ./packages/plugin-hyperia/dist
COPY --from=builder /app/packages/web3/dist ./packages/web3/dist
COPY --from=builder /app/packages/server/dist ./packages/server/dist
COPY --from=builder /app/packages/server/scripts ./packages/server/scripts
COPY --from=builder /app/packages/server/src ./packages/server/src
COPY --from=builder /app/packages/server/world ./packages/server/world
COPY --from=builder /app/packages/client/dist ./packages/client/dist
RUN mkdir -p ./packages/server/public/live
EXPOSE 5555
HEALTHCHECK --interval=30s --timeout=5s --start-period=45s --retries=5 \
CMD curl -fsS http://localhost:${PORT:-5555}/status >/dev/null || exit 1
CMD ["node", "--import", "/app/packages/server/scripts/register-hooks.mjs", "/app/packages/server/dist/index.js"]