summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CLAUDE.md18
-rw-r--r--doc/setup-guide.md51
-rw-r--r--git-server/server.yaml18
-rw-r--r--nginx/nginx.conf51
-rw-r--r--nginx/run_certbot.sh3
5 files changed, 125 insertions, 16 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index f5f3916..aacd3e4 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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