2 Commits

Author SHA1 Message Date
Priec
f92cb1f134 caddyfile
Some checks failed
CI / Check Style (push) Has been cancelled
CI / Run Clippy (push) Has been cancelled
CI / Run Tests (push) Has been cancelled
2026-05-20 11:24:06 +02:00
Priec
a385b0540d prod setup is now fully ready 2026-05-20 11:14:42 +02:00
8 changed files with 191 additions and 1 deletions

19
.dockerignore Normal file
View File

@@ -0,0 +1,19 @@
target
node_modules
Dockerfile
.dockerignore
docker-compose.prod.yml
Makefile
Caddyfile
.git
.gitignore
.env
.env.*
*.sqlite
*.sqlite-*
uploads
*report.html

26
.env.production.example Normal file
View File

@@ -0,0 +1,26 @@
CONTAINER_NAME=universal-web
REVERSE_PROXY_NETWORK=
UPLOADS_VOLUME_NAME=universal_web_uploads
APP_HOST=https://gitara.farmeris.sk
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=

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
**/config/local.yaml
**/config/*.local.yaml
**/config/production.yaml
# Generated by Cargo
# will have compiled files and executables

17
Caddyfile Normal file
View File

@@ -0,0 +1,17 @@
# Reverse-proxy config for temp.sk.
#
# This file is intended to be imported by the central Caddyfile on the server.
# Caddy provisions and renews the HTTPS certificate automatically.
gitara.farmeris.sk {
encode gzip
@static path /static/*
header @static Cache-Control "public, max-age=2592000"
reverse_proxy universal-web:5150
}
www.gitara.farmeris.sk {
redir https://temp.sk{uri} permanent
}

24
Dockerfile Normal file
View File

@@ -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"]

20
Makefile Normal file
View File

@@ -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

57
config/production.yaml Normal file
View File

@@ -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") }}"

28
docker-compose.prod.yml Normal file
View File

@@ -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}