mirror of
https://github.com/terraphim/gitea-infrastructure.git
synced 2026-07-16 00:00:32 +02:00
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
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
# 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]
|
||||
Reference in New Issue
Block a user