admin docker production with nginx, update workflow

This commit is contained in:
einhornimmond 2025-04-29 09:13:20 +02:00
parent b805d1312d
commit 08a2f391fb
7 changed files with 135 additions and 63 deletions

View File

@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v3
- name: Admin Interface | Build 'test' image
run: docker build -f ./admin/Dockerfile --target test -t "gradido/admin:test" --build-arg NODE_ENV="test" .
run: docker build -f ./admin/Dockerfile --target production -t "gradido/admin:production" --build-arg NODE_ENV="production" --build-arg BUILD_COMMIT=$(git rev-parse HEAD) --build-arg BUILD_COMMIT_SHORT=$(git rev-parse --short HEAD) .
unit_test:
if: needs.files-changed.outputs.admin == 'true'
@ -41,44 +41,58 @@ jobs:
needs: files-changed
runs-on: ubuntu-latest
steps:
- name: Set Node.js version
uses: actions/setup-node@v4
with:
node-version: '18.20.7'
- name: Checkout code
uses: actions/checkout@v3
- name: Install turbo
run: yarn global add turbo@^2
- name: Prune admin with turbos help
run: turbo prune admin
- name: install dependencies
run: cd out && yarn install --frozen-lockfile --production=false
- name: Admin Interface | Unit tests
run: cd admin && yarn global add node-gyp && yarn && yarn run test
id: test
run: |
turbo admin#test admin#lint
echo "success=$([ $? -eq 0 ] && echo true || echo false)" >> $GITHUB_OUTPUT
lint:
if: needs.files-changed.outputs.admin == 'true'
name: Lint - Admin Interface
needs: files-changed
needs: [files-changed, unit_test]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Admin Interface | Lint
run: cd admin && yarn global add node-gyp && yarn && yarn run lint
- name: Check result from previous step
run: if [ "${{ needs.unit_test.outputs.test-success }}" != "true" ]; then exit 1; fi
stylelint:
if: needs.files-changed.outputs.admin == 'true'
name: Stylelint - Admin Interface
needs: files-changed
needs: [files-changed, unit_test]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Admin Interface | Stylelint
run: cd admin && yarn global add node-gyp && yarn && yarn run stylelint
- name: Check result from previous step
run: if [ "${{ needs.unit_test.outputs.test-success }}" != "true" ]; then exit 1; fi
locales:
if: needs.files-changed.outputs.admin == 'true'
name: Locales - Admin Interface
needs: files-changed
needs: [files-changed, unit_test]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Admin Interface | Locales
run: cd admin && yarn global add node-gyp && yarn && yarn run locales
- name: Check result from previous step
run: if [ "${{ needs.unit_test.outputs.test-success }}" != "true" ]; then exit 1; fi

View File

@ -1,7 +1,7 @@
##################################################################################
# BASE ###########################################################################
##################################################################################
FROM node:18.20-alpine3.20 as base
FROM node:18.20.7-alpine3.21 as base
# ENVs (available in production aswell, can be overwritten by commandline or env file)
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
@ -9,9 +9,12 @@ ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z"
## We cannot do $(npm run version).${BUILD_NUMBER} here so we default to 0.0.0.0
ENV BUILD_VERSION="0.0.0.0"
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT_SHORT="0000000"
ARG BUILD_VERSION
ENV BUILD_VERSION=${BUILD_VERSION}
ARG BUILD_COMMIT
ENV BUILD_COMMIT=${BUILD_COMMIT}
ARG BUILD_COMMIT_SHORT
ENV BUILD_COMMIT_SHORT=${BUILD_COMMIT_SHORT}
## SET NODE_ENV
ARG NODE_ENV="production"
## App relevant Envs
@ -42,67 +45,57 @@ EXPOSE ${PORT}
RUN mkdir -p ${DOCKER_WORKDIR}
WORKDIR ${DOCKER_WORKDIR}
RUN mkdir -p /config
##################################################################################
# DEVELOPMENT (Connected to the local environment, to reload on demand) ##########
# Base with turbo ################################################################
##################################################################################
FROM base as development
FROM base as turbo-base
# We don't need to copy or build anything since we gonna bind to the
# local filesystem which will need a rebuild anyway
# Run command
# (for development we need to execute yarn install since the
# node_modules are on another volume and need updating)
CMD /bin/sh -c "cd /config && yarn install && cd /app && yarn && yarn run dev"
RUN apk update && apk add --no-cache libc6-compat \
&& yarn global add turbo@^2 \
&& rm -rf /tmp/* ~/.cache node_modules/.cache \
&& yarn cache clean
##################################################################################
# BUILD (Does contain all files and is therefore bloated) ########################
# BUILDER (create partly monorepo only with data needed by dht-node) #############
##################################################################################
FROM base as build
FROM turbo-base as builder
# Copy everything
COPY ./admin/ .
# Copy everything from config
COPY ./config/ ../config/
COPY --chown=app:app . .
RUN turbo prune admin --docker
# yarn install and build config
RUN cd ../config && yarn install --production=false --frozen-lockfile --non-interactive && yarn build
# yarn install admin
RUN yarn install --production=false --frozen-lockfile --non-interactive
# yarn build
RUN yarn run build
##################################################################################
# INSTALLER (create production image) ##############################################
##################################################################################
FROM turbo-base AS installer
# First install the dependencies (as they change less often)
COPY --chown=app:app --from=builder /app/out/json/ .
RUN yarn install --frozen-lockfile --production=false \
&& rm -rf /tmp/* ~/.cache node_modules/.cache \
&& yarn cache clean
# Build the project
COPY --chown=app:app --from=builder /app/out/full/ .
RUN turbo build --env-mode=loose
RUN pwd && ls -lah && du -d1 -h
##################################################################################
# TEST ###########################################################################
##################################################################################
FROM build as test
# Install Additional Software
RUN apk add --no-cache bash jq
FROM installer as test
# Run command
CMD /bin/sh -c "yarn run dev"
CMD /bin/sh -c "turbo admin#test --env-mode=loose"
##################################################################################
# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) #
##################################################################################
FROM base as production
FROM nginx:alpine as production
# Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/build ./build
COPY --from=build ${DOCKER_WORKDIR}/../config/build ../config/build
# We also copy the node_modules express and serve-static for the run script
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
# Copy static files
COPY --from=build ${DOCKER_WORKDIR}/public ./public
# Copy package.json for script definitions (lock file should not be needed)
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json
# Copy run scripts run/
COPY --from=build ${DOCKER_WORKDIR}/run ./run
# copy builded frontend files
COPY --from=installer /app/admin/build/ /usr/share/nginx/html/
# copy nginx config
COPY nginx/serveAdmin.conf /etc/nginx/conf.d/default.conf
# Run command
CMD /bin/sh -c "yarn run start"

View File

@ -28,6 +28,7 @@ export default defineConfig(async ({ command }) => {
}
if (existsSync('../.git', constants.F_OK)) {
CONFIG.BUILD_COMMIT = execSync('git rev-parse HEAD').toString().trim()
CONFIG.BUILD_COMMIT_SHORT = (CONFIG.BUILD_COMMIT ?? '0000000').slice(0, 7)
}
validate(schema, CONFIG)
// make sure that all urls used in browser have the same protocol to prevent mixed content errors

View File

@ -44,11 +44,15 @@ services:
context: ./
dockerfile: ./admin/Dockerfile
target: production
args:
BUILD_COMMIT: ${BUILD_COMMIT}
BUILD_COMMIT_SHORT: ${BUILD_COMMIT_SHORT}
BUILD_VERSION: ${BUILD_VERSION}
networks:
- external-net
- internal-net
ports:
- 8080:8080
- 8080:80
environment:
# Envs used in Dockerfile
# - DOCKER_WORKDIR="/app"

30
nginx/serve.conf Normal file
View File

@ -0,0 +1,30 @@
server {
listen 80;
server_name localhost;
gzip_static on;
gzip on;
gzip_proxied any;
gzip_types
text/css
text/javascript
text/xml
text/plain
application/javascript
application/x-javascript
application/json;
root /usr/share/nginx/html;
index index.html;
location / {
#limit_req zone=frontend burst=40 nodelay;
#limit_conn addr 40;
root /usr/share/nginx/html/;
index index.html;
try_files $uri $uri/ /index.html = 404;
}
# Optional: CORS Header (vorsichtig, je nach Bedarf)
add_header Access-Control-Allow-Origin *;
}

29
nginx/serveAdmin.conf Normal file
View File

@ -0,0 +1,29 @@
server {
listen 80;
server_name localhost;
gzip_static on;
gzip on;
gzip_proxied any;
gzip_types
text/css
text/javascript
text/xml
text/plain
application/javascript
application/x-javascript
application/json;
location /admin {
#limit_req zone=frontend burst=30 nodelay;
#limit_conn addr 40;
rewrite ^/admin/(.*)$ /$1 break;
root /usr/share/nginx/html/;
index index.html;
try_files $uri $uri/ /index.html = 404;
}
# Optional: CORS Header (vorsichtig, je nach Bedarf)
add_header Access-Control-Allow-Origin *;
}

View File

@ -19,7 +19,8 @@
],
"scripts": {
"release": "scripts/release.sh",
"installAll": "yarn && cd database && yarn && cd ../frontend && yarn && cd ../admin && yarn && cd ../backend && yarn && cd ../federation && yarn && cd ../dht-node && yarn && cd ../e2e-tests && yarn && cd .."
"installAll": "yarn && cd database && yarn && cd ../frontend && yarn && cd ../admin && yarn && cd ../backend && yarn && cd ../federation && yarn && cd ../dht-node && yarn && cd ../e2e-tests && yarn && cd ..",
"docker:admin": "docker build --progress=plain -f ./admin/Dockerfile --target production -t \"gradido/admin:latest\" --build-arg NODE_ENV=\"production\" --build-arg BUILD_COMMIT=$(git rev-parse HEAD) --build-arg BUILD_COMMIT_SHORT=$(git rev-parse --short HEAD) ."
},
"dependencies": {
"auto-changelog": "^2.4.0",