-
-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathDockerfile
More file actions
409 lines (379 loc) · 16.7 KB
/
Copy pathDockerfile
File metadata and controls
409 lines (379 loc) · 16.7 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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# syntax=docker/dockerfile:1
ARG NODE_VERSION=22
ARG BUILDPLATFORM
# Shared deps (alpine) for website/docs/webapp builds
FROM node:${NODE_VERSION}-alpine AS deps-alpine
WORKDIR /repo
# Some workspace deps (e.g. node-pty) may not have prebuilt binaries for all architectures
# and will fall back to node-gyp. Install the minimal toolchain + Python for reliable builds.
RUN apk add --no-cache libc6-compat python3 build-base
ENV REDISMS_DISABLE_POSTINSTALL=1
ENV YARN_CACHE_FOLDER=/tmp/.yarn-cache
COPY package.json yarn.lock ./
RUN mkdir -p apps/ui apps/server apps/cli apps/website apps/docs packages/agents packages/cli-common packages/connection-supervisor packages/protocol packages/release-runtime packages/transfers packages/audio-stream-native packages/sherpa-native scripts/pipeline/expo
COPY apps/ui/package.json apps/ui/
COPY apps/server/package.json apps/server/
COPY apps/cli/package.json apps/cli/
COPY apps/website/package.json apps/website/
COPY apps/docs/package.json apps/docs/
COPY packages/agents/package.json packages/agents/
COPY packages/cli-common/package.json packages/cli-common/
COPY packages/connection-supervisor/package.json packages/connection-supervisor/
COPY packages/protocol/package.json packages/protocol/
COPY packages/release-runtime/package.json packages/release-runtime/
COPY packages/transfers/package.json packages/transfers/
COPY packages/audio-stream-native/package.json packages/audio-stream-native/
COPY packages/sherpa-native/package.json packages/sherpa-native/
COPY scripts/pipeline/expo/eas-postinstall.mjs scripts/pipeline/expo/
COPY scripts/ci/yarn-install-with-retry.sh /usr/local/bin/yarn-install-with-retry
RUN chmod +x /usr/local/bin/yarn-install-with-retry
RUN --mount=type=cache,target=/tmp/.yarn-cache,sharing=locked \
yarn config set registry https://registry.npmjs.org/ \
&& yarn-install-with-retry --frozen-lockfile --ignore-engines --network-timeout 600000 --prefer-offline --non-interactive
COPY scripts/workspaces ./scripts/workspaces
# Shared deps (alpine) for web UI export embeds.
# We build the web export on the BUILDPLATFORM because the output is architecture-agnostic, and
# running Node/Yarn under QEMU for linux/arm64 has proven unstable (SIGILL).
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION}-alpine AS deps-alpine-build
WORKDIR /repo
RUN apk add --no-cache libc6-compat python3 build-base
ENV REDISMS_DISABLE_POSTINSTALL=1
ENV YARN_CACHE_FOLDER=/tmp/.yarn-cache
COPY package.json yarn.lock ./
RUN mkdir -p apps/ui apps/server apps/cli apps/website apps/docs packages/agents packages/cli-common packages/connection-supervisor packages/protocol packages/release-runtime packages/transfers packages/audio-stream-native packages/sherpa-native scripts/pipeline/expo
COPY apps/ui/package.json apps/ui/
COPY apps/server/package.json apps/server/
COPY apps/cli/package.json apps/cli/
COPY apps/website/package.json apps/website/
COPY apps/docs/package.json apps/docs/
COPY packages/agents/package.json packages/agents/
COPY packages/cli-common/package.json packages/cli-common/
COPY packages/connection-supervisor/package.json packages/connection-supervisor/
COPY packages/protocol/package.json packages/protocol/
COPY packages/release-runtime/package.json packages/release-runtime/
COPY packages/transfers/package.json packages/transfers/
COPY packages/audio-stream-native/package.json packages/audio-stream-native/
COPY packages/sherpa-native/package.json packages/sherpa-native/
COPY scripts/pipeline/expo/eas-postinstall.mjs scripts/pipeline/expo/
COPY scripts/ci/yarn-install-with-retry.sh /usr/local/bin/yarn-install-with-retry
RUN chmod +x /usr/local/bin/yarn-install-with-retry
RUN --mount=type=cache,target=/tmp/.yarn-cache,sharing=locked \
yarn config set registry https://registry.npmjs.org/ \
&& yarn-install-with-retry --frozen-lockfile --ignore-engines --network-timeout 600000 --prefer-offline --non-interactive
COPY scripts/workspaces ./scripts/workspaces
# Shared deps (debian) for server builds (needs toolchain for native deps)
FROM node:${NODE_VERSION} AS deps-debian
RUN apt-get update && apt-get install -y python3 ffmpeg make g++ build-essential && rm -rf /var/lib/apt/lists/*
WORKDIR /repo
ENV REDISMS_DISABLE_POSTINSTALL=1
ENV YARN_CACHE_FOLDER=/tmp/.yarn-cache
COPY package.json yarn.lock ./
RUN mkdir -p apps/ui apps/server apps/cli apps/website apps/docs packages/agents packages/cli-common packages/connection-supervisor packages/protocol packages/release-runtime packages/transfers packages/audio-stream-native packages/sherpa-native scripts/pipeline/expo
COPY apps/ui/package.json apps/ui/
COPY apps/server/package.json apps/server/
COPY apps/cli/package.json apps/cli/
COPY apps/website/package.json apps/website/
COPY apps/docs/package.json apps/docs/
COPY packages/agents/package.json packages/agents/
COPY packages/cli-common/package.json packages/cli-common/
COPY packages/connection-supervisor/package.json packages/connection-supervisor/
COPY packages/protocol/package.json packages/protocol/
COPY packages/release-runtime/package.json packages/release-runtime/
COPY packages/transfers/package.json packages/transfers/
COPY packages/audio-stream-native/package.json packages/audio-stream-native/
COPY packages/sherpa-native/package.json packages/sherpa-native/
COPY scripts/pipeline/expo/eas-postinstall.mjs scripts/pipeline/expo/
COPY scripts/ci/yarn-install-with-retry.sh /usr/local/bin/yarn-install-with-retry
RUN chmod +x /usr/local/bin/yarn-install-with-retry
RUN --mount=type=cache,target=/tmp/.yarn-cache,sharing=locked \
yarn config set registry https://registry.npmjs.org/ \
&& yarn-install-with-retry --frozen-lockfile --ignore-engines --network-timeout 600000 --prefer-offline --non-interactive
COPY scripts/workspaces ./scripts/workspaces
#
# Targets
#
# Website (Vite static)
FROM deps-alpine AS website-builder
ARG WEBSITE_VARIANT=prerelease
COPY apps/website ./apps/website
RUN test -f "apps/website/index.${WEBSITE_VARIANT}.html" && cp "apps/website/index.${WEBSITE_VARIANT}.html" "apps/website/index.html"
RUN yarn workspace @happier-dev/website build
FROM nginxinc/nginx-unprivileged:alpine AS website
USER root
RUN apk add --no-cache curl
COPY --from=website-builder /repo/apps/website/dist /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
RUN echo 'server { \
listen 8080; \
server_name _; \
root /usr/share/nginx/html; \
\
location = /health { \
return 200 "ok\n"; \
} \
\
location /assets/ { \
try_files $uri =404; \
} \
\
location /.well-known/ { \
try_files $uri =404; \
} \
\
location / { \
try_files $uri $uri/ /index.html; \
} \
}' > /etc/nginx/conf.d/default.conf
USER 101
EXPOSE 8080
# Webapp (Expo export static)
FROM deps-alpine-build AS webapp-builder
ARG HAPPIER_EMBEDDED_POLICY_ENV=preview
ARG POSTHOG_API_KEY=""
ARG POSTHOG_HOST=""
ARG SENTRY_DSN=""
ARG SENTRY_RELEASE=""
ARG REVENUE_CAT_STRIPE=""
ARG EXPO_PUBLIC_HAPPIER_SERVER_URL=""
ARG EXPO_PUBLIC_HAPPY_SERVER_URL=""
ARG EXPO_PUBLIC_SERVER_URL=""
ENV NODE_ENV=production
ENV APP_ENV=production
ENV EXPO_PUBLIC_HAPPIER_SERVER_URL=$EXPO_PUBLIC_HAPPIER_SERVER_URL
ENV EXPO_PUBLIC_HAPPY_SERVER_URL=$EXPO_PUBLIC_HAPPY_SERVER_URL
ENV EXPO_PUBLIC_SERVER_URL=$EXPO_PUBLIC_SERVER_URL
ENV EXPO_PUBLIC_POSTHOG_KEY=$POSTHOG_API_KEY
ENV EXPO_PUBLIC_POSTHOG_HOST=$POSTHOG_HOST
ENV EXPO_PUBLIC_SENTRY_DSN=$SENTRY_DSN
ENV EXPO_PUBLIC_SENTRY_RELEASE=$SENTRY_RELEASE
ENV EXPO_UNSTABLE_WEB_MODAL=1
ENV EXPO_PUBLIC_REVENUE_CAT_STRIPE=$REVENUE_CAT_STRIPE
ENV HAPPIER_EMBEDDED_POLICY_ENV=$HAPPIER_EMBEDDED_POLICY_ENV
COPY .github/feature-policy ./.github/feature-policy
COPY apps/ui ./apps/ui
COPY packages/agents ./packages/agents
COPY packages/connection-supervisor ./packages/connection-supervisor
COPY packages/protocol ./packages/protocol
COPY packages/release-runtime ./packages/release-runtime
COPY packages/transfers ./packages/transfers
COPY scripts/pipeline/release/precompress-ui-web-assets.mjs ./scripts/pipeline/release/precompress-ui-web-assets.mjs
COPY scripts/pipeline/release/lib/precompress-ui-web-assets.mjs ./scripts/pipeline/release/lib/precompress-ui-web-assets.mjs
RUN yarn workspace @happier-dev/protocol postinstall:real \
&& yarn workspace @happier-dev/release-runtime postinstall:real \
&& yarn workspace @happier-dev/agents postinstall:real \
&& yarn workspace @happier-dev/connection-supervisor postinstall:real \
&& yarn workspace @happier-dev/transfers postinstall:real
RUN yarn workspace @happier-dev/app postinstall:real
RUN rm -rf apps/ui/dist
RUN yarn workspace @happier-dev/app expo export --platform web --output-dir dist --max-workers 1
RUN node scripts/pipeline/release/precompress-ui-web-assets.mjs --dir apps/ui/dist --gzip-only
FROM nginxinc/nginx-unprivileged:alpine AS webapp
USER root
RUN apk add --no-cache curl
COPY --from=webapp-builder /repo/apps/ui/dist /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
RUN echo 'server { \
listen 8080; \
gzip_static on; \
gzip_vary on; \
\
location = /health { \
return 200 "ok\n"; \
} \
\
location /_expo/ { \
root /usr/share/nginx/html; \
add_header Cache-Control "public, max-age=31536000, immutable"; \
try_files $uri =404; \
} \
\
location /assets/ { \
root /usr/share/nginx/html; \
add_header Cache-Control "public, max-age=31536000, immutable"; \
try_files $uri =404; \
} \
\
location /.well-known/ { \
root /usr/share/nginx/html; \
try_files $uri =404; \
} \
\
location / { \
root /usr/share/nginx/html; \
index index.html index.htm; \
add_header Cache-Control "no-store"; \
try_files $uri $uri.html $uri/index.html $uri/index.htm $uri/ /index.html /index.htm =404; \
} \
\
error_page 500 502 503 504 /50x.html; \
location = /50x.html { \
root /usr/share/nginx/html; \
try_files $uri @redirect_to_index; \
internal; \
} \
\
error_page 404 = @handle_404; \
\
location @handle_404 { \
root /usr/share/nginx/html; \
try_files /404.html @redirect_to_index; \
internal; \
} \
\
location @redirect_to_index { \
return 302 /; \
} \
}' > /etc/nginx/conf.d/default.conf
USER 101
EXPOSE 8080
# Docs (Next.js)
FROM deps-alpine AS docs-builder
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
COPY apps/docs ./apps/docs
COPY apps/ui/sources/assets/fonts ./apps/ui/sources/assets/fonts
RUN yarn workspace docs postinstall:real && yarn workspace docs build
FROM node:${NODE_VERSION}-alpine AS docs
WORKDIR /repo
RUN apk add --no-cache libc6-compat curl
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
COPY --from=docs-builder /repo/node_modules /repo/node_modules
COPY --from=docs-builder /repo/apps/docs /repo/apps/docs
EXPOSE 3000
CMD ["yarn", "--cwd", "apps/docs", "start"]
# Server
FROM deps-debian AS server-builder
ARG HAPPIER_EMBEDDED_POLICY_ENV=preview
ARG HAPPIER_BUILD_DB_PROVIDERS=""
ENV HAPPIER_BUILD_DB_PROVIDERS=$HAPPIER_BUILD_DB_PROVIDERS
ENV HAPPIER_EMBEDDED_POLICY_ENV=$HAPPIER_EMBEDDED_POLICY_ENV
COPY .github/feature-policy ./.github/feature-policy
COPY apps/server ./apps/server
COPY packages/agents ./packages/agents
COPY packages/cli-common ./packages/cli-common
COPY packages/protocol ./packages/protocol
COPY packages/release-runtime ./packages/release-runtime
RUN yarn workspace @happier-dev/protocol postinstall:real && yarn workspace @happier-dev/agents postinstall:real
RUN yarn workspace @happier-dev/release-runtime postinstall:real
RUN yarn workspace @happier-dev/server postinstall:real
RUN yarn workspace @happier-dev/server build
FROM node:${NODE_VERSION} AS server
WORKDIR /repo
ARG SENTRY_RELEASE=""
RUN apt-get update \
&& apt-get install -y --no-install-recommends -o APT::Keep-Downloaded-Packages=false python3 ffmpeg curl \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_ENV=production
ENV PORT=3005
ENV RUN_MIGRATIONS=1
ENV SENTRY_RELEASE=$SENTRY_RELEASE
ENV HAPPIER_RELEASE_SOURCE_SHA=$SENTRY_RELEASE
COPY --from=server-builder --chown=node:node /repo/node_modules /repo/node_modules
COPY --from=server-builder --chown=node:node /repo/packages/agents /repo/packages/agents
COPY --from=server-builder --chown=node:node /repo/packages/cli-common /repo/packages/cli-common
COPY --from=server-builder --chown=node:node /repo/packages/protocol /repo/packages/protocol
COPY --from=server-builder --chown=node:node /repo/packages/release-runtime /repo/packages/release-runtime
COPY --from=server-builder --chown=node:node /repo/apps/server /repo/apps/server
COPY --from=server-builder /repo/apps/server/scripts/run-server.sh /usr/local/bin/run-server
RUN chmod +x /usr/local/bin/run-server
RUN mkdir -p /data && chown -R node:node /data
USER node
EXPOSE 3005
CMD ["run-server"]
# Convenience: worker image variant (same bits, different defaults)
FROM server AS server-worker
ENV SERVER_ROLE=worker
# Local relay server image for source-backed release candidate upgrade QA.
FROM server AS relay-server-local-source
USER root
RUN mkdir -p /opt/happier/ui-web \
&& chown -R node:node /opt/happier
COPY --from=webapp-builder --chown=node:node /repo/apps/ui/dist /opt/happier/ui-web
ENV HAPPIER_SERVER_FLAVOR=light
ENV HAPPY_SERVER_FLAVOR=light
ENV HAPPIER_DB_PROVIDER=sqlite
ENV HAPPY_DB_PROVIDER=sqlite
ENV HAPPIER_SERVER_LIGHT_DATA_DIR=/data
ENV HAPPY_SERVER_LIGHT_DATA_DIR=/data
ENV HAPPIER_SERVER_UI_DIR=/opt/happier/ui-web
ENV HAPPIER_SERVER_UI_PREFIX=/
ENV HAPPIER_SERVER_UI_REQUIRED=1
ENV HAPPIER_SQLITE_AUTO_MIGRATE=1
USER node
# Relay server (self-host default: light + sqlite)
FROM debian:12-slim AS relay-artifacts
ARG TARGETARCH
ARG HAPPIER_RELEASE_BASE_URL="https://github.com/happier-dev/happier/releases/download"
ARG HAPPIER_RELAY_SERVER_RELEASE_TAG=""
ARG HAPPIER_RELAY_SERVER_VERSION=""
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl tar minisign \
&& rm -rf /var/lib/apt/lists/*
COPY scripts/pipeline/docker/fetch-verified-release-artifact.sh /usr/local/bin/fetch-verified-release-artifact
COPY scripts/release/installers/happier-release.pub /tmp/happier-release.pub
RUN chmod +x /usr/local/bin/fetch-verified-release-artifact
RUN set -eux; \
case "$TARGETARCH" in \
amd64) artifact_arch="x64" ;; \
arm64) artifact_arch="arm64" ;; \
*) echo "Unsupported TARGETARCH: $TARGETARCH" >&2; exit 1 ;; \
esac; \
fetch-verified-release-artifact \
--base-url "$HAPPIER_RELEASE_BASE_URL" \
--release-tag "$HAPPIER_RELAY_SERVER_RELEASE_TAG" \
--product happier-server \
--version "$HAPPIER_RELAY_SERVER_VERSION" \
--os linux \
--arch "$artifact_arch" \
--dest /opt/happier/server \
--pubkey /tmp/happier-release.pub; \
rm -rf /opt/happier/server/generated/mysql-client; \
case "$TARGETARCH" in \
amd64) \
find /opt/happier/server/generated/sqlite-client -name '*.node' \
! -name "libquery_engine-debian-openssl-3.0.x.so.node" -delete; \
rm -rf /opt/happier/server/node_modules/@img/sharp-libvips-linuxmusl-x64 \
/opt/happier/server/node_modules/@img/sharp-linuxmusl-x64 ;; \
arm64) \
find /opt/happier/server/generated/sqlite-client -name '*.node' \
! -name "libquery_engine-linux-arm64-openssl-3.0.x.so.node" -delete; \
rm -rf /opt/happier/server/node_modules/@img/sharp-libvips-linuxmusl-arm64 \
/opt/happier/server/node_modules/@img/sharp-linuxmusl-arm64 ;; \
esac
FROM debian:12-slim AS relay-server
WORKDIR /opt/happier/server
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl sqlite3 \
&& rm -rf /var/lib/apt/lists/*
RUN useradd -m -s /bin/bash happier \
&& mkdir -p /data /opt/happier/server \
&& chown -R happier:happier /data /opt/happier
COPY --from=relay-artifacts --chown=happier:happier /opt/happier/server /opt/happier/server
ARG SENTRY_RELEASE=""
ENV SENTRY_RELEASE=$SENTRY_RELEASE
ENV HAPPIER_RELEASE_SOURCE_SHA=$SENTRY_RELEASE
ARG SENTRY_SERVER_CENTRAL_DSN=""
ENV HAPPIER_SENTRY_CENTRAL_DSN=$SENTRY_SERVER_CENTRAL_DSN
ENV HAPPIER_SENTRY_USE_CENTRAL_DSN=1
ENV NODE_ENV=production
ENV PORT=3005
ENV HAPPIER_SERVER_FLAVOR=light
ENV HAPPY_SERVER_FLAVOR=light
ENV HAPPIER_DB_PROVIDER=sqlite
ENV HAPPY_DB_PROVIDER=sqlite
ENV HAPPIER_SERVER_LIGHT_DATA_DIR=/data
ENV HAPPY_SERVER_LIGHT_DATA_DIR=/data
ENV HAPPIER_SERVER_UI_DIR=/opt/happier/server/ui-web/current
ENV HAPPIER_SERVER_UI_PREFIX=/
ENV HAPPIER_SERVER_UI_REQUIRED=1
ENV HAPPIER_SQLITE_AUTO_MIGRATE=1
ENV HAPPIER_SQLITE_MIGRATIONS_DIR=/opt/happier/server/prisma/sqlite/migrations
ENV HAPPY_SQLITE_MIGRATIONS_DIR=/opt/happier/server/prisma/sqlite/migrations
USER happier
EXPOSE 3005
VOLUME ["/data"]
CMD ["/opt/happier/server/happier-server"]
# Default target when building without --target
FROM server AS default