From 6d497eb5d31b9dbad368f9dabe1f7efb21337eb6 Mon Sep 17 00:00:00 2001 From: "glm-5.1" Date: Thu, 11 Jun 2026 13:42:08 +0000 Subject: [PATCH] Add systemd unit, Dockerfile, docker-compose, and fail2ban configs for production deployment --- deploy/Dockerfile | 22 +++++++++ deploy/docker-compose.yml | 52 +++++++++++++++++++++ deploy/fail2ban/filter.d/reverse-proxy.conf | 3 ++ deploy/fail2ban/jail.d/reverse-proxy.conf | 7 +++ deploy/reverse-proxy.service | 24 ++++++++++ 5 files changed, 108 insertions(+) create mode 100644 deploy/Dockerfile create mode 100644 deploy/docker-compose.yml create mode 100644 deploy/fail2ban/filter.d/reverse-proxy.conf create mode 100644 deploy/fail2ban/jail.d/reverse-proxy.conf create mode 100644 deploy/reverse-proxy.service diff --git a/deploy/Dockerfile b/deploy/Dockerfile new file mode 100644 index 0000000..bf200cf --- /dev/null +++ b/deploy/Dockerfile @@ -0,0 +1,22 @@ +FROM rust:alpine AS builder + +RUN apk add --no-cache musl-dev + +WORKDIR /usr/src/reverse-proxy +COPY . . + +RUN cargo build --release --target x86_64-unknown-linux-musl + +FROM alpine:latest + +RUN apk add --no-cache ca-certificates + +COPY --from=builder /usr/src/reverse-proxy/target/x86_64-unknown-linux-musl/release/reverse-proxy /usr/local/bin/reverse-proxy + +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD wget -q --spider http://127.0.0.1:9900/health || exit 1 + +EXPOSE 80 443 + +ENTRYPOINT ["reverse-proxy"] +CMD ["--config", "/etc/reverse-proxy/config.toml"] \ No newline at end of file diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..de53f4e --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,52 @@ +services: + reverse-proxy: + build: . + container_name: reverse-proxy + restart: unless-stopped + ports: + - "203.0.113.10:80:80" + - "203.0.113.10:443:443" + volumes: + - /etc/reverse-proxy/config.toml:/etc/reverse-proxy/config.toml:ro + - /var/lib/reverse-proxy/acme-cache:/var/lib/reverse-proxy/acme-cache + - /var/log/reverse-proxy:/var/log/reverse-proxy + - /run/reverse-proxy:/run/reverse-proxy + networks: + - proxy-net + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:9900/health"] + interval: 30s + timeout: 5s + retries: 3 + + gitea: + image: gitea/gitea:latest + container_name: gitea + restart: unless-stopped + ports: + - "203.0.113.10:22:2222" + volumes: + - /opt/gitea:/data + networks: + - proxy-net + - gitea-db-net + + gitea-db: + image: postgres:16-alpine + container_name: gitea-db + restart: unless-stopped + environment: + POSTGRES_USER: admin + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: gitea + volumes: + - gitea-db:/var/lib/postgresql/data + networks: + - gitea-db-net + +networks: + proxy-net: + gitea-db-net: + +volumes: + gitea-db: \ No newline at end of file diff --git a/deploy/fail2ban/filter.d/reverse-proxy.conf b/deploy/fail2ban/filter.d/reverse-proxy.conf new file mode 100644 index 0000000..77fe452 --- /dev/null +++ b/deploy/fail2ban/filter.d/reverse-proxy.conf @@ -0,0 +1,3 @@ +[Definition] +failregex = ^RATE_LIMIT client_ip= host=\S+ path=\S+ status=\d+$ +ignoreregex = \ No newline at end of file diff --git a/deploy/fail2ban/jail.d/reverse-proxy.conf b/deploy/fail2ban/jail.d/reverse-proxy.conf new file mode 100644 index 0000000..71c5000 --- /dev/null +++ b/deploy/fail2ban/jail.d/reverse-proxy.conf @@ -0,0 +1,7 @@ +[reverse-proxy] +enabled = true +filter = reverse-proxy +logpath = /var/log/reverse-proxy/access.log +maxretry = 10 +findtime = 60 +bantime = 3600 \ No newline at end of file diff --git a/deploy/reverse-proxy.service b/deploy/reverse-proxy.service new file mode 100644 index 0000000..a44c238 --- /dev/null +++ b/deploy/reverse-proxy.service @@ -0,0 +1,24 @@ +[Unit] +Description=Reverse Proxy +After=network.target +Wants=network-online.target + +[Service] +Type=notify +NotifyAccess=all +ExecStart=/usr/local/bin/reverse-proxy --config /etc/reverse-proxy/config.toml +Restart=on-failure +RestartSec=5 + +# Security hardening +NoNewPrivileges=yes +ProtectSystem=strict +ProtectHome=yes +PrivateTmp=yes +ReadWritePaths=/var/lib/reverse-proxy /var/log/reverse-proxy + +# ACME challenge cache directory +StateDirectory=reverse-proxy + +[Install] +WantedBy=multi-user.target \ No newline at end of file