feat(docker): Multi stage docker now fetch deps once
Split dockerfile into three different dockerfiles such that dependencies are only downloaded once This allows the build to be a bit faster, since all deps are downloaded once at the start. This also makes it so the frontend container no longer needs to be ran, as its files are directly embedded into the nginx container This also remove the extra files, since bind mounts do work it also remove the entrypoint.sh file, as you should prefer to not use it
This commit is contained in:
parent
af13395f2f
commit
2ed524872b
17 changed files with 93 additions and 128 deletions
|
|
@ -6,7 +6,6 @@ DOCKER_SERVICE= \
|
||||||
auth \
|
auth \
|
||||||
chat \
|
chat \
|
||||||
tic-tac-toe \
|
tic-tac-toe \
|
||||||
frontend \
|
|
||||||
nginx \
|
nginx \
|
||||||
user \
|
user \
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,41 @@ networks:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
##########
|
||||||
|
# DEPS #
|
||||||
|
##########
|
||||||
|
|
||||||
|
pnpm_base:
|
||||||
|
build:
|
||||||
|
context: ./src
|
||||||
|
dockerfile: '@dockerfiles/pnpm.Dockerfile'
|
||||||
|
restart: on-failure:3
|
||||||
|
|
||||||
|
pnpm_deps:
|
||||||
|
build:
|
||||||
|
context: ./src
|
||||||
|
dockerfile: '@dockerfiles/deps.Dockerfile'
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
|
restart: on-failure:3
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
build: ./frontend
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
container_name: app-frontend
|
container_name: app-frontend
|
||||||
restart: on-failure:3
|
restart: on-failure:3
|
||||||
networks:
|
|
||||||
- app
|
############
|
||||||
volumes:
|
# SERVICES #
|
||||||
- static-volume:/volumes/static
|
############
|
||||||
logging:
|
|
||||||
driver: gelf
|
|
||||||
options:
|
|
||||||
gelf-address: "udp://127.0.0.1:12201"
|
|
||||||
tag: "{{.Name}}"
|
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
build: ./nginx
|
build:
|
||||||
|
context: ./nginx
|
||||||
|
additional_contexts:
|
||||||
|
frontend: "service:frontend"
|
||||||
container_name: app-nginx
|
container_name: app-nginx
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
|
@ -41,15 +60,14 @@ services:
|
||||||
gelf-address: "udp://127.0.0.1:12201"
|
gelf-address: "udp://127.0.0.1:12201"
|
||||||
tag: "{{.Name}}"
|
tag: "{{.Name}}"
|
||||||
|
|
||||||
###############
|
|
||||||
# SERVICE #
|
|
||||||
###############
|
|
||||||
|
|
||||||
auth:
|
auth:
|
||||||
build:
|
build:
|
||||||
context: ./src/
|
context: ./src/
|
||||||
args:
|
args:
|
||||||
- SERVICE=auth
|
- SERVICE=auth
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
|
pnpm_deps: "service:pnpm_deps"
|
||||||
container_name: app-auth
|
container_name: app-auth
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
|
@ -74,6 +92,9 @@ services:
|
||||||
context: ./src/
|
context: ./src/
|
||||||
args:
|
args:
|
||||||
- SERVICE=tic-tac-toe
|
- SERVICE=tic-tac-toe
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
|
pnpm_deps: "service:pnpm_deps"
|
||||||
container_name: app-tic-tac-toe
|
container_name: app-tic-tac-toe
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
|
@ -97,6 +118,9 @@ services:
|
||||||
context: ./src/
|
context: ./src/
|
||||||
args:
|
args:
|
||||||
- SERVICE=chat
|
- SERVICE=chat
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
|
pnpm_deps: "service:pnpm_deps"
|
||||||
container_name: app-chat
|
container_name: app-chat
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
|
@ -119,6 +143,9 @@ services:
|
||||||
context: ./src/
|
context: ./src/
|
||||||
args:
|
args:
|
||||||
- SERVICE=user
|
- SERVICE=user
|
||||||
|
additional_contexts:
|
||||||
|
pnpm_base: "service:pnpm_base"
|
||||||
|
pnpm_deps: "service:pnpm_deps"
|
||||||
container_name: app-user
|
container_name: app-user
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
FROM node:22-alpine AS pnpm_base
|
|
||||||
RUN npm install --global pnpm@10;
|
|
||||||
|
|
||||||
FROM pnpm_base AS deps
|
FROM pnpm_base AS deps
|
||||||
|
|
||||||
COPY ./package.json ./pnpm-lock.yaml ./pnpm-workspace.yaml /src/
|
COPY ./package.json ./pnpm-lock.yaml ./pnpm-workspace.yaml /src/
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
RUN pnpm install --frozen-lockfile;
|
RUN pnpm install -q --frozen-lockfile;
|
||||||
|
|
||||||
FROM pnpm_base AS builder
|
FROM pnpm_base AS builder
|
||||||
|
|
||||||
|
|
@ -14,12 +11,3 @@ COPY --from=deps /src/node_modules /src/node_modules
|
||||||
COPY . /src
|
COPY . /src
|
||||||
|
|
||||||
RUN pnpm run build;
|
RUN pnpm run build;
|
||||||
|
|
||||||
FROM pnpm_base
|
|
||||||
|
|
||||||
COPY --from=builder /src/dist /dist
|
|
||||||
COPY ./run.sh /bin/run.sh
|
|
||||||
|
|
||||||
RUN chmod +x /bin/run.sh
|
|
||||||
|
|
||||||
CMD [ "/bin/run.sh" ]
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -x
|
|
||||||
set -e
|
|
||||||
|
|
||||||
rm -rf /volumes/static/app
|
|
||||||
mkdir -p /volumes/static/app
|
|
||||||
|
|
||||||
cp -r /dist/* /volumes/static/app/
|
|
||||||
|
|
@ -1,17 +1,9 @@
|
||||||
# **************************************************************************** #
|
FROM frontend AS frontend-files
|
||||||
# #
|
|
||||||
# ::: :::::::: #
|
|
||||||
# Dockerfile :+: :+: :+: #
|
|
||||||
# +:+ +:+ +:+ #
|
|
||||||
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
|
||||||
# +#+#+#+#+#+ +#+ #
|
|
||||||
# Created: 2025/06/12 16:42:38 by maiboyer #+# #+# #
|
|
||||||
# Updated: 2025/07/29 13:58:39 by maiboyer ### ########.fr #
|
|
||||||
# #
|
|
||||||
# **************************************************************************** #
|
|
||||||
|
|
||||||
FROM nginx:stable-alpine
|
FROM nginx:stable-alpine
|
||||||
|
|
||||||
|
ENV NGINX_DOMAIN "local.maix.me"
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
mkdir -p /volumes/ && \
|
mkdir -p /volumes/ && \
|
||||||
mkdir -p /etc/nginx/ && \
|
mkdir -p /etc/nginx/ && \
|
||||||
|
|
@ -21,15 +13,17 @@ RUN \
|
||||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||||
-keyout /etc/ssl/private/nginx-selfsigned.key \
|
-keyout /etc/ssl/private/nginx-selfsigned.key \
|
||||||
-out /etc/ssl/certs/nginx-selfsigned.crt \
|
-out /etc/ssl/certs/nginx-selfsigned.crt \
|
||||||
-subj "/C=FR/OU=student/CN=${NGINX_DOMAIN}"
|
-subj "/C=FR/OU=student/CN=${NGINX_DOMAIN}";
|
||||||
|
|
||||||
COPY ./15-local-resolvers.envsh /docker-entrypoint.d/
|
COPY ./15-local-resolvers.envsh /docker-entrypoint.d/
|
||||||
COPY ./17-add-template-prefix.sh /docker-entrypoint.d/
|
COPY ./17-add-template-prefix.sh /docker-entrypoint.d/
|
||||||
|
COPY ./conf /etc/nginx/templates
|
||||||
|
|
||||||
COPY ./conf /etc/nginx/templates
|
COPY ./monitoring.index.html /var/share/www/monitoring/
|
||||||
COPY ./monitoring.index.html /var/share/www/monitoring/
|
COPY --from=frontend-files /src/dist /var/share/www/static/
|
||||||
|
|
||||||
RUN chmod -R +r /var/share/www/monitoring/;
|
RUN chmod -R +r /var/share/www/monitoring/;
|
||||||
|
RUN chmod -R +r /var/share/www/static/;
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s \
|
HEALTHCHECK --interval=30s --timeout=3s \
|
||||||
CMD curl -f -s http://localhost:8080/ok?docker || exit 1;
|
CMD curl -f -s http://localhost:8080/ok?docker || exit 1;
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
location /app {
|
location /app {
|
||||||
root /volumes/static/app/;
|
root /var/share/www/static/;
|
||||||
try_files /index.html =404;
|
try_files /index.html =404;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /assets {
|
location /assets {
|
||||||
root /volumes/static/app/;
|
root /var/share/www/static/;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
|
|
||||||
14
src/@dockerfiles/deps.Dockerfile
Normal file
14
src/@dockerfiles/deps.Dockerfile
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM pnpm_base AS deps
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml /build/
|
||||||
|
|
||||||
|
|
||||||
|
# You need to list all services here...
|
||||||
|
COPY @shared/package.json /build/@shared/package.json
|
||||||
|
COPY auth/package.json /build/auth/package.json
|
||||||
|
COPY chat/package.json /build/chat/package.json
|
||||||
|
COPY tic-tac-toe/package.json /build/tic-tac-toe/package.json
|
||||||
|
COPY user/package.json /build/user/package.json
|
||||||
|
|
||||||
|
RUN pnpm install -q --frozen-lockfile;
|
||||||
3
src/@dockerfiles/pnpm.Dockerfile
Normal file
3
src/@dockerfiles/pnpm.Dockerfile
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
FROM node:22-alpine AS pnpm_base
|
||||||
|
RUN npm install --global pnpm@10 --no-fund -q;
|
||||||
|
RUN apk add make python3 gcc clang build-base musl-dev curl;
|
||||||
|
|
@ -1,33 +1,25 @@
|
||||||
FROM node:22-alpine AS pnpm_base
|
# lets include the pnpm_deps as an named image (raw_deps)
|
||||||
RUN npm install --global pnpm@10 --no-fund -q;
|
FROM pnpm_deps AS raw_deps
|
||||||
RUN apk add make python3 gcc clang build-base musl-dev;
|
|
||||||
RUN apk add --no-cache curl
|
|
||||||
|
|
||||||
FROM pnpm_base AS deps
|
# lets make a `raw_builder` as an image -> this only include the deps and the metadata files
|
||||||
WORKDIR /build
|
FROM pnpm_base AS raw_builder
|
||||||
ARG SERVICE
|
|
||||||
|
|
||||||
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml /build/
|
|
||||||
COPY @shared/package.json /build/@shared/
|
|
||||||
COPY ${SERVICE}/package.json /build/${SERVICE}/
|
|
||||||
|
|
||||||
RUN pnpm install --frozen-lockfile;
|
|
||||||
|
|
||||||
FROM pnpm_base AS builder
|
|
||||||
|
|
||||||
ARG SERVICE
|
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY --from=raw_deps /build/node_modules /build/node_modules
|
||||||
|
ARG SERVICE
|
||||||
COPY package.json /build/
|
COPY package.json /build/
|
||||||
COPY @shared/package.json /build/@shared/
|
COPY @shared/package.json /build/@shared/
|
||||||
COPY ${SERVICE}/ /build/${SERVICE}
|
COPY ${SERVICE}/package.json /build/${SERVICE}/
|
||||||
COPY tsconfig.base.json pnpm-workspace.yaml pnpm-lock.yaml /build/
|
COPY tsconfig.base.json pnpm-workspace.yaml pnpm-lock.yaml /build/
|
||||||
COPY ${SERVICE}/entrypoint.sh /build/
|
|
||||||
|
|
||||||
COPY --from=deps /build/node_modules /build/node_modules
|
|
||||||
|
|
||||||
COPY @shared/ /build/@shared/
|
# lets actually build our stuff
|
||||||
COPY ${SERVICE}/ /build/${SERVICE}/
|
FROM raw_builder AS builder
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY @shared/ /build/@shared/
|
||||||
|
COPY ${SERVICE}/ /build/${SERVICE}/
|
||||||
|
|
||||||
RUN cd /build/${SERVICE} && \
|
RUN cd /build/${SERVICE} && \
|
||||||
pnpm run build:prod && \
|
pnpm run build:prod && \
|
||||||
|
|
@ -35,24 +27,16 @@ RUN cd /build/${SERVICE} && \
|
||||||
cp /build/pnpm-workspace.yaml /dist/pnpm-workspace.yaml && \
|
cp /build/pnpm-workspace.yaml /dist/pnpm-workspace.yaml && \
|
||||||
cp /build/pnpm-lock.yaml /dist/pnpm-lock.yaml && \
|
cp /build/pnpm-lock.yaml /dist/pnpm-lock.yaml && \
|
||||||
cp /build/@shared/package.json /dist/@shared/ && \
|
cp /build/@shared/package.json /dist/@shared/ && \
|
||||||
cp /build/${SERVICE}/package.json /dist/${SERVICE}/ && \
|
cp /build/${SERVICE}/package.json /dist/${SERVICE}/;
|
||||||
cp /build/entrypoint.sh /dist/ && \
|
|
||||||
chmod +x /dist/entrypoint.sh;
|
|
||||||
|
|
||||||
|
|
||||||
|
# this is our actual running container :D
|
||||||
FROM pnpm_base
|
FROM pnpm_base
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
ARG EXTRA_FILES=empty
|
COPY --from=builder /dist /src
|
||||||
COPY --from=builder /dist /src
|
COPY --from=raw_builder /build/node_modules /src/node_modules
|
||||||
COPY --from=deps /build/node_modules /src/node_modules
|
|
||||||
|
|
||||||
COPY ${EXTRA_FILES} /extra
|
|
||||||
ENTRYPOINT [ "/src/entrypoint.sh" ]
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s \
|
|
||||||
CMD curl -f -s http://localhost/monitoring?docker || exit 1
|
|
||||||
|
|
||||||
CMD ["node", "/src/run.cjs"]
|
CMD ["node", "/src/run.cjs"]
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s \
|
||||||
|
CMD curl -f -s http://localhost/monitoring?docker || exit 1
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
# do anything here
|
|
||||||
|
|
||||||
# run the CMD [ ... ] from the dockerfile
|
|
||||||
exec "$@"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
# do anything here
|
|
||||||
|
|
||||||
# run the CMD [ ... ] from the dockerfile
|
|
||||||
exec "$@"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
|
|
||||||
"spaces": 2,
|
|
||||||
"generator-cli": {
|
|
||||||
"version": "7.17.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
# do anything here
|
|
||||||
|
|
||||||
# run the CMD [ ... ] from the dockerfile
|
|
||||||
exec "$@"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
# do anything here
|
|
||||||
|
|
||||||
# run the CMD [ ... ] from the dockerfile
|
|
||||||
exec "$@"
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue