Files
gitea-infrastructure/ARTICLE-gitea-deployment.md
Alex 4a4a0351aa feat: Gitea deployment with 1Password and Caddy
Complete infrastructure deployment including:
- Docker Compose templates with 1Password integration (op://)
- Caddy reverse proxy configuration for git.terraphim.cloud
- Automated deployment script (deploy-to-bigbox.sh)
- Comprehensive documentation and deployment article
- Network isolation: Public (Gitea) + Tailscale (Prometheus/S3)
- Security: No hardcoded secrets, all via 1Password

Services deployed:
- Gitea 1.22.6 (Git hosting)
- PostgreSQL 15 (Database)
- SeaweedFS (S3-compatible storage)
- Prometheus (Monitoring)

Excludes:
- docker-compose.yml (contains resolved secrets)
- s3_config.json (contains resolved secrets)
- Data directories (gitea/, postgres/, seaweedfs/)

Refs: Private deployment on bigbox with TerraphimPlatform vault
2026-02-16 19:40:19 +00:00

316 lines
9.7 KiB
Markdown

# Deploying Gitea with 1Password Secrets Management and Caddy on Bigbox
**Date:** February 16, 2026
**Author:** Infrastructure Team
**Tags:** gitea, 1password, caddy, docker, tailscale, devops
## Executive Summary
This article documents the deployment of a production-ready Gitea instance on bigbox server, featuring enterprise-grade security with 1Password secrets management, Caddy reverse proxy with automatic HTTPS, and network isolation via Tailscale.
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ Internet │
│ │ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ Caddy (bigbox) │ │
│ │ :443/:80 │ │
│ └──────────┬───────────┘ │
│ │ │
│ ┌──────────────┼──────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ workflows. git.terraphim. *.terraphim. │
│ terraphim. cloud (NEW) cloud │
│ cloud │ (catchall) │
│ ▼ │
│ ┌──────────────┐ │
│ │ Gitea │ │
│ │ :3000 │ │
│ └──────┬───────┘ │
│ │ │
└───────────────────┼─────────────────────────────────────────────┘
┌───────────┴───────────┐
│ Tailscale VPN │
│ (100.106.66.0/8) │
└───────────┬───────────┘
┌───────────┼───────────┐
▼ ▼ ▼
Prometheus S3 API SeaweedFS
:9000 :8333 (Internal)
```
## Key Features
### 1. Security-First Design
- **No hardcoded secrets** - All credentials stored in 1Password
- **1Password integration** - Secrets injected at runtime via `op inject`
- **Template-based configuration** - `.template` files in git, resolved configs excluded
- **Network isolation** - Internal services not exposed to internet
### 2. Multi-Layer Network Security
| Service | Exposure | Access Method |
|---------|----------|---------------|
| Gitea Web | Public | HTTPS via Caddy (git.terraphim.cloud) |
| Gitea SSH | Public | Port 222 direct |
| Prometheus | Tailscale only | http://100.106.66.7:9000 |
| S3 API | Tailscale only | http://100.106.66.7:8333 |
| PostgreSQL | Internal only | Docker network |
| SeaweedFS | Internal only | Docker network |
### 3. Technology Stack
- **Gitea 1.22.6** - Git hosting with Actions support
- **PostgreSQL 15** - Database
- **SeaweedFS** - Distributed S3-compatible object storage
- **Prometheus** - Metrics and monitoring
- **Caddy** - Reverse proxy with automatic HTTPS
- **1Password CLI** - Secrets management
- **Tailscale** - VPN for internal services
## Deployment Process
### Prerequisites
- SSH access to bigbox
- 1Password service account configured (`~/op_zesticai_non_prod.sh`)
- Caddy already running on bigbox
- Docker and Docker Compose installed
### Step 1: Create 1Password Vault Items
```bash
eval $(op signin)
# Create PostgreSQL credentials
op item create \
--vault="TerraphimPlatform" \
--category=login \
--title="gitea-postgres" \
--generate-password=20,letters,digits \
username=gitea
# Create S3 credentials
op item create \
--vault="TerraphimPlatform" \
--category=custom \
--title="gitea-s3" \
access-key="$(openssl rand -hex 20)" \
secret-key="$(openssl rand -hex 40)"
```
### Step 2: Template Configuration Files
Create `.template` files with 1Password references:
**docker-compose.yml.template:**
```yaml
version: "3"
services:
server:
image: gitea/gitea:1.22.6
environment:
- GITEA__database__PASSWD=op://TerraphimPlatform/gitea-postgres/password
- GITEA__storage__MINIO_ACCESS_KEY_ID=op://TerraphimPlatform/gitea-s3/access-key
- GITEA__storage__MINIO_SECRET_ACCESS_KEY=op://TerraphimPlatform/gitea-s3/secret-key
# ... other config
```
**s3_config.json.template:**
```json
{
"identities": [{
"name": "gitea",
"credentials": [{
"accessKey": "op://TerraphimPlatform/gitea-s3/access-key",
"secretKey": "op://TerraphimPlatform/gitea-s3/secret-key"
}]
}]
}
```
### Step 3: Inject Secrets and Deploy
```bash
# Source 1Password credentials
source ~/op_zesticai_non_prod.sh
# Inject secrets into configuration files
op inject --in-file docker-compose.yml.template --out-file docker-compose.yml
op inject --in-file s3_config.json.template --out-file s3_config.json
# Start services
docker compose up -d
```
### Step 4: Configure Caddy
Add Gitea route to existing Caddy instance:
```bash
# Add route via Caddy Admin API
curl -X POST http://localhost:2019/config/apps/http/servers/srv0/routes \
-H "Content-Type: application/json" \
-d '{
"@id": "gitea_route",
"match": [{"host": ["git.terraphim.cloud"]}],
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [{
"handler": "reverse_proxy",
"upstreams": [{"dial": "localhost:3000"}]
}]
}]
}],
"terminal": true
}'
```
**Important:** Route order matters! Add specific routes before wildcard routes.
## Network Configuration Details
### Port Bindings
**Gitea (Public):**
- `127.0.0.1:3000:3000` - HTTP via Caddy
- `0.0.0.0:222:22` - SSH direct access
**Prometheus (Tailscale only):**
- `100.106.66.7:9000:9090` - Only accessible via Tailscale
**S3 API (Tailscale only):**
- `100.106.66.7:8333:8333` - Only accessible via Tailscale
- `100.106.66.7:9327:9327` - Prometheus metrics
### Docker Compose Network Isolation
```yaml
networks:
gitea:
external: false # Internal Docker network only
services:
db:
networks:
- gitea # No external ports
master:
# No ports exposed - internal only
volume:
# No ports exposed - internal only
filer:
# No ports exposed - internal only
```
## Security Considerations
### 1. Secrets Management
- ✅ No secrets in Git repository
- ✅ No secrets in Docker images
- ✅ Secrets injected at runtime
- ✅ Easy rotation via 1Password
### 2. Network Security
- ✅ Public services behind Caddy with automatic HTTPS
- ✅ Internal services on Tailscale VPN
- ✅ Database isolated in Docker network
- ✅ SSH on non-standard port (222)
### 3. Access Control
- Prometheus and S3 require Tailscale connection
- Gitea accessible publicly via HTTPS
- SSH access available on port 222
## Troubleshooting
### Permission Denied Errors
If Gitea shows permission errors:
```bash
sudo chown -R 1000:1000 gitea/
sudo chmod -R 755 gitea/
docker compose restart server
```
### Route Not Working
Check Caddy route order:
```bash
curl -s http://localhost:2019/config/apps/http/servers/srv0/routes | \
jq '.[] | select(.match[0].host[0] | contains("terraphim")) | .match[0].host[0]'
```
Specific routes must come before wildcard routes.
### 1Password Authentication
Verify service account:
```bash
source ~/op_zesticai_non_prod.sh
op vault list
```
## Maintenance
### Backup
```bash
# Backup data directories
rsync -avz bigbox:~/gitea-stack/gitea ./backup/
rsync -avz bigbox:~/gitea-stack/postgres ./backup/
rsync -avz bigbox:~/gitea-stack/seaweedfs ./backup/
```
### Update Images
```bash
cd ~/gitea-stack
docker compose pull
docker compose up -d
```
### Rotate Secrets
1. Update in 1Password vault
2. Re-run deployment:
```bash
source ~/op_zesticai_non_prod.sh
op inject --in-file docker-compose.yml.template --out-file docker-compose.yml
docker compose up -d
```
## Access Points
### Public URLs
- **Gitea Web:** https://git.terraphim.cloud
- **Gitea SSH:** ssh://git@bigbox:222
### Tailscale-only URLs
Connect to Tailscale first: `tailscale up`
- **Prometheus:** http://100.106.66.7:9000
- **S3 API:** http://100.106.66.7:8333
## Conclusion
This deployment demonstrates production-ready practices:
- Zero hardcoded secrets
- Defense in depth with network isolation
- Automatic HTTPS via Caddy
- Easy maintenance with Docker Compose
- Centralized secrets management with 1Password
The architecture balances security (Tailscale isolation, 1Password integration) with usability (public HTTPS access to Gitea, direct SSH access).
## References
- [Gitea Documentation](https://docs.gitea.io/)
- [1Password CLI](https://developer.1password.com/docs/cli/)
- [Caddy Documentation](https://caddyserver.com/docs/)
- [Tailscale](https://tailscale.com/)
---
**Repository:** [Private terraphim repo with configuration]