From a385b0540da3ac3f2a5b6af87913b0335d2d19d4 Mon Sep 17 00:00:00 2001 From: Priec Date: Wed, 20 May 2026 11:14:42 +0200 Subject: [PATCH] prod setup is now fully ready --- .dockerignore | 18 +++++++++++++ .env.production.example | 26 +++++++++++++++++++ .gitignore | 1 - Dockerfile | 24 +++++++++++++++++ Makefile | 20 +++++++++++++++ config/production.yaml | 57 +++++++++++++++++++++++++++++++++++++++++ docker-compose.prod.yml | 28 ++++++++++++++++++++ 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 .env.production.example create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 config/production.yaml create mode 100644 docker-compose.prod.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7e91b2d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +target +node_modules + +Dockerfile +.dockerignore +docker-compose.prod.yml +Makefile + +.git +.gitignore + +.env +.env.* +*.sqlite +*.sqlite-* + +uploads +*report.html diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..e5feb51 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,26 @@ +CONTAINER_NAME=universal-web +REVERSE_PROXY_NETWORK= +UPLOADS_VOLUME_NAME=universal_web_uploads + +APP_HOST= +PORT=5150 +SERVER_BINDING=0.0.0.0 + +DATABASE_URL= +JWT_SECRET= + +ADMIN_EMAIL= +ADMIN_PASSWORD= +ADMIN_NAME=Admin +UPLOADS_ROOT=data/uploads + +LOG_LEVEL=info +LOG_FORMAT=compact + +MAILER_STUB=true +SMTP_ENABLE=false +SMTP_HOST=localhost +SMTP_PORT=1025 +SMTP_SECURE=false +SMTP_USER= +SMTP_PASSWORD= diff --git a/.gitignore b/.gitignore index 3554139..4ba4193 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ **/config/local.yaml **/config/*.local.yaml -**/config/production.yaml # Generated by Cargo # will have compiled files and executables diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9d04fad --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM rust:1.87.0-slim-bookworm AS builder + +WORKDIR /usr/src + +COPY . . + +RUN cargo build --release --bin universal_web-cli + +FROM debian:bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates curl \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /usr/app + +COPY --from=builder /usr/src/assets assets +COPY --from=builder /usr/src/config config +COPY --from=builder /usr/src/target/release/universal_web-cli universal_web-cli + +ENV LOCO_ENV=production +EXPOSE 5150 +ENTRYPOINT ["/usr/app/universal_web-cli"] +CMD ["start"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6f6c87a --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +COMPOSE = docker compose -f docker-compose.prod.yml --env-file .env.production + +.PHONY: up down restart logs build ps + +up: + $(COMPOSE) up -d --build + +down: + $(COMPOSE) down + +restart: down up + +logs: + $(COMPOSE) logs -f --tail=100 + +build: + $(COMPOSE) build --no-cache + +ps: + $(COMPOSE) ps diff --git a/config/production.yaml b/config/production.yaml new file mode 100644 index 0000000..abac1a5 --- /dev/null +++ b/config/production.yaml @@ -0,0 +1,57 @@ +logger: + enable: true + pretty_backtrace: false + level: "{{ get_env(name="LOG_LEVEL", default="info") }}" + format: "{{ get_env(name="LOG_FORMAT", default="compact") }}" + +server: + port: {{ get_env(name="PORT", default="5150") }} + binding: "{{ get_env(name="SERVER_BINDING", default="0.0.0.0") }}" + host: "{{ get_env(name="APP_HOST") }}" + middlewares: + static: + enable: true + must_exist: true + precompressed: false + folder: + uri: "/static" + path: "assets/static" + fallback: "assets/static/404.html" + +workers: + mode: "{{ get_env(name="WORKER_MODE", default="BackgroundAsync") }}" + +mailer: + stub: {{ get_env(name="MAILER_STUB", default="true") }} + smtp: + enable: {{ get_env(name="SMTP_ENABLE", default="false") }} + host: "{{ get_env(name="SMTP_HOST", default="localhost") }}" + port: {{ get_env(name="SMTP_PORT", default="1025") }} + secure: {{ get_env(name="SMTP_SECURE", default="false") }} + auth: + user: "{{ get_env(name="SMTP_USER", default="") }}" + password: "{{ get_env(name="SMTP_PASSWORD", default="") }}" + +database: + uri: "{{ get_env(name="DATABASE_URL") }}" + enable_logging: {{ get_env(name="DB_ENABLE_LOGGING", default="false") }} + connect_timeout: {{ get_env(name="DB_CONNECT_TIMEOUT", default="500") }} + idle_timeout: {{ get_env(name="DB_IDLE_TIMEOUT", default="500") }} + min_connections: {{ get_env(name="DB_MIN_CONNECTIONS", default="1") }} + max_connections: {{ get_env(name="DB_MAX_CONNECTIONS", default="5") }} + auto_migrate: {{ get_env(name="DB_AUTO_MIGRATE", default="true") }} + dangerously_truncate: false + dangerously_recreate: false + +auth: + jwt: + location: + - from: Cookie + name: auth_token + - from: Bearer + secret: "{{ get_env(name="JWT_SECRET") }}" + expiration: {{ get_env(name="JWT_EXPIRATION", default="604800") }} + +settings: + admin_email: "{{ get_env(name="ADMIN_EMAIL", default="") }}" + uploads_root: "{{ get_env(name="UPLOADS_ROOT", default="data/uploads") }}" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..eed1a5a --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,28 @@ +services: + universal-web: + container_name: ${CONTAINER_NAME:?set CONTAINER_NAME} + build: + context: . + dockerfile: Dockerfile + env_file: + - .env.production + volumes: + - universal_web_uploads:/usr/app/data/uploads + networks: + - reverse-proxy + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://localhost:$${PORT:-5150}/_ping"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + +networks: + reverse-proxy: + external: true + name: ${REVERSE_PROXY_NETWORK:?set REVERSE_PROXY_NETWORK} + +volumes: + universal_web_uploads: + name: ${UPLOADS_VOLUME_NAME:?set UPLOADS_VOLUME_NAME}