build: refactor production containers
Production containers now copy the Zeppelin source files at build-time rather than using a shared volume. This means fewer permission issues and backend/dashboard builds only have to run once at build-time, not every time the containers are started. Docs in PRODUCTION.md have been updated accordingly.
This commit is contained in:
parent
b60a7fb145
commit
b67b3c35b7
8 changed files with 60 additions and 64 deletions
11
.dockerignore
Normal file
11
.dockerignore
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.git
|
||||||
|
.github
|
||||||
|
.idea
|
||||||
|
.devcontainer
|
||||||
|
|
||||||
|
/docker/development/data
|
||||||
|
/docker/production/data
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
/backend/dist
|
||||||
|
/dashboard/dist
|
|
@ -5,7 +5,8 @@ Zeppelin's production environment - that is, the **bot, API, and dashboard** - u
|
||||||
1. Install Docker on the machine running the bot
|
1. Install Docker on the machine running the bot
|
||||||
2. Make a copy of `.env.example` called `.env`
|
2. Make a copy of `.env.example` called `.env`
|
||||||
3. Fill in the missing values in `.env`
|
3. Fill in the missing values in `.env`
|
||||||
4. Run `docker compose -f docker-compose.production.yml up -d`
|
4. Run `docker compose -f docker-compose.production.yml build`
|
||||||
|
5. Run `docker compose -f docker-compose.production.yml up -d`
|
||||||
|
|
||||||
**Note:** The dashboard and API are exposed with a self-signed certificate. It is recommended to set up a proxy with a proper certificate in front of them. Cloudflare is a popular choice here.
|
**Note:** The dashboard and API are exposed with a self-signed certificate. It is recommended to set up a proxy with a proper certificate in front of them. Cloudflare is a popular choice here.
|
||||||
|
|
||||||
|
@ -15,18 +16,17 @@ Zeppelin's production environment - that is, the **bot, API, and dashboard** - u
|
||||||
If you've downloaded the bot's files by cloning the git repository, you can use `update.sh` to update the bot.
|
If you've downloaded the bot's files by cloning the git repository, you can use `update.sh` to update the bot.
|
||||||
|
|
||||||
### Manual instructions
|
### Manual instructions
|
||||||
1. Shut the bot down: `docker compose -f docker-compose.production.yml stop`
|
1. Shut the bot down: `docker compose -f docker-compose.production.yml down`
|
||||||
2. Update the files (e.g. `git pull`)
|
2. Update the files (e.g. `git pull`)
|
||||||
3. Start the bot again: `docker compose -f docker-compose.production.yml start`
|
3. Build new images: `docker compose -f docker-compose.production.yml build`
|
||||||
|
3. Start the bot again: `docker compose -f docker-compose.production.yml up -d`
|
||||||
|
|
||||||
### Ephemeral hotfixes
|
### Ephemeral hotfixes
|
||||||
If you need to make a hotfix to the bot's source files directly on the server:
|
If you need to make a hotfix to the bot's source files directly on the server:
|
||||||
1. Shut the bot down: `docker compose -f docker-compose.production.yml stop`
|
1. Shut the bot down: `docker compose -f docker-compose.production.yml down`
|
||||||
2. Make your edits
|
2. Make your edits
|
||||||
3. Start the bot again: `docker compose -f docker-compose.production.yml start`
|
3. Build new images: `docker compose -f docker-compose.production.yml build`
|
||||||
|
4. Start the bot again: `docker compose -f docker-compose.production.yml up -d`
|
||||||
Note that you can't edit the compiled files directly as they're overwritten when the environment starts.
|
|
||||||
Only edit files in `/backend/src`, `/shared/src`, and `/dashboard/src`.
|
|
||||||
|
|
||||||
Make sure to revert any hotfixes before updating the bot normally.
|
Make sure to revert any hotfixes before updating the bot normally.
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ name: zeppelin-prod
|
||||||
services:
|
services:
|
||||||
nginx:
|
nginx:
|
||||||
build:
|
build:
|
||||||
context: ./docker/production/nginx
|
context: .
|
||||||
|
dockerfile: docker/production/nginx/Dockerfile
|
||||||
args:
|
args:
|
||||||
API_PORT: ${API_PORT:?Missing API_PORT}
|
API_PORT: ${API_PORT:?Missing API_PORT}
|
||||||
DOCKER_PROD_DOMAIN: ${DOCKER_PROD_DOMAIN:?Missing DOCKER_PROD_DOMAIN}
|
DOCKER_PROD_DOMAIN: ${DOCKER_PROD_DOMAIN:?Missing DOCKER_PROD_DOMAIN}
|
||||||
|
@ -30,60 +31,32 @@ services:
|
||||||
timeout: 300s
|
timeout: 300s
|
||||||
retries: 60
|
retries: 60
|
||||||
|
|
||||||
prepare_backend:
|
migrate:
|
||||||
build:
|
build:
|
||||||
context: ./docker/production/node
|
context: .
|
||||||
args:
|
dockerfile: docker/production/backend/Dockerfile
|
||||||
DOCKER_USER_UID: ${DOCKER_USER_UID:?Missing DOCKER_USER_UID}
|
command: ["npm", "run", "migrate-prod"]
|
||||||
DOCKER_USER_GID: ${DOCKER_USER_GID:?Missing DOCKER_USER_GID}
|
|
||||||
depends_on:
|
|
||||||
mysql:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- ./:/zeppelin
|
|
||||||
command: |-
|
|
||||||
bash -c "cd /zeppelin/backend && npm ci && npm run build && npm run migrate-prod"
|
|
||||||
|
|
||||||
api:
|
api:
|
||||||
build:
|
|
||||||
context: ./docker/production/node
|
|
||||||
args:
|
|
||||||
DOCKER_USER_UID: ${DOCKER_USER_UID:?Missing DOCKER_USER_UID}
|
|
||||||
DOCKER_USER_GID: ${DOCKER_USER_GID:?Missing DOCKER_USER_GID}
|
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
depends_on:
|
||||||
prepare_backend:
|
migrate:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
volumes:
|
build:
|
||||||
- ./:/zeppelin
|
context: .
|
||||||
|
dockerfile: docker/production/backend/Dockerfile
|
||||||
|
restart: on-failure
|
||||||
environment:
|
environment:
|
||||||
DEBUG: ${DEBUG-}
|
DEBUG: ${DEBUG-}
|
||||||
working_dir: /zeppelin/backend
|
|
||||||
command: ["npm", "run", "start-api-prod"]
|
command: ["npm", "run", "start-api-prod"]
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
build:
|
|
||||||
context: ./docker/production/node
|
|
||||||
args:
|
|
||||||
DOCKER_USER_UID: ${DOCKER_USER_UID:?Missing DOCKER_USER_UID}
|
|
||||||
DOCKER_USER_GID: ${DOCKER_USER_GID:?Missing DOCKER_USER_GID}
|
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
depends_on:
|
||||||
prepare_backend:
|
migrate:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
volumes:
|
build:
|
||||||
- ./:/zeppelin
|
context: .
|
||||||
|
dockerfile: docker/production/backend/Dockerfile
|
||||||
|
restart: on-failure
|
||||||
environment:
|
environment:
|
||||||
DEBUG: ${DEBUG-}
|
DEBUG: ${DEBUG-}
|
||||||
command: ["/bin/bash", "/zeppelin/docker/production/start-bot.sh"]
|
command: ["/bin/bash", "/zeppelin/docker/production/start-bot.sh"]
|
||||||
|
|
||||||
build_dashboard:
|
|
||||||
build:
|
|
||||||
context: ./docker/production/node
|
|
||||||
args:
|
|
||||||
DOCKER_USER_UID: ${DOCKER_USER_UID:?Missing DOCKER_USER_UID}
|
|
||||||
DOCKER_USER_GID: ${DOCKER_USER_GID:?Missing DOCKER_USER_GID}
|
|
||||||
volumes:
|
|
||||||
- ./:/zeppelin
|
|
||||||
command: |-
|
|
||||||
bash -c "cd /zeppelin/dashboard && npm ci && npm run build"
|
|
||||||
|
|
9
docker/production/backend/Dockerfile
Normal file
9
docker/production/backend/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
FROM node:18
|
||||||
|
USER node
|
||||||
|
|
||||||
|
COPY --chown=node:node . /zeppelin
|
||||||
|
|
||||||
|
WORKDIR /zeppelin/backend
|
||||||
|
RUN ls -lah
|
||||||
|
RUN pwd
|
||||||
|
RUN npm ci && npm run build
|
|
@ -1,3 +1,13 @@
|
||||||
|
FROM node:18 AS builder
|
||||||
|
USER node
|
||||||
|
|
||||||
|
COPY --chown=node:node . /zeppelin
|
||||||
|
|
||||||
|
WORKDIR /zeppelin/dashboard
|
||||||
|
RUN ls -lah
|
||||||
|
RUN pwd
|
||||||
|
RUN npm ci && npm run build
|
||||||
|
|
||||||
FROM nginx
|
FROM nginx
|
||||||
|
|
||||||
ARG API_PORT
|
ARG API_PORT
|
||||||
|
@ -6,6 +16,8 @@ ARG DOCKER_PROD_DOMAIN
|
||||||
RUN apt-get update && apt-get install -y openssl
|
RUN apt-get update && apt-get install -y openssl
|
||||||
RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/zeppelin-self-signed-cert.key -out /etc/ssl/certs/zeppelin-self-signed-cert.pem -days 3650 -subj "/CN=${DOCKER_PROD_DOMAIN}" -nodes
|
RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/zeppelin-self-signed-cert.key -out /etc/ssl/certs/zeppelin-self-signed-cert.pem -days 3650 -subj "/CN=${DOCKER_PROD_DOMAIN}" -nodes
|
||||||
|
|
||||||
COPY ./default.conf /etc/nginx/conf.d/default.conf
|
COPY ./docker/production/nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||||
RUN sed -ir "s/_API_PORT_/${API_PORT}/g" /etc/nginx/conf.d/default.conf
|
RUN sed -ir "s/_API_PORT_/${API_PORT}/g" /etc/nginx/conf.d/default.conf
|
||||||
RUN sed -ir "s/_DOCKER_PROD_DOMAIN_/${DOCKER_PROD_DOMAIN}/g" /etc/nginx/conf.d/default.conf
|
RUN sed -ir "s/_DOCKER_PROD_DOMAIN_/${DOCKER_PROD_DOMAIN}/g" /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
COPY --from=builder /zeppelin/dashboard/dist /var/www
|
||||||
|
|
|
@ -3,7 +3,7 @@ server {
|
||||||
listen [::]:443 ssl http2;
|
listen [::]:443 ssl http2;
|
||||||
server_name _DOCKER_PROD_DOMAIN_;
|
server_name _DOCKER_PROD_DOMAIN_;
|
||||||
|
|
||||||
root /zeppelin/dashboard/dist;
|
root /var/www;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
FROM node:18
|
|
||||||
|
|
||||||
ARG DOCKER_USER_UID
|
|
||||||
ARG DOCKER_USER_GID
|
|
||||||
|
|
||||||
# This custom Dockerfile is needed for the Node image so we can change the uid/gid used for the node user
|
|
||||||
# See https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#non-root-user
|
|
||||||
RUN groupmod -g "${DOCKER_USER_GID}" node && usermod -u "${DOCKER_USER_UID}" -g "${DOCKER_USER_GID}" node
|
|
||||||
|
|
||||||
USER node
|
|
|
@ -4,6 +4,7 @@ echo Updating Zeppelin...
|
||||||
|
|
||||||
docker compose -f docker-compose.production.yml stop
|
docker compose -f docker-compose.production.yml stop
|
||||||
git pull
|
git pull
|
||||||
docker compose -f docker-compose.production.yml start
|
docker compose -f docker-compose.production.yml build
|
||||||
|
docker compose -f docker-compose.production.yml up -d
|
||||||
|
|
||||||
echo Update finished!
|
echo Update finished!
|
||||||
|
|
Loading…
Add table
Reference in a new issue