Ускорение деплоя NestJS и Angular с помощью общественных Github-раннеров и создания промежуточных Docker-образов
В этом посте я настрою сборку Docker-образов:
- Билдер NestJS и Angular приложений;
- Мигратор баз данных с помощью Flyway;
- Тест-раннер для запуска фронтенд и бэкенд E2E-тестов;
- Nginx c встроенной статикой Angular приложения;
- NestJS приложение.
1. Создаем Docker-образ со всеми зависимостями
В данном посте код и Docker-образа будут собираться на публичных раннерах, которые имеют лимит в месяц по общему времени выполнения и при интенсивной разработке этот лимит можно легко исчерпать, так что нужно быть готовыми переехать на собственный раннер.
В предыдущем посте зависимости устанавливались на хост машину в которой и происходила сборка кода, это было сделано в качестве примера того как можно, но так делать не нужно.
На хост машину нужно ставить минимальное количество программ и библиотек, так как любой сторонний софт может нести в себе вредоносное ПО, поэтому сборку кода нужно производить внутри специализированного Docker-контейнера.
Так как зависимости мы устанавливаем редко, то можно создать специальный Docker-образ который будет использоваться при сборке кода.
Папка с исходными файлами для сборки и папка для собранных файлов монтируется как volume
в контейнер при запуске.
Пересборка данного Docker-образа будет происходить при смене версии корневого package.json
.
Создаем файл .docker/builder.Dockerfile
FROM node:20.16.0-alpine AS builder
WORKDIR /usr/src/app
# Copy all files in repository to image
COPY --chown=node:node . .
# Install utils
RUN apk add dumb-init
# Clean up
RUN rm -rf /var/cache/apk/*
# Install deps
RUN npm install --prefer-offline --no-audit --progress=false
# Some utilities require a ".env" file
RUN echo '' > .env
FROM node:20.16.0-alpine
WORKDIR /usr/src/app
# Disable nx daemon
ENV NX_DAEMON=false
# Disable the statics server built into NestJS
ENV DISABLE_SERVE_STATIC=true
# Copy node_modules
COPY --from=builder /usr/src/app/node_modules /usr/src/app/node_modules
# Copy utility for "To work as a PID 1"
COPY --from=builder /usr/bin/dumb-init /usr/bin/dumb-init
# Copy the settings
COPY --from=builder /usr/src/app/.docker/.dockerignore /usr/src/app/.dockerignore
COPY --from=builder /usr/src/app/.docker/nx.json /usr/src/app/nx.json
COPY --from=builder /usr/src/app/package.json /usr/src/app/package.json
COPY --from=builder /usr/src/app/rucken.json /usr/src/app/rucken.json
COPY --from=builder /usr/src/app/tsconfig.base.json /usr/src/app/tsconfig.base.json
COPY --from=builder /usr/src/app/.env /usr/src/app/.env
# Copy the settings for linting
COPY --from=builder /usr/src/app/.nxignore /usr/src/app/.nxignore
COPY --from=builder /usr/src/app/.eslintrc.json /usr/src/app/.eslintrc.json
COPY --from=builder /usr/src/app/.eslintignore /usr/src/app/.eslintignore
COPY --from=builder /usr/src/app/.prettierignore /usr/src/app/.prettierignore
COPY --from=builder /usr/src/app/.prettierrc /usr/src/app/.prettierrc
COPY --from=builder /usr/src/app/jest.config.ts /usr/src/app/jest.config.ts
COPY --from=builder /usr/src/app/jest.preset.js /usr/src/app/jest.preset.js
# Install java
RUN apk add openjdk11-jre
# Clean up
RUN rm -rf /var/cache/apk/*
# We build the source code as the "node" user
# and set permissions for new files: full access from outside the container
CMD npm run build:prod
Для сборки кода, необходимо запустить контейнер с данным образом и смонтировать директории apps
, libs
и dist
.
Пример запуска:
docker run -v ./dist:/usr/src/app/dist -v ./apps:/usr/src/app/apps -v ./libs:/usr/src/app/libs ghcr.io/nestjs-mod/nestjs-mod-fullstack-builder:latest
2. Создаем базовый Docker-образ для запуска NestJS-приложения
Данный образ будет включать зависимости используемые при работе NestJS-приложения, это необходимо для уменьшения итогового образа и для ускорения процесса деплоя.
Пересборка данного Docker-образа будет происходить при смене версии корневого package.json
.
Создаем файл .docker/base-server.Dockerfile
FROM node:20.16.0-alpine AS builder
WORKDIR /usr/src/app
# Copy all files in repository to image
COPY --chown=node:node . .
# Install utils
RUN apk add jq dumb-init
# Clean up
RUN rm -rf /var/cache/apk/*
# Remove dev dependencies info
RUN echo $(cat package.json | jq 'del(.devDependencies)') > package.json
# Install deps
RUN npm install --prefer-offline --no-audit --progress=false
# Installing utilities to generate additional files
RUN npm install --prefer-offline --no-audit --progress=false --save-dev nx@19.5.3
RUN npm install --prefer-offline --no-audit --progress=false --save-dev prisma@5.18.0
RUN npm install --prefer-offline --no-audit --progress=false --save-dev prisma-class-generator@0.2.11
# Some utilities require a ".env" file
RUN echo '' > .env
FROM node:20.16.0-alpine
WORKDIR /usr/src/app
# Copy node_modules
COPY --from=builder /usr/src/app/node_modules /usr/src/app/node_modules
# Copy utility for "To work as a PID 1"
COPY --from=builder /usr/bin/dumb-init /usr/bin/dumb-init
# Copy the settings
COPY --from=builder /usr/src/app/.docker/.dockerignore /usr/src/app/.dockerignore
COPY --from=builder /usr/src/app/.docker/nx.json /usr/src/app/nx.json
COPY --from=builder /usr/src/app/package.json /usr/src/app/package.json
COPY --from=builder /usr/src/app/rucken.json /usr/src/app/rucken.json
COPY --from=builder /usr/src/app/tsconfig.base.json /usr/src/app/tsconfig.base.json
COPY --from=builder /usr/src/app/.env /usr/src/app/.env
3. Создаем Docker-образ для запуска NestJS-приложения
Так как установку зависимостей мы производим при создании "базового Docker-образа для запуска NestJS-приложения", а сборку кода производим через запуск "Docker-образа со всеми зависимостями", то теперь необходимо это все соединить вместе.
Пересборка данного Docker-образа будет происходить при смене версии apps/server/package.json
.
Создаем файл .docker/server.Dockerfile
ARG BASE_SERVER_IMAGE_TAG=latest
ARG REGISTRY=ghcr.io
ARG BASE_SERVER_IMAGE_NAME=nestjs-mod/nestjs-mod-fullstack-base-server
FROM ${REGISTRY}/${BASE_SERVER_IMAGE_NAME}:${BASE_SERVER_IMAGE_TAG} AS builder
WORKDIR /usr/src/app
# Disable nx daemon
ENV NX_DAEMON=false
# Copy the generated code
COPY --chown=node:node ./dist ./dist
# Copy prisma schema files
COPY --chown=node:node ./apps ./apps
COPY --chown=node:node ./libs ./libs
# Copy the application's package.json file to use its information at runtime.
COPY --chown=node:node ./apps/server/package.json ./dist/apps/server/package.json
# Generating additional code
RUN npm run prisma:generate -- --verbose
# Remove unnecessary packages
RUN rm -rf /usr/src/app/node_modules/@nx && \
rm -rf /usr/src/app/node_modules/@prisma-class-generator && \
rm -rf /usr/src/app/node_modules/@angular && \
rm -rf /usr/src/app/node_modules/@swc && \
rm -rf /usr/src/app/node_modules/@babel && \
rm -rf /usr/src/app/node_modules/@angular-devkit && \
rm -rf /usr/src/app/node_modules/@ngneat && \
rm -rf /usr/src/app/node_modules/@types && \
rm -rf /usr/src/app/node_modules/@ng-packagr && \
rm -rf /usr/src/app/apps && \
rm -rf /usr/src/app/libs
FROM node:20.16.0-alpine
WORKDIR /usr/src/app
# Set server port
ENV SERVER_PORT=8080
# Copy all project files
COPY --from=builder /usr/src/app/ /usr/src/app/
# Copy utility for "To work as a PID 1"
COPY --from=builder /usr/bin/dumb-init /usr/bin/dumb-init
# Expose server port
EXPOSE 8080
# Run server
CMD ["dumb-init","node", "dist/apps/server/main.js"]
4. Создаем Docker-образ для запуска миграций в базы данных
Так как мы не хотим ставить лишние зависимости на хост машине, то для запуска миграций собираем Docker-образ с необходимыми зависимостями.
В своих проектах я использую мигратор "Flyway", но для его работы нужно скачать дополнительные файлы которые сильно увеличивают итоговый образ, если взять другой мигратор, то образ будет меньше.
Файлы с миграциями не кладутся в сам образ, они лежат рядом с исходным кодом, который монтируется через volume
в контейнер при старте.
Пересборка данного Docker-образа бу дет происходить при смене версии корневого package.json
.
Создаем файл .docker/migrations.Dockerfile
FROM node:20-bullseye-slim AS builder
WORKDIR /usr/src/app
# Disable nx daemon
ENV NX_DAEMON=false
# Copy all files in repository to image
COPY --chown=node:node . .
# Copy the settings
COPY ./.docker/migrations-package.json package.json
COPY ./.docker/.dockerignore .dockerignore
COPY ./.docker/nx.json nx.json
# Install dependencies
RUN rm -rf package-lock.json && npm install --prefer-offline --no-audit --progress=false
# Some utilities require a ".env" file
RUN echo '' > .env
# Generate additional files
RUN ./node_modules/.bin/flyway -c ./.flyway.js info || echo 'skip flyway errors'
FROM node:20-bullseye-slim
WORKDIR /usr/src/app
# Copy node_modules
COPY --from=builder /usr/src/app/node_modules /usr/src/app/node_modules
# Copy the settings
COPY --from=builder /usr/src/app/.docker/.dockerignore /usr/src/app/.dockerignore
COPY --from=builder /usr/src/app/.docker/nx.json /usr/src/app/nx.json
COPY --from=builder /usr/src/app/package.json /usr/src/app/package.json
COPY --from=builder /usr/src/app/rucken.json /usr/src/app/rucken.json
COPY --from=builder /usr/src/app/tsconfig.base.json /usr/src/app/tsconfig.base.json
COPY --from=builder /usr/src/app/.env /usr/src/app/.env
# Copy files for flyway
COPY --from=builder /usr/src/app/tmp /usr/src/app/tmp
COPY --from=builder /usr/src/app/.flyway.js /usr/src/app/.flyway.js
# Copy folders with migrations
# COPY --chown=node:node ./apps ./apps
# COPY --chown=node:node ./libs ./libs
CMD ["npm","run", "db:create-and-fill"]
Список зависимостей отличается от рутового списка это нужно для уменьшения итогового образа.
Создаем файл с необходимыми зависимостями .docker/migrations-package.json
{
"name": "@nestjs-mod-fullstack/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"_____db_____": "_____db_____",
"db:create": "./node_modules/.bin/nx run-many -t=db-create",
"db:create-and-fill": "npm run db:create && npm run flyway:migrate",
"_____flyway_____": "_____flyway_____",
"flyway:migrate": "./node_modules/.bin/nx run-many -t=flyway-migrate"
},
"private": true,
"devDependencies": {
"node-flywaydb": "^3.0.7",
"nx": "19.5.3",
"rucken": "^4.8.1"
},
"dependencies": {
"dotenv": "^16.4.5"
}
}
5. Создаем Docker-образ для запуска E2E-тестов
Так как мы не хотим ставить лишние зависимости на хост машине, то для запуска E2E-тестов собираем Docker-образ с необходимыми зависимостями..
Клиентские E2E-тесты запускаются через playwright и используют при работе браузерные движки: chromium, firefox и webkit, для их работы нужно скачать дополнительные файлы которые сильно увеличивают итоговый образ, если исключить часть движков или вообще отключить клиенсткие тесты, то образ будет меньше.
Файлы с тестами не кладутся в сам образ, они лежат рядом с исходным кодом, который монтируется через volume
в контейнер при старте.
Пересборка данного Docker-образа будет происходить при смене версии корневого package.json
.
Создаем файл .docker/e2e-tests.Dockerfile
FROM node:20-bullseye-slim
WORKDIR /usr/src/app
# Disable nx daemon
ENV NX_DAEMON=false
# Url with stage to run e2e tests
ENV BASE_URL=http://localhost:8080
# Copy all files in repository to image
COPY --chown=node:node . .
# Copy the settings
COPY ./.docker/e2e-tests-package.json package.json
COPY ./.docker/e2e-tests-nx.json nx.json
COPY ./.docker/.dockerignore .dockerignore
# Some utilities require a ".env" file
RUN echo '' > .env
# Install dependencies
RUN rm -rf package-lock.json && \
npm install --prefer-offline --no-audit --progress=false && \
# Install external utils
npx playwright install --with-deps && \
# Clear cache
npm cache clean --force
# Copy folders with migrations
# COPY --chown=node:node ./apps ./apps
# COPY --chown=node:node ./libs ./libs
CMD ["npm","run", "test:e2e"]
Список зависимостей отличается от рутового списка это нужно для уменьшения итогового образа.
Создаем файл с необходимыми зависимостями .docker/e2e-tests-package.json
{
"name": "@nestjs-mod-fullstack/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"test:e2e": "./node_modules/.bin/nx run-many --exclude=@nestjs-mod-fullstack/source --all -t=e2e --skip-nx-cache=true --output-style=stream-without-prefixes"
},
"private": true,
"devDependencies": {
"@nx/jest": "19.5.3",
"@nx/playwright": "19.5.3",
"@playwright/test": "^1.36.0",
"@types/jest": "^29.4.0",
"@types/node": "~18.16.9",
"jest": "^29.4.1",
"nx": "19.5.3",
"ts-jest": "^29.1.0"
},
"dependencies": {
"dotenv": "^16.4.5",
"rxjs": "^7.8.0",
"tslib": "^2.3.0"
}
}
Миграции запускаются с помощью nx, для полного запуска которого нужно ставить дополнительные зависимости.
Чтобы не увеличивать итог овый размер образа для запуска тестов, необходимо создать урезанный вариант nx конфига.
Создаем файл .docker/e2e-tests-nx.json
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": ["default", "!{projectRoot}/.eslintrc.json", "!{projectRoot}/eslint.config.js", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", "!{projectRoot}/tsconfig.spec.json", "!{projectRoot}/jest.config.[jt]s", "!{projectRoot}/src/test-setup.[jt]s", "!{projectRoot}/test-setup.[jt]s"],
"sharedGlobals": []
},
"plugins": [
{
"plugin": "@nx/playwright/plugin",
"options": {
"targetName": "e2e"
}
}
]
}
6. Клиентский код отдается через Nginx, так что создаем Docker-образ с встроенным Nginx и статичными файлами
Часть параметров Nginx конфигурации должны быть переопределяемыми, так как будут несколько вариантов запуска инфраструктуры: Docker Compose и Kubernetes, в каждом варианте полное название сервисов в пределах сети инфраструктуры отличается.
Стартовой точкой данного образа будет не Nginx, а Bash-скрипт который предварительно пропатчить конфигурацию Nginx.
Создаем файл .docker/nginx.Dockerfile
FROM nginx:alpine
# Set server port
ENV SERVER_PORT=8080
# Set nginx port
ENV NGINX_PORT=8080
# Copy nginx config
COPY --chown=node:node ../.docker/nginx /etc/nginx/conf.d
# Copy frontend
COPY --chown=node:node ../dist/apps/client/browser /usr/share/nginx/html
# Install Bash Shell
RUN apk add --update bash
# Clean up
RUN rm -rf /var/cache/apk/*
# Add a startup script
COPY --chown=node:node ../.docker/nginx/start.sh /start.sh
RUN chmod 755 /start.sh
# Expose nginx port
EXPOSE 8080
CMD ["/start.sh"]
Обновляем файл c конфигурацией Nginx .docker/nginx/nginx.conf
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream nestjs-mod-fullstack-server {
# Dynamic name of the server container and the port it runs on
server ___SERVER_NAME___:___SERVER_PORT___;
}
server {
# Dynamic Nginx port that is shared externally
listen ___NGINX_PORT___;
server_name localhost;
gzip on;
gzip_proxied any;
gzip_types text/plain application/xml text/css application/javascript application/json;
gzip_min_length 1000;
gzip_vary on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
client_max_body_size 50m;
proxy_connect_timeout 5m;
proxy_send_timeout 5m;
proxy_read_timeout 5m;
send_timeout 5m;
proxy_max_temp_file_size 0;
root /usr/share/nginx/html;
index index.html;
location /api {
proxy_pass http://nestjs-mod-fullstack-server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
location /swagger {
proxy_pass http://nestjs-mod-fullstack-server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
location / {
expires $expires;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_intercept_errors on;
error_page 404 =200 /index.html;
root /usr/share/nginx/html;
}
}
Создаем Bash-скрипт для пачтинга конфигурации Nginx и его запуск .docker/nginx/start.sh
#!/bin/bash
if [[ -z "${SERVER_PORT}" ]]; then
SERVER_PORT="8080"
else
SERVER_PORT="${SERVER_PORT}"
fi
if [[ -z "${SERVER_NAME}" ]]; then
SERVER_NAME="nestjs-mod-fullstack-server"
else
SERVER_NAME="${SERVER_NAME}"
fi
if [[ -z "${NGINX_PORT}" ]]; then
NGINX_PORT="8080"
else
NGINX_PORT="${NGINX_PORT}"
fi
# Replacing Nginx Dynamic Parameters
sed -i "s/___SERVER_NAME___/$SERVER_NAME/g" /etc/nginx/conf.d/nginx.conf
sed -i "s/___SERVER_PORT___/$SERVER_PORT/g" /etc/nginx/conf.d/nginx.conf
sed -i "s/___NGINX_PORT___/$NGINX_PORT/g" /etc/nginx/conf.d/nginx.conf
# Launch Nginx
/usr/sbin/nginx -g "daemon off;"
7. Обновляем файлы для запуска в режиме "Docker Compose"
Часть переменных окружения для сборки и запуска образов будет формироваться в специальном Bash-скрипте и экспортироваться в активный процесс.
Создаем файл .docker/set-env.sh
#!/bin/bash
set -e
export REPOSITORY=nestjs-mod/nestjs-mod-fullstack
export REGISTRY=ghcr.io
export BASE_SERVER_IMAGE_NAME="${REPOSITORY}-base-server"
export BUILDER_IMAGE_NAME="${REPOSITORY}-builder"
export MIGRATIONS_IMAGE_NAME="${REPOSITORY}-migrations"
export SERVER_IMAGE_NAME="${REPOSITORY}-server"
export NGINX_IMAGE_NAME="${REPOSITORY}-nginx"
export E2E_TESTS_IMAGE_NAME="${REPOSITORY}-e2e-tests"
export COMPOSE_INTERACTIVE_NO_CLI=1
export NX_DAEMON=false
export NX_PARALLEL=1
export NX_SKIP_NX_CACHE=true
export DISABLE_SERVE_STATIC=true
export ROOT_VERSION=$(npm pkg get version --workspaces=false | tr -d \")
export SERVER_VERSION=$(cd ./apps/server && npm pkg get version --workspaces=false | tr -d \")
Обновляем файл .docker/docker-compose-full.yml
version: '3'
networks:
nestjs-mod-fullstack-network:
driver: 'bridge'
services:
nestjs-mod-fullstack-postgre-sql:
image: 'bitnami/postgresql:15.5.0'
container_name: 'nestjs-mod-fullstack-postgre-sql'
networks:
- 'nestjs-mod-fullstack-network'
healthcheck:
test:
- 'CMD-SHELL'
- 'pg_isready -U postgres'
interval: '5s'
timeout: '5s'
retries: 5
tty: true
restart: 'always'
environment:
POSTGRESQL_USERNAME: '${SERVER_POSTGRE_SQL_POSTGRESQL_USERNAME}'
POSTGRESQL_PASSWORD: '${SERVER_POSTGRE_SQL_POSTGRESQL_PASSWORD}'
POSTGRESQL_DATABASE: '${SERVER_POSTGRE_SQL_POSTGRESQL_DATABASE}'
volumes:
- 'nestjs-mod-fullstack-postgre-sql-volume:/bitnami/postgresql'
nestjs-mod-fullstack-postgre-sql-migrations:
image: 'ghcr.io/nestjs-mod/nestjs-mod-fullstack-migrations:${ROOT_VERSION}'
container_name: 'nestjs-mod-fullstack-postgre-sql-migrations'
networks:
- 'nestjs-mod-fullstack-network'
tty: true
environment:
NX_SKIP_NX_CACHE: 'true'
SERVER_ROOT_DATABASE_URL: '${SERVER_ROOT_DATABASE_URL}'
SERVER_APP_DATABASE_URL: '${SERVER_APP_DATABASE_URL}'
depends_on:
nestjs-mod-fullstack-postgre-sql:
condition: 'service_healthy'
working_dir: '/usr/src/app'
volumes:
- './../apps:/usr/src/app/apps'
- './../libs:/usr/src/app/libs'
nestjs-mod-fullstack-server:
image: 'ghcr.io/nestjs-mod/nestjs-mod-fullstack-server:${SERVER_VERSION}'
container_name: 'nestjs-mod-fullstack-server'
networks:
- 'nestjs-mod-fullstack-network'
healthcheck:
test: ['CMD-SHELL', 'npx -y wait-on --timeout= --interval=1000 --window --verbose --log http://localhost:${SERVER_PORT}/api/health']
interval: 30s
timeout: 10s
retries: 10
tty: true
environment:
SERVER_APP_DATABASE_URL: '${SERVER_APP_DATABASE_URL}'
SERVER_PORT: '${SERVER_PORT}'
restart: 'always'
depends_on:
nestjs-mod-fullstack-postgre-sql:
condition: service_healthy
nestjs-mod-fullstack-postgre-sql-migrations:
condition: service_completed_successfully
nestjs-mod-fullstack-nginx:
image: 'ghcr.io/nestjs-mod/nestjs-mod-fullstack-nginx:${SERVER_VERSION}'
container_name: 'nestjs-mod-fullstack-nginx'
networks:
- 'nestjs-mod-fullstack-network'
healthcheck:
test: ['CMD-SHELL', 'curl -so /dev/null http://localhost:${NGINX_PORT} || exit 1']
interval: 30s
timeout: 10s
retries: 10
environment:
SERVER_PORT: '${SERVER_PORT}'
NGINX_PORT: '${NGINX_PORT}'
restart: 'always'
depends_on:
nestjs-mod-fullstack-server:
condition: service_healthy
ports:
- '${NGINX_PORT}:${NGINX_PORT}'
nestjs-mod-fullstack-e2e-tests:
image: 'ghcr.io/nestjs-mod/nestjs-mod-fullstack-e2e-tests:${ROOT_VERSION}'
container_name: 'nestjs-mod-fullstack-e2e-tests'
networks:
- 'nestjs-mod-fullstack-network'
environment:
BASE_URL: 'http://nestjs-mod-fullstack-nginx:${NGINX_PORT}'
depends_on:
nestjs-mod-fullstack-nginx:
condition: service_healthy
working_dir: '/usr/src/app'
volumes:
- './../apps:/usr/src/app/apps'
- './../libs:/usr/src/app/libs'
nestjs-mod-fullstack-https-portal:
image: steveltn/https-portal:1
container_name: 'nestjs-mod-fullstack-https-portal'
networks:
- 'nestjs-mod-fullstack-network'
ports:
- '80:80'
- '443:443'
links:
- nestjs-mod-fullstack-nginx
restart: always
environment:
STAGE: '${HTTPS_PORTAL_STAGE}'
DOMAINS: '${SERVER_DOMAIN} -> http://nestjs-mod-fullstack-nginx:${NGINX_PORT}'
depends_on:
nestjs-mod-fullstack-nginx:
condition: service_healthy
volumes:
- nestjs-mod-fullstack-https-portal-volume:/var/lib/https-portal
volumes:
nestjs-mod-fullstack-postgre-sql-volume:
name: 'nestjs-mod-fullstack-postgre-sql-volume'
nestjs-mod-fullstack-https-portal-volume:
name: 'nestjs-mod-fullstack-https-portal-volume'