diff options
| author | Arseney300 <Arseney300@gmail.com> | 2026-02-20 10:43:41 +0700 |
|---|---|---|
| committer | Arseney300 <Arseney300@gmail.com> | 2026-02-20 10:43:41 +0700 |
| commit | e702989894c4e2a2e0a910cdc071e565fceadef8 (patch) | |
| tree | 579b27c8ebaab3c19819b2771cf1d97aa5385464 | |
| parent | fd82abff82e8c2f71bfcdb3330849ba7b520b798 (diff) | |
Add Gerrit code review service to git-server stack
Gerrit joins git-network (repo access) and jenkins_network (build triggers),
uses the official gerritcodereview/gerrit image with persistent storage under
/var/gerrit, and is reverse-proxied via nginx at gerrit.swave.lol and
swave.lol/gerrit. Updated certbot, setup guide, and project docs accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| -rw-r--r-- | CLAUDE.md | 18 | ||||
| -rw-r--r-- | doc/setup-guide.md | 51 | ||||
| -rw-r--r-- | git-server/server.yaml | 18 | ||||
| -rw-r--r-- | nginx/nginx.conf | 51 | ||||
| -rw-r--r-- | nginx/run_certbot.sh | 3 |
5 files changed, 125 insertions, 16 deletions
@@ -5,7 +5,7 @@ Bastion is a self-hosted server system on Debian that runs multiple services in ## Domain - Primary domain: `swave.lol` -- Subdomains: `blog.swave.lol`, `jenkins.swave.lol`, `cgit.swave.lol` +- Subdomains: `blog.swave.lol`, `jenkins.swave.lol`, `cgit.swave.lol`, `gerrit.swave.lol` ## Services / Stacks @@ -39,6 +39,15 @@ Bastion is a self-hosted server system on Debian that runs multiple services in - No host ports (accessed only via main nginx reverse proxy) - Accessible at `https://cgit.swave.lol` and `https://swave.lol/cgit` +### Gerrit (code review) +- Part of `git-server/server.yaml` compose stack +- Image: `gerritcodereview/gerrit:latest` (no custom Dockerfile) +- Networks: `git-network` (static IP 172.22.0.4) and `jenkins_network` +- Web UI on port 8080 internally, SSH on 29418 +- No host ports (accessed only via main nginx reverse proxy) +- Volumes: `/var/gerrit` (etc, git, db, index, cache), shared `/var/git/repos` +- Accessible at `https://gerrit.swave.lol` and `https://swave.lol/gerrit` + ### Jenkins - Dir: `jenkins/` - Compose: `jenkins/docker-compose.yaml`, builds from `jenkins/Dockerfile` @@ -62,16 +71,17 @@ Bastion is a self-hosted server system on Debian that runs multiple services in ## Networking Each stack has its own Docker network. Nginx joins all of them to reverse proxy: -- `git-network` — git-server + cgit + nginx +- `git-network` — git-server + cgit + gerrit + nginx - `ghost_network` — ghost + ghost-db + nginx -- `jenkins_network` — jenkins + nginx +- `jenkins_network` — jenkins + gerrit + nginx ## Startup Order 1. Portainer (standalone) 2. Git Server (creates git-network) 3. Ghost (creates ghost_network) 4. Jenkins (creates jenkins_network) -5. Nginx (joins all networks, must be last) +5. Gerrit (joins git-network + jenkins_network, both must exist) +6. Nginx (joins all networks, must be last) ## Key Files - `doc/setup-guide.md` — full build instructions from fresh Debian diff --git a/doc/setup-guide.md b/doc/setup-guide.md index 40cff8d..3b1b5f4 100644 --- a/doc/setup-guide.md +++ b/doc/setup-guide.md @@ -11,6 +11,7 @@ Full instruction to build the server from a fresh Debian installation. - `blog.swave.lol` - `jenkins.swave.lol` - `cgit.swave.lol` + - `gerrit.swave.lol` ## 1. Install Docker @@ -199,12 +200,34 @@ pipeline { See `doc/Jenkinsfile.example` for a full multi-stage example. -## 7. Nginx (Reverse Proxy + SSL) +## 7. Gerrit (Code Review) -Nginx must be started AFTER Git Server, Ghost, and Jenkins, because it joins +### 7.1 Create host directories + +```bash +mkdir -p /var/gerrit/{etc,git,db,index,cache} +chown -R 1000:1000 /var/gerrit # gerrit user inside container runs as UID 1000 +``` + +### 7.2 Start Gerrit + +Gerrit is part of the git-server stack. It requires `jenkins_network` to exist, +so Jenkins must be started first. + +```bash +cd /root/Projects/bastion/git-server +docker compose -f server.yaml up -d gerrit +``` + +Gerrit shares `/var/git/repos` with git-server for repository access. + + +## 8. Nginx (Reverse Proxy + SSL) + +Nginx must be started AFTER Git Server, Ghost, Jenkins, and Gerrit, because it joins their networks as external. -### 7.1 Create host directories +### 8.1 Create host directories ```bash # Nginx config directory @@ -225,7 +248,7 @@ mkdir -p /var/letsencrypt/lts_site cp /root/Projects/bastion/nginx/letsencrypt/index.html /var/letsencrypt/lts_site/ ``` -### 7.2 First run — HTTP only (no SSL yet) +### 8.2 First run — HTTP only (no SSL yet) Before we have SSL certificates, we need to temporarily disable the SSL server blocks so Nginx can start and serve the ACME challenge for certbot. @@ -244,7 +267,7 @@ cd /root/Projects/bastion/nginx docker compose up -d ``` -### 7.3 Obtain SSL certificates +### 8.3 Obtain SSL certificates ```bash cd /root/Projects/bastion/nginx @@ -256,10 +279,11 @@ This requests certificates for: - `blog.swave.lol` - `jenkins.swave.lol` - `cgit.swave.lol` +- `gerrit.swave.lol` IMPORTANT: All DNS records must be pointing to the server before running certbot. -### 7.4 Enable SSL +### 8.4 Enable SSL ```bash # Restore full nginx.conf with SSL blocks @@ -270,7 +294,7 @@ cd /root/Projects/bastion/nginx docker compose restart ``` -### 7.5 Verify +### 8.5 Verify All services should now be accessible: @@ -282,6 +306,8 @@ All services should now be accessible: | `https://jenkins.swave.lol` | Jenkins (subdomain) | | `https://swave.lol/cgit` | Cgit (path-based) | | `https://cgit.swave.lol` | Cgit (subdomain) | +| `https://swave.lol/gerrit` | Gerrit (path-based) | +| `https://gerrit.swave.lol` | Gerrit (subdomain) | | `http://<server-ip>:9000` | Portainer | | `ssh://git@<server-ip>/repos/<repo>.git` | Git (SSH) | | `git://<server-ip>/<repo>.git` | Git (daemon, read-only) | @@ -292,8 +318,9 @@ All services should now be accessible: ``` git-network (172.22.0.0/16) ├── git-server (172.22.0.2) -├── cgit -└── nginx (172.22.0.254) +├── cgit (172.22.0.3) +├── gerrit (172.22.0.4) +└── nginx (172.22.0.254) ghost_network ├── ghost @@ -303,6 +330,7 @@ ghost_network jenkins_network ├── jenkins +├── gerrit └── nginx ``` @@ -329,7 +357,10 @@ docker compose -f /root/Projects/bastion/ghost/compose.yml up -d # 4. Jenkins (creates jenkins_network) docker compose -f /root/Projects/bastion/jenkins/docker-compose.yaml up -d -# 5. Nginx (joins all networks — must be last) +# 5. Gerrit (joins git-network + jenkins_network, both must exist) +docker compose -f /root/Projects/bastion/git-server/server.yaml up -d gerrit + +# 6. Nginx (joins all networks — must be last) docker compose -f /root/Projects/bastion/nginx/docker-compose.yaml up -d ``` diff --git a/git-server/server.yaml b/git-server/server.yaml index 0f31bc1..d05436c 100644 --- a/git-server/server.yaml +++ b/git-server/server.yaml @@ -28,6 +28,22 @@ services: git-network: ipv4_address: 172.22.0.3 + gerrit: + image: gerritcodereview/gerrit:latest + restart: always + container_name: gerrit + volumes: + - /var/gerrit/etc:/var/gerrit/etc + - /var/gerrit/git:/var/gerrit/git + - /var/gerrit/db:/var/gerrit/db + - /var/gerrit/index:/var/gerrit/index + - /var/gerrit/cache:/var/gerrit/cache + - /var/git/repos:/var/gerrit/git:rw + networks: + git-network: + ipv4_address: 172.22.0.4 + jenkins_network: + networks: git-network: @@ -37,3 +53,5 @@ networks: config: - subnet: 172.22.0.0/16 gateway: 172.22.0.1 + jenkins_network: + external: true diff --git a/nginx/nginx.conf b/nginx/nginx.conf index b110783..9afed4f 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -4,7 +4,7 @@ server { listen 80; listen [::]:80; - server_name swave.lol blog.swave.lol jenkins.swave.lol cgit.swave.lol; + server_name swave.lol blog.swave.lol jenkins.swave.lol cgit.swave.lol gerrit.swave.lol; location / { rewrite ^ https://$host$request_uri? permanent; @@ -62,6 +62,15 @@ server { proxy_set_header X-Forwarded-Proto $scheme; } + # Gerrit via path prefix on main domain + location /gerrit { + proxy_pass http://gerrit:8080/gerrit; + 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; + } + # Jenkins via path prefix on main domain location /jenkins { proxy_pass http://jenkins:8080/jenkins; @@ -160,3 +169,43 @@ server { proxy_set_header X-Forwarded-Proto $scheme; } } + +# Gerrit — gerrit.swave.lol +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name gerrit.swave.lol; + + server_tokens off; + + ssl_certificate /var/letsencrypt/etc/live/swave.lol/fullchain.pem; + ssl_certificate_key /var/letsencrypt/etc/live/swave.lol/privkey.pem; + + ssl_buffer_size 8k; + + ssl_dhparam /etc/ssl/certs/dhparam-2048.pem; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + + ssl_ecdh_curve secp384r1; + ssl_session_tickets off; + + # OCSP stapling + ssl_stapling on; + ssl_stapling_verify on; + resolver 8.8.8.8; + + charset utf-8; + + location / { + proxy_pass http://gerrit:8080; + 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; + } +} diff --git a/nginx/run_certbot.sh b/nginx/run_certbot.sh index d265cce..79cc681 100644 --- a/nginx/run_certbot.sh +++ b/nginx/run_certbot.sh @@ -21,4 +21,5 @@ docker run -it --rm \ -d $domain \ -d blog.$domain \ -d jenkins.$domain \ - -d cgit.$domain + -d cgit.$domain \ + -d gerrit.$domain |
