diff --git a/.devcontainer/.docker/dzhura/Dockerfile b/.devcontainer/.docker/dzhura/Dockerfile index fde94bc5..51822866 100644 --- a/.devcontainer/.docker/dzhura/Dockerfile +++ b/.devcontainer/.docker/dzhura/Dockerfile @@ -1,9 +1,13 @@ -FROM ghcr.io/sjinks/codespaces/alpine-base:latest@sha256:31cf3a267c59a9887acd0d68c62c46bc808c53e78debe87492f56ef84a019632 +FROM ghcr.io/sjinks/codespaces/nodejs:latest@sha256:04805972fe280ba8a0e7951e101f5139316f123b79542d0e38073d861cda3a8a + +ENV SERVICE_NAME dzhura RUN \ - apk add --no-cache nodejs npm python3 make g++ nginx + apk add --no-cache nginx && \ + sed -i "s/user nginx;/user ${CONTAINER_USER};/" /etc/nginx/nginx.conf && \ + chown -R "${CONTAINER_USER}:${CONTAINER_USER}" /run/nginx /var/log/nginx /var/lib/nginx COPY rootfs / WORKDIR /usr/src/service -RUN chown -R vscode:vscode /usr/src/service +RUN chown -R "${CONTAINER_USER}:${CONTAINER_USER}" /usr/src/service diff --git a/.devcontainer/.docker/dzhura/rootfs/etc/nginx/http.d/default.conf b/.devcontainer/.docker/dzhura/rootfs/etc/nginx/http.d/default.conf index ccf1dbbb..e356a103 100644 --- a/.devcontainer/.docker/dzhura/rootfs/etc/nginx/http.d/default.conf +++ b/.devcontainer/.docker/dzhura/rootfs/etc/nginx/http.d/default.conf @@ -24,7 +24,7 @@ server { proxy_pass http://localhost:3000/; } - location /swagger { + location /swagger/ { proxy_pass http://swagger:8080; } } diff --git a/.devcontainer/.docker/dzhura/rootfs/etc/sv/dzhura/run b/.devcontainer/.docker/dzhura/rootfs/etc/sv/dzhura/run index a4085e77..4707135e 100755 --- a/.devcontainer/.docker/dzhura/rootfs/etc/sv/dzhura/run +++ b/.devcontainer/.docker/dzhura/rootfs/etc/sv/dzhura/run @@ -4,6 +4,9 @@ set -e exec 2>&1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +SERVICE_USER="${CONTAINER_USER:-vscode}" -install -d -o vscode -g vscode -m 0755 /var/log/dzhura -exec sudo -u vscode -H /usr/local/bin/start-dzhura.sh > /var/log/dzhura/start.log 2>&1 +: "${SERVICE_NAME:?}" + +install -d -o "${SERVICE_USER}" -g "${SERVICE_USER}" -m 0755 "/var/log/${SERVICE_NAME}" +exec sudo -u "${SERVICE_USER}" -H /usr/local/bin/start-service.sh > "/var/log/${SERVICE_NAME}/start.log" 2>&1 diff --git a/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/post-create.sh b/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/post-create.sh index b9ac87a8..0c6175e6 100755 --- a/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/post-create.sh +++ b/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/post-create.sh @@ -2,6 +2,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +: "${SERVICE_NAME:?}" + cd /usr/src/service || exit 1 if [ ! -f .npmrc.local ] || ! grep -q '//npm.pkg.github.com/:_authToken=' .npmrc.local; then @@ -18,4 +20,4 @@ else echo ".npmrc.local already exists and has an authentication token for npm.pkg.github.com" fi -sudo sv start dzhura +exec sudo sv start "${SERVICE_NAME}" diff --git a/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-dzhura.sh b/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-service.sh similarity index 86% rename from .devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-dzhura.sh rename to .devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-service.sh index 2a36d492..8ef79c62 100755 --- a/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-dzhura.sh +++ b/.devcontainer/.docker/dzhura/rootfs/usr/local/bin/start-service.sh @@ -2,6 +2,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +: "${SERVICE_NAME:?}" + cd /usr/src/service || exit 1 if [ ! -f src/specs/dzhura.yaml ] && [ -d .git ]; then @@ -23,4 +25,4 @@ fi npm run wait-for-mysql npx --no-install ts-node ./test/migrate.mts -npm run start:dev 2>&1 | tee -a /var/log/dzhura/dzhura.log +npm run start:dev 2>&1 | tee -a "/var/log/${SERVICE_NAME}/${SERVICE_NAME}.log" diff --git a/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/001-criminals.sql.xz b/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/001-criminals.sql.xz new file mode 100644 index 00000000..4b76fe45 Binary files /dev/null and b/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/001-criminals.sql.xz differ diff --git a/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/002-criminal_attachments.sql.xz b/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/002-criminal_attachments.sql.xz new file mode 100644 index 00000000..d5b6115b Binary files /dev/null and b/.devcontainer/.docker/mariadb/docker-entrypoint-initdb.d/002-criminal_attachments.sql.xz differ diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index fe8b566d..2dff83d8 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -4,19 +4,20 @@ services: context: .docker/dzhura dockerfile: Dockerfile environment: - NODE_ENV: development - NO_UPDATE_NOTIFIER: 'true' - NPM_CONFIG_FUND: '0' - SUPPRESS_SUPPORT: '1' - HTTPS: '0' - PORT: '3000' - ENABLE_TRACING: '1' - ZIPKIN_ENDPOINT: http://zipkin:9411/api/v2/spans - MYSQL_DATABASE: myrotvorets - MYSQL_USER: myro - MYSQL_PASSWORD: pass - MYSQL_HOST: mariadb - MYSQL_CONN_LIMIT: '3' + - NODE_ENV=development + - NO_UPDATE_NOTIFIER=true + - NPM_CONFIG_FUND=0 + - SUPPRESS_SUPPORT=1 + - HTTPS=0 + - PORT=3000 + - ENABLE_TRACING=1 + - OTEL_EXPORTER_ZIPKIN_ENDPOINT=http://zipkin:9411/api/v2/spans + - HAVE_SWAGGER=true + - MYSQL_DATABASE=myrotvorets + - MYSQL_USER=myro + - MYSQL_PASSWORD=pass + - MYSQL_HOST=mariadb + - MYSQL_CONN_LIMIT=3 restart: always volumes: - "../:/usr/src/service" @@ -25,19 +26,20 @@ services: mariadb: image: mariadb:11@sha256:5d851e999b84625ef9810589e832686cae58453452698ee69e2980041e626eb2 environment: - MYSQL_ROOT_PASSWORD: password - MYSQL_ROOT_HOST: '%' - MYSQL_DATABASE: myrotvorets - MYSQL_USER: myro - MYSQL_PASSWORD: pass + - MYSQL_ROOT_PASSWORD=password + - MYSQL_ROOT_HOST=% + - MYSQL_DATABASE=myrotvorets + - MYSQL_USER=myro + - MYSQL_PASSWORD=pass restart: always volumes: - mysql_data:/var/lib/mysql + - ./.docker/mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d adminer: image: adminer:latest@sha256:40c1d6691703a8ca102dc108c4a6fc11863e928b6ae6014fb8557b6e083a29ff environment: - ADMINER_DEFAULT_SERVER: mariadb + - ADMINER_DEFAULT_SERVER=mariadb restart: always zipkin: @@ -47,8 +49,14 @@ services: swagger: image: swaggerapi/swagger-ui:latest@sha256:c17153d23b81490d9b1d56bb26448b44b2fd43e46e8656ccb6af34eceb291a79 environment: - SWAGGER_JSON_URL: /specs/dzhura.yaml - BASE_URL: /swagger + - SWAGGER_JSON_URL=/specs/dzhura.yaml + - BASE_URL=/swagger + - DISPLAY_REQUEST_DURATION=true + - DEFAULT_MODELS_EXPAND_DEPTH=100 + - DEFAULT_MODEL_EXPAND_DEPTH=100 + - DEEP_LINKING=true + - VALIDATOR_URL=none + restart: always volumes: mysql_data: diff --git a/src/server.mts b/src/server.mts index ded882e7..4191749c 100644 --- a/src/server.mts +++ b/src/server.mts @@ -16,23 +16,26 @@ import { monitoringController } from './controllers/monitoring.mjs'; export async function configureApp(app: Express): Promise { const env = environment(); + const base = dirname(fileURLToPath(import.meta.url)); - if (env.NODE_ENV !== 'production') { - app.use( - '/specs/', - staticMiddleware(join(dirname(fileURLToPath(import.meta.url)), 'specs'), { - acceptRanges: false, - index: false, - }), - ); - } + await installOpenApiValidator(join(base, 'specs', 'dzhura.yaml'), app, env.NODE_ENV, { + ignorePaths: /^(\/$|\/specs\/)/u, + }); - await installOpenApiValidator( - join(dirname(fileURLToPath(import.meta.url)), 'specs', 'dzhura.yaml'), - app, - env.NODE_ENV, + app.use( + '/specs/', + staticMiddleware(join(base, 'specs'), { + acceptRanges: false, + index: false, + }), ); + /* c8 ignore start */ + if (process.env.HAVE_SWAGGER === 'true') { + app.get('/', (_req, res) => res.redirect('/swagger/')); + } + /* c8 ignore stop */ + app.use('/', searchController()); app.use('/', notFoundMiddleware); app.use(errorMiddleware);