Repository navigation
Expand file tree
/
Copy pathContainerfile.codebattle
More file actions
86 lines (63 loc) · 2.68 KB
/
Copy pathContainerfile.codebattle
File metadata and controls
86 lines (63 loc) · 2.68 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
# The frontend: its own package and Vite build.
FROM node:24.15-alpine AS frontend-image
# Mirrors the repo layout: the app imports translations from ../priv/gettext.
WORKDIR /tmp/codebattle/frontend
RUN npm install --global pnpm@11.18.0
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
COPY priv/gettext ../priv/gettext
COPY frontend ./
RUN pnpm run build
FROM elixir:1.20.4-otp-29-alpine AS compile-image
ENV MIX_ENV=prod
WORKDIR /opt/app
RUN apk update && apk add --no-cache build-base git ca-certificates make curl brotli gzip \
&& mix local.hex --force \
&& mix local.rebar --force
COPY mix.exs .
COPY mix.lock .
COPY config ./config
RUN mix do deps.get --only prod, deps.compile
COPY lib ./lib
COPY priv ./priv
COPY static ./static
# Static files (images, audio, fonts, favicons) at /assets/*; the PWA worker and its
# offline page at the root.
RUN mkdir -p priv/static/assets \
&& cp -R static/. priv/static/assets/ \
&& mv priv/static/assets/offline.html priv/static/assets/service-worker.js priv/static/
# Served at /assets/v2 by nginx and Phoenix (see CodebattleWeb.Frontend).
COPY --from=frontend-image /tmp/codebattle/frontend/dist ./priv/static/assets/v2
# phx.digest writes digested copies plus .gz for its gzippable extensions.
# Add .br for every compressible file (and .gz where digest skipped it) so
# nginx can serve precompressed variants via brotli_static/gzip_static.
RUN mix phx.digest \
&& find priv/static/assets -type f \( \
-name "*.js" -o -name "*.mjs" -o -name "*.css" -o -name "*.html" -o \
-name "*.json" -o -name "*.map" -o -name "*.svg" -o -name "*.txt" -o \
-name "*.xml" -o -name "*.csv" -o -name "*.ico" -o -name "*.ttf" -o \
-name "*.otf" -o -name "*.eot" \
\) -print0 \
| xargs -0 -r -P "$(nproc)" -n 16 sh -c \
'for f; do brotli -f -q 11 "$f"; [ -f "$f.gz" ] || gzip -k -9 "$f"; done' _ \
&& mix release codebattle \
&& mv _build/prod/rel/codebattle /opt/release
FROM alpine:3.23 AS nginx-assets
RUN apk add --no-cache nginx nginx-mod-http-brotli
COPY nginx.conf /etc/nginx/http.d/default.conf
COPY nginx-assets-entrypoint.sh /opt/nginx-assets-entrypoint.sh
COPY --from=compile-image /opt/release/lib/codebattle-0.1.0/priv/static/assets/ /var/www/assets
RUN nginx -t
RUN chmod +x /opt/nginx-assets-entrypoint.sh
CMD ["/opt/nginx-assets-entrypoint.sh"]
FROM elixir:1.20.4-otp-29-alpine AS runtime-image
RUN apk add --no-cache ca-certificates chromium git make curl vim
ARG GIT_HASH
ENV APP_VERSION=$GIT_HASH
ENV PORT=4000
ENV MIX_ENV=prod
EXPOSE ${PORT}
WORKDIR /opt/app
COPY --from=compile-image /opt/release .
COPY Makefile Makefile
CMD ["/opt/app/bin/codebattle", "start"]