From ee7e9ef2a364c8e79e964b8759206b07905723d5 Mon Sep 17 00:00:00 2001 From: swomf Date: Wed, 5 Mar 2025 01:05:02 -0500 Subject: [PATCH] build: setup docker-compose.dev.yml dev iteration This is based off of the 5-commit branch at https://github.com/neobooru/szurubooru/blob/docker-development-setup. Compared to said branch, we * Exclude extraneous changes such as * Any formatting * The use of deprecated/ineffectual top-level `version:` in composer files * Support controlling $THREADS (modernizing the branch to upstream) * Integrate into master more cleanly However, client/docker-start-dev uses a temporary hack -- due to volume mounting overwriting node_modules at arbitrary points during the `docker compose build` step, we run `npm i` before any given `npm run watch`. To see the effects of this commit in action, run: docker compose -f ./docker-compose.dev.yml up --- client/.dockerignore | 1 + client/Dockerfile | 23 ++++++++++++++++ client/build.js | 2 +- client/docker-start-dev.sh | 17 ++++++++++++ client/docker-start.sh | 6 ++--- client/js/main.js | 2 +- docker-compose.dev.yml | 54 ++++++++++++++++++++++++++++++++++++++ server/Dockerfile | 35 ++++++++++++++++++++++++ server/docker-start-dev.sh | 8 ++++++ 9 files changed, 143 insertions(+), 5 deletions(-) create mode 100755 client/docker-start-dev.sh create mode 100644 docker-compose.dev.yml create mode 100755 server/docker-start-dev.sh diff --git a/client/.dockerignore b/client/.dockerignore index cc2d280c..69da0e1c 100644 --- a/client/.dockerignore +++ b/client/.dockerignore @@ -1,4 +1,5 @@ node_modules/* +public/ Dockerfile .dockerignore **/.gitignore diff --git a/client/Dockerfile b/client/Dockerfile index ea5151fa..8012a999 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,3 +1,26 @@ +FROM --platform=$BUILDPLATFORM node:lts-alpine as development +WORKDIR /opt/app + +RUN apk --no-cache add \ + dumb-init \ + nginx \ + git + +RUN ln -sf /opt/app/nginx.conf.docker /etc/nginx/nginx.conf +RUN rm -rf /var/www +RUN ln -sf /opt/app/public/ /var/www + +COPY package.json package-lock.json ./ +RUN npm install + +ARG BUILD_INFO="docker-development" +ENV BUILD_INFO=${BUILD_INFO} +ENV BACKEND_HOST="server" + +CMD ["/opt/app/docker-start-dev.sh"] +VOLUME ["/data"] + + FROM --platform=$BUILDPLATFORM node:lts as builder WORKDIR /opt/app diff --git a/client/build.js b/client/build.js index eaf28a54..5b0d4ee7 100755 --- a/client/build.js +++ b/client/build.js @@ -315,7 +315,7 @@ function makeOutputDirs() { } function watch() { - let wss = new WebSocket.Server({ port: 8080 }); + let wss = new WebSocket.Server({ port: environment === "development" ? 8081 : 8080 }); const liveReload = !process.argv.includes('--no-live-reload'); function emitReload() { diff --git a/client/docker-start-dev.sh b/client/docker-start-dev.sh new file mode 100755 index 00000000..fe9d22e0 --- /dev/null +++ b/client/docker-start-dev.sh @@ -0,0 +1,17 @@ +#!/usr/bin/dumb-init /bin/sh + +# Integrate environment variables +sed -i "s|__BACKEND__|${BACKEND_HOST}|" \ + /etc/nginx/nginx.conf + +# Start server +nginx & + +# Watch source for changes and build app +# FIXME: It's not ergonomic to run `npm i` outside of the build step. +# However, the mounting of different directories into the +# client container's /opt/app causes node_modules to disappear +# (the mounting causes client/Dockerfile's RUN npm install +# to silently clobber). +# Find a way to move `npm i` into client/Dockerfile. +npm i && npm run watch -- --polling diff --git a/client/docker-start.sh b/client/docker-start.sh index 0b2bec8a..30392591 100755 --- a/client/docker-start.sh +++ b/client/docker-start.sh @@ -2,10 +2,10 @@ # Integrate environment variables sed -i "s|__BACKEND__|${BACKEND_HOST}|" \ - /etc/nginx/nginx.conf + /etc/nginx/nginx.conf sed -i "s|__BASEURL__|${BASE_URL:-/}|g" \ - /var/www/index.htm \ - /var/www/manifest.json + /var/www/index.htm \ + /var/www/manifest.json # Start server exec nginx diff --git a/client/js/main.js b/client/js/main.js index c5bdc537..d1b59e6f 100644 --- a/client/js/main.js +++ b/client/js/main.js @@ -3,7 +3,7 @@ const config = require("./config.js"); if (config.environment == "development") { - var ws = new WebSocket("ws://" + location.hostname + ":8080"); + var ws = new WebSocket("ws://" + location.hostname + ":8081"); ws.addEventListener("open", function (event) { console.log("Live-reloading websocket connected."); }); diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 00000000..3c736f0c --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,54 @@ +## Docker Compose configuration for dev iteration +## +## Data is transient by using named vols. +## Run: docker-compose -f ./docker-compose.dev.yml up +services: + + server: + build: + context: ./server + target: development + depends_on: + - sql + environment: + ## These should be the names of the dependent containers listed below, + ## or FQDNs/IP addresses if these services are running outside of Docker + POSTGRES_HOST: sql + ## Credentials for database: + POSTGRES_USER: + POSTGRES_PASSWORD: + ## Commented Values are Default: + #POSTGRES_DB: defaults to same as POSTGRES_USER + #POSTGRES_PORT: 5432 + #LOG_SQL: 0 (1 for verbose SQL logs) + THREADS: + volumes: + - "data:/data" + - "./server/:/opt/app/" + + client: + build: + context: ./client + target: development + depends_on: + - server + volumes: + - "data:/data:ro" + - "./client/:/opt/app/" + - "/opt/app/public/" + ports: + - "${PORT}:80" + - "8081:8081" + + sql: + image: postgres:11-alpine + restart: unless-stopped + environment: + POSTGRES_USER: + POSTGRES_PASSWORD: + volumes: + - "sql:/var/lib/postgresql/data" + +volumes: + data: + sql: diff --git a/server/Dockerfile b/server/Dockerfile index 3e4dadfb..032ec098 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -61,7 +61,42 @@ ENTRYPOINT ["pytest", "--tb=short"] CMD ["szurubooru/"] +FROM prereqs as development +WORKDIR /opt/app + +ARG PUID=1000 +ARG PGID=1000 + +RUN apk --no-cache add \ + dumb-init \ + py3-pip \ + py3-setuptools \ + py3-waitress \ + && pip3 install --no-cache-dir --disable-pip-version-check \ + hupper \ + && mkdir -p /opt/app /data \ + && addgroup -g ${PGID} app \ + && adduser -SDH -h /opt/app -g '' -G app -u ${PUID} app \ + && chown -R app:app /opt/app /data + +USER app +CMD ["/opt/app/docker-start-dev.sh"] + +ARG PORT=6666 +ENV PORT=${PORT} +EXPOSE ${PORT} + +ARG THREADS=4 +ENV THREADS=${THREADS} + +VOLUME ["/data/"] + + FROM prereqs as release + +COPY ./ /opt/app/ +RUN rm -rf /opt/app/szurubooru/tests + WORKDIR /opt/app ARG PUID=1000 diff --git a/server/docker-start-dev.sh b/server/docker-start-dev.sh new file mode 100755 index 00000000..2474a649 --- /dev/null +++ b/server/docker-start-dev.sh @@ -0,0 +1,8 @@ +#!/usr/bin/dumb-init /bin/sh +set -e +cd /opt/app + +alembic upgrade head + +echo "Starting szurubooru API on port ${PORT} - Running on ${THREADS} threads" +exec hupper -m waitress --port ${PORT} --threads ${THREADS} szurubooru.facade:app