deploy(backend): add prod Dockerfiles, compose stack, nginx configs, deploy scripts
Multi-stage Dockerfiles for accounts-service/configs-service/gateway, a docker-compose.prod.yml wiring fresh Postgres+MinIO+the three services on a private network, nginx site templates for visual.loki-code.dev (static SPA + /api proxy) and bekend.loki-code.dev (full gateway proxy for the mod), and idempotent setup.sh/deploy.sh scripts for the VDS. Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
This commit is contained in:
parent
484adaaf52
commit
2735a1c161
9 changed files with 263 additions and 0 deletions
19
backend/accounts-service/Dockerfile
Normal file
19
backend/accounts-service/Dockerfile
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Build context must be backend/ (the workspace root).
|
||||||
|
FROM rust:1-slim AS builder
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
protobuf-compiler pkg-config libssl-dev ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /build
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
COPY common ./common
|
||||||
|
COPY accounts-service ./accounts-service
|
||||||
|
COPY gateway ./gateway
|
||||||
|
COPY configs-service ./configs-service
|
||||||
|
RUN cargo build --release -p accounts-service
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates libssl3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /build/target/release/accounts-service /usr/local/bin/accounts-service
|
||||||
|
ENTRYPOINT ["/usr/local/bin/accounts-service"]
|
||||||
19
backend/configs-service/Dockerfile
Normal file
19
backend/configs-service/Dockerfile
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Build context must be backend/ (the workspace root).
|
||||||
|
FROM rust:1-slim AS builder
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
protobuf-compiler pkg-config libssl-dev ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /build
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
COPY common ./common
|
||||||
|
COPY accounts-service ./accounts-service
|
||||||
|
COPY gateway ./gateway
|
||||||
|
COPY configs-service ./configs-service
|
||||||
|
RUN cargo build --release -p configs-service
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates libssl3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /build/target/release/configs-service /usr/local/bin/configs-service
|
||||||
|
ENTRYPOINT ["/usr/local/bin/configs-service"]
|
||||||
29
backend/deploy/deploy.sh
Executable file
29
backend/deploy/deploy.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Idempotent redeploy for LoVisual. Run as: /opt/lovisual/deploy.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR=/opt/lovisual
|
||||||
|
FRONTEND_ROOT=/var/www/visual.loki-code.dev/html
|
||||||
|
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
git pull --ff-only
|
||||||
|
|
||||||
|
echo "==> Building & (re)starting backend services"
|
||||||
|
cd "$REPO_DIR/backend"
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
|
||||||
|
echo "==> Building frontend"
|
||||||
|
cd "$REPO_DIR/frontend"
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
echo "==> Syncing frontend build to $FRONTEND_ROOT"
|
||||||
|
mkdir -p "$FRONTEND_ROOT"
|
||||||
|
rsync -a --delete dist/ "$FRONTEND_ROOT/"
|
||||||
|
|
||||||
|
echo "==> Reloading nginx"
|
||||||
|
nginx -t
|
||||||
|
systemctl reload nginx
|
||||||
|
|
||||||
|
echo "==> Done"
|
||||||
|
docker compose -f "$REPO_DIR/backend/docker-compose.prod.yml" ps
|
||||||
14
backend/deploy/nginx-bekend.loki-code.dev.conf
Normal file
14
backend/deploy/nginx-bekend.loki-code.dev.conf
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
server {
|
||||||
|
server_name bekend.loki-code.dev;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
}
|
||||||
20
backend/deploy/nginx-visual.loki-code.dev.conf
Normal file
20
backend/deploy/nginx-visual.loki-code.dev.conf
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
server {
|
||||||
|
server_name visual.loki-code.dev;
|
||||||
|
root /var/www/visual.loki-code.dev/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
}
|
||||||
6
backend/deploy/pg-init/01-create-databases.sh
Executable file
6
backend/deploy/pg-init/01-create-databases.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "postgres" <<-EOSQL
|
||||||
|
SELECT 'CREATE DATABASE accounts_db OWNER lovisual' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'accounts_db')\gexec
|
||||||
|
SELECT 'CREATE DATABASE configs_db OWNER lovisual' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'configs_db')\gexec
|
||||||
|
EOSQL
|
||||||
22
backend/deploy/setup.sh
Executable file
22
backend/deploy/setup.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# One-time first-install setup for LoVisual on this VDS. Safe to re-run.
|
||||||
|
# Assumes: repo already cloned to /opt/lovisual, backend/.env already created (chmod 600).
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR=/opt/lovisual
|
||||||
|
|
||||||
|
echo "==> nginx site configs"
|
||||||
|
cp "$REPO_DIR/backend/deploy/nginx-visual.loki-code.dev.conf" /etc/nginx/sites-available/visual.loki-code.dev
|
||||||
|
cp "$REPO_DIR/backend/deploy/nginx-bekend.loki-code.dev.conf" /etc/nginx/sites-available/bekend.loki-code.dev
|
||||||
|
ln -sf /etc/nginx/sites-available/visual.loki-code.dev /etc/nginx/sites-enabled/visual.loki-code.dev
|
||||||
|
ln -sf /etc/nginx/sites-available/bekend.loki-code.dev /etc/nginx/sites-enabled/bekend.loki-code.dev
|
||||||
|
mkdir -p /var/www/visual.loki-code.dev/html
|
||||||
|
nginx -t
|
||||||
|
systemctl reload nginx
|
||||||
|
|
||||||
|
echo "==> certbot"
|
||||||
|
certbot --nginx -d visual.loki-code.dev --non-interactive --agree-tos -m mauhhhh7@gmail.com --redirect || true
|
||||||
|
certbot --nginx -d bekend.loki-code.dev --non-interactive --agree-tos -m mauhhhh7@gmail.com --redirect || true
|
||||||
|
|
||||||
|
echo "==> First deploy"
|
||||||
|
"$REPO_DIR/backend/deploy/deploy.sh"
|
||||||
115
backend/docker-compose.prod.yml
Normal file
115
backend/docker-compose.prod.yml
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
name: lovisual
|
||||||
|
|
||||||
|
networks:
|
||||||
|
lovisual-internal:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
lovisual-pg-data:
|
||||||
|
lovisual-minio-data:
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: lovisual
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB: postgres
|
||||||
|
volumes:
|
||||||
|
- lovisual-pg-data:/var/lib/postgresql/data
|
||||||
|
- ./deploy/pg-init:/docker-entrypoint-initdb.d:ro
|
||||||
|
networks: [lovisual-internal]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U lovisual"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
minio:
|
||||||
|
image: minio/minio
|
||||||
|
restart: unless-stopped
|
||||||
|
command: server /data
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${S3_ACCESS_KEY}
|
||||||
|
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
|
||||||
|
volumes:
|
||||||
|
- lovisual-minio-data:/data
|
||||||
|
networks: [lovisual-internal]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
minio-init:
|
||||||
|
image: minio/mc
|
||||||
|
depends_on:
|
||||||
|
minio:
|
||||||
|
condition: service_healthy
|
||||||
|
networks: [lovisual-internal]
|
||||||
|
entrypoint: >
|
||||||
|
/bin/sh -c "
|
||||||
|
mc alias set local http://minio:9000 $${S3_ACCESS_KEY} $${S3_SECRET_KEY} &&
|
||||||
|
(mc mb local/$${S3_BUCKET} || true) &&
|
||||||
|
echo bucket-ready
|
||||||
|
"
|
||||||
|
environment:
|
||||||
|
S3_ACCESS_KEY: ${S3_ACCESS_KEY}
|
||||||
|
S3_SECRET_KEY: ${S3_SECRET_KEY}
|
||||||
|
S3_BUCKET: ${S3_BUCKET}
|
||||||
|
|
||||||
|
accounts-service:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: accounts-service/Dockerfile
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
minio-init:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgres://lovisual:${POSTGRES_PASSWORD}@postgres:5432/accounts_db
|
||||||
|
S3_ENDPOINT: http://minio:9000
|
||||||
|
PORT: 8081
|
||||||
|
GRPC_PORT: 50051
|
||||||
|
networks: [lovisual-internal]
|
||||||
|
|
||||||
|
configs-service:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: configs-service/Dockerfile
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
accounts-service:
|
||||||
|
condition: service_started
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
CONFIGS_DATABASE_URL: postgres://lovisual:${POSTGRES_PASSWORD}@postgres:5432/configs_db
|
||||||
|
ACCOUNTS_GRPC_URL: http://accounts-service:50051
|
||||||
|
CONFIGS_PORT: 8082
|
||||||
|
networks: [lovisual-internal]
|
||||||
|
|
||||||
|
gateway:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: gateway/Dockerfile
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
accounts-service:
|
||||||
|
condition: service_started
|
||||||
|
configs-service:
|
||||||
|
condition: service_started
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
GATEWAY_PORT: 8080
|
||||||
|
ACCOUNTS_HTTP_URL: http://accounts-service:8081
|
||||||
|
ACCOUNTS_GRPC_URL: http://accounts-service:50051
|
||||||
|
CONFIGS_HTTP_URL: http://configs-service:8082
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8080:8080"
|
||||||
|
networks: [lovisual-internal]
|
||||||
19
backend/gateway/Dockerfile
Normal file
19
backend/gateway/Dockerfile
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Build context must be backend/ (the workspace root).
|
||||||
|
FROM rust:1-slim AS builder
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
protobuf-compiler pkg-config libssl-dev ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /build
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
COPY common ./common
|
||||||
|
COPY accounts-service ./accounts-service
|
||||||
|
COPY gateway ./gateway
|
||||||
|
COPY configs-service ./configs-service
|
||||||
|
RUN cargo build --release -p gateway
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates libssl3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /build/target/release/gateway /usr/local/bin/gateway
|
||||||
|
ENTRYPOINT ["/usr/local/bin/gateway"]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue