mirror of
https://github.com/terraphim/gitea-infrastructure.git
synced 2026-07-16 00:00:32 +02:00
Automated fix from pre-commit hooks (trailing-whitespace, end-of-file-fixer). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
323 lines
13 KiB
Markdown
323 lines
13 KiB
Markdown
# Research Document: Gitea Deployment to Bigbox with 1Password Secrets Management
|
|
|
|
**Status**: Draft
|
|
**Author**: Claude
|
|
**Date**: 2026-02-16
|
|
**Reviewers**: [Pending]
|
|
|
|
## Executive Summary
|
|
|
|
This project deploys a comprehensive Gitea-based development infrastructure stack including Git hosting (Gitea), object storage (SeaweedFS), monitoring (Prometheus), and PostgreSQL database to a remote server called "bigbox". This deployment uses **1Password secrets management** via `op inject` to securely manage credentials and includes **Caddy reverse proxy** for SSL termination and routing. The environment is configured using the `op_zesticai_non_prod.sh` script for 1Password authentication.
|
|
|
|
## Essential Questions Check
|
|
|
|
| Question | Answer | Evidence |
|
|
|----------|--------|----------|
|
|
| Energizing? | Yes | Provides self-hosted Git infrastructure with production-grade secrets management |
|
|
| Leverages strengths? | Yes | Uses 1Password (already configured), Docker Compose patterns, SSH deployment |
|
|
| Meets real need? | Yes | Creates secure build machine with proper secrets management and reverse proxy |
|
|
|
|
**Proceed**: Yes - All 3 questions answered YES
|
|
|
|
## Problem Statement
|
|
|
|
### Description
|
|
Deploy a Gitea-based development infrastructure stack to a remote server (bigbox) using SSH with:
|
|
- **1Password secrets management** for all credentials (no hardcoded secrets)
|
|
- **Caddy reverse proxy** for SSL termination and routing
|
|
- **Secure credential injection** via `op inject`
|
|
- Environment authentication via `source op_zesticai_non_prod.sh`
|
|
|
|
The stack includes:
|
|
- Gitea (Git hosting with Actions support)
|
|
- PostgreSQL (database)
|
|
- SeaweedFS (distributed object storage with S3 API)
|
|
- Prometheus (monitoring)
|
|
- Caddy (reverse proxy with automatic HTTPS)
|
|
|
|
### Impact
|
|
Who is affected:
|
|
- Developers needing self-hosted Git repository management
|
|
- Teams requiring production-grade security with proper secrets management
|
|
- Projects needing S3-compatible object storage with secure credential handling
|
|
|
|
### Success Criteria
|
|
- [ ] All services start successfully on bigbox
|
|
- [ ] Gitea accessible via HTTPS (via Caddy reverse proxy)
|
|
- [ ] SeaweedFS S3 API accessible with secure credentials
|
|
- [ ] Prometheus monitoring accessible (via Caddy or directly)
|
|
- [ ] Data persistence across container restarts
|
|
- [ ] Services communicate properly within Docker network
|
|
- [ ] No hardcoded credentials in configuration files
|
|
- [ ] Caddy configured with proper reverse proxy rules
|
|
- [ ] 1Password secrets injected via `op inject`
|
|
|
|
## Current State Analysis
|
|
|
|
### Existing Implementation
|
|
The project uses Docker Compose with the following services:
|
|
|
|
| Component | Location | Purpose |
|
|
|-----------|----------|---------|
|
|
| Gitea | `docker-compose.yml:8` | Git hosting server with Actions and LFS support |
|
|
| PostgreSQL | `docker-compose.yml:46` | Database for Gitea |
|
|
| SeaweedFS Master | `docker-compose.yml:57` | Metadata management for distributed storage |
|
|
| SeaweedFS Volume | `docker-compose.yml:68` | Data storage nodes |
|
|
| SeaweedFS Filer | `docker-compose.yml:81` | File metadata and directory operations |
|
|
| SeaweedFS S3 | `docker-compose.yml:101` | S3-compatible API gateway |
|
|
| Prometheus | `docker-compose.yml:145` | Metrics collection and monitoring |
|
|
| **Caddy** | **NEW** | Reverse proxy with automatic HTTPS |
|
|
|
|
### Bigbox Environment Verified
|
|
- **1Password CLI**: Installed (`/usr/bin/op`)
|
|
- **1Password Service Account**: `~/op_zesticai_non_prod.sh` configured with `OP_SERVICE_ACCOUNT_TOKEN`
|
|
- **Docker**: 28.1.1 installed
|
|
- **Docker Compose**: v2.35.1 installed
|
|
- **Caddy**: Installed but no service configured
|
|
- **Hardware**: 125GB RAM, 3.5TB disk (367GB free)
|
|
|
|
### Secrets Management Architecture
|
|
```
|
|
1Password Vault (non-prod)
|
|
│
|
|
│ op inject
|
|
▼
|
|
op_zesticai_non_prod.sh ←── Export OP_SERVICE_ACCOUNT_TOKEN
|
|
│
|
|
▼
|
|
docker-compose.yml.template
|
|
│
|
|
│ op inject --in-file docker-compose.yml.template --out-file docker-compose.yml
|
|
▼
|
|
docker-compose.yml (secrets populated)
|
|
│
|
|
▼
|
|
Containers (receive secrets as environment variables)
|
|
```
|
|
|
|
### Data Flow
|
|
```
|
|
Internet ──▶ Caddy (:443/:80)
|
|
│
|
|
├──▶ Gitea (:3000)
|
|
│ └──▶ PostgreSQL (:5432)
|
|
│
|
|
├──▶ SeaweedFS S3 (:8333)
|
|
│ └──▶ Filer (:8888) ──▶ Master (:9333) + Volume (:8080)
|
|
│
|
|
└──▶ Prometheus (:9000)
|
|
```
|
|
|
|
### Integration Points
|
|
- Gitea uses SeaweedFS S3 for LFS and attachment storage
|
|
- Prometheus scrapes metrics from all SeaweedFS components
|
|
- Services communicate via internal Docker network "gitea"
|
|
- Caddy terminates SSL and routes to services
|
|
- 1Password injects secrets at deployment time
|
|
|
|
## Constraints
|
|
|
|
### Technical Constraints
|
|
- **Docker Compose Version**: Uses version 3 syntax
|
|
- **Container Images**: Fixed versions (gitea:1.22.6, postgres:15, prom/prometheus:v2.21.0)
|
|
- **SeaweedFS**: Uses "latest" tag (chrislusf/seaweedfs)
|
|
- **1Password CLI**: Must be available and authenticated via service account
|
|
- **Caddy**: Installed but needs configuration
|
|
- **Port Requirements**:
|
|
- 80/443 (Caddy - external)
|
|
- 3000 (Gitea HTTP - internal)
|
|
- 222 (Gitea SSH - external)
|
|
- 8333 (S3 API - internal or external via Caddy)
|
|
- 9000 (Prometheus - internal or external via Caddy)
|
|
|
|
### Security Constraints
|
|
- **No Hardcoded Secrets**: All credentials must come from 1Password
|
|
- **Service Account Authentication**: Must source `op_zesticai_non_prod.sh` before `op inject`
|
|
- **Template Files**: Use `.template` extension for files with 1Password references
|
|
- **Secret Rotation**: Support easy rotation via 1Password updates
|
|
|
|
### Non-Functional Requirements
|
|
| Requirement | Target | Current |
|
|
|-------------|--------|---------|
|
|
| Security | No hardcoded secrets | Hardcoded credentials exist |
|
|
| Secrets Management | 1Password integration | Not implemented |
|
|
| SSL/TLS | Automatic via Caddy | Not configured |
|
|
| Availability | 99% uptime | Not measured |
|
|
|
|
## Vital Few (Essentialism)
|
|
|
|
### Essential Constraints (Max 3)
|
|
| Constraint | Why It's Vital | Evidence |
|
|
|------------|----------------|----------|
|
|
| 1Password CLI and service account | Required for secrets injection | `/usr/bin/op` and `~/op_zesticai_non_prod.sh` verified |
|
|
| Caddy reverse proxy | SSL termination and routing | Production-grade deployment requirement |
|
|
| SSH Access to bigbox | Required for deployment | `ssh -G bigbox` confirms configuration |
|
|
|
|
### Eliminated from Scope
|
|
| Eliminated Item | Why Eliminated |
|
|
|-----------------|----------------|
|
|
| Gitea Runners (TODO) | Listed as future work in README |
|
|
| Earthly Buildkit | Listed as future work in README |
|
|
| Nginx S3 Gateway | Caddy replaces this need |
|
|
| Panamax (crates mirror) | Commented out in compose file |
|
|
| Automated backups | Out of scope for initial deployment |
|
|
| Custom domain SSL certs | Caddy handles automatic HTTPS |
|
|
|
|
## Dependencies
|
|
|
|
### Internal Dependencies
|
|
| Dependency | Impact | Risk |
|
|
|------------|--------|------|
|
|
| Gitea | Depends on PostgreSQL and S3 | High - core service |
|
|
| SeaweedFS S3 | Depends on Filer, Volume, Master | High - storage layer |
|
|
| Caddy | Depends on all web services | High - external access |
|
|
| 1Password | Required for secrets injection | High - security dependency |
|
|
| Prometheus | Depends on all services | Low - monitoring only |
|
|
|
|
### External Dependencies
|
|
| Dependency | Version | Risk | Alternative |
|
|
|------------|---------|------|-------------|
|
|
| Gitea | 1.22.6 | Low | Upgrade path available |
|
|
| PostgreSQL | 15 | Low | Well established |
|
|
| SeaweedFS | latest | Medium | Version pinning recommended |
|
|
| Prometheus | v2.21.0 | Low | Established monitoring |
|
|
| Caddy | latest | Low | Stable reverse proxy |
|
|
| 1Password CLI | latest | Low | Enterprise secrets management |
|
|
|
|
## Risks and Unknowns
|
|
|
|
### Known Risks
|
|
| Risk | Likelihood | Impact | Mitigation |
|
|
|------|------------|--------|------------|
|
|
| 1Password authentication failure | Low | High | Verify service account token before deployment |
|
|
| Caddy configuration errors | Medium | High | Test config with `caddy validate` |
|
|
| Port conflicts on bigbox | Medium | High | Verify ports before deployment |
|
|
| Secrets injection failure | Low | High | Validate templates before deployment |
|
|
| SSL certificate issues | Low | Medium | Caddy handles automatically |
|
|
|
|
### Open Questions
|
|
1. What 1Password vault/items contain the required secrets? - [Need to document]
|
|
2. What domain/subdomain will Caddy use? - [Need to determine]
|
|
3. Are required ports available (80/443)? - [Port scan required]
|
|
4. Existing Caddy configuration on bigbox? - [Verified: none active]
|
|
|
|
### Assumptions Explicitly Stated
|
|
| Assumption | Basis | Risk if Wrong | Verified? |
|
|
|------------|-------|---------------|-----------|
|
|
| 1Password CLI available on bigbox | `/usr/bin/op` exists | Secrets injection fails | Yes |
|
|
| op_zesticai_non_prod.sh has valid token | File exists with token | Authentication fails | Yes (token present) |
|
|
| Caddy installed and working | `/usr/bin/caddy` exists | Reverse proxy fails | Yes |
|
|
| Docker is installed on bigbox | Docker 28.1.1 verified | Deployment fails | Yes |
|
|
| Sufficient disk space available | 367GB available verified | Out of space | Yes |
|
|
| Network ports are available | Not verified | Port conflicts | No |
|
|
|
|
### Multiple Interpretations Considered
|
|
| Interpretation | Implications | Why Chosen/Rejected |
|
|
|----------------|--------------|---------------------|
|
|
| 1Password Connect Server | Centralized secret serving | Rejected - adds infrastructure complexity |
|
|
| Docker Secrets | Native Docker secrets | Rejected - requires Swarm mode |
|
|
| op inject with templates | Simple, effective | Chosen - minimal complexity, works with Compose |
|
|
| Caddy with Docker Compose | Containerized Caddy | Alternative - but native Caddy is simpler |
|
|
|
|
## Research Findings
|
|
|
|
### Key Insights
|
|
1. **Production-Ready Security**: 1Password integration eliminates hardcoded credentials
|
|
2. **Caddy Simplification**: Automatic HTTPS eliminates SSL certificate management
|
|
3. **Service Account Auth**: `op_zesticai_non_prod.sh` provides secure 1Password access
|
|
4. **Template Pattern**: `.template` files with 1Password references enable secure deployment
|
|
5. **Complete Stack**: Full infrastructure with proper secrets management and reverse proxy
|
|
|
|
### 1Password Secrets Required
|
|
Based on current configuration, the following secrets must exist in 1Password:
|
|
|
|
| Secret | Purpose | Current Hardcoded Value |
|
|
|--------|---------|------------------------|
|
|
| `op://zesticai-non-prod/gitea-postgres/password` | PostgreSQL password | gitea |
|
|
| `op://zesticai-non-prod/gitea-s3/access-key` | S3 access key | REDACTED_S3_ACCESS_KEY |
|
|
| `op://zesticai-non-prod/gitea-s3/secret-key` | S3 secret key | REDACTED_S3_SECRET_KEY |
|
|
| `op://zesticai-non-prod/gitea-jwt/secret` | Gitea JWT secret | (not currently set) |
|
|
|
|
### Caddy Configuration Requirements
|
|
```caddyfile
|
|
# Caddyfile for gitea-stack
|
|
gitea.bigbox.example.com {
|
|
reverse_proxy localhost:3000
|
|
}
|
|
|
|
s3.bigbox.example.com {
|
|
reverse_proxy localhost:8333
|
|
}
|
|
|
|
prometheus.bigbox.example.com {
|
|
reverse_proxy localhost:9000
|
|
}
|
|
```
|
|
|
|
### Technical Spikes Needed
|
|
| Spike | Purpose | Estimated Effort |
|
|
|-------|---------|------------------|
|
|
| Verify 1Password vault structure | Confirm required secrets exist | 30 minutes |
|
|
| Test op inject workflow | Validate secrets injection | 30 minutes |
|
|
| Design Caddy configuration | Determine routing rules | 1 hour |
|
|
| Test Caddy with services | Validate reverse proxy | 1 hour |
|
|
|
|
## Recommendations
|
|
|
|
### Proceed/No-Proceed
|
|
**Proceed** - Bigbox has all required tools (1Password CLI, Docker, Caddy), and the 1Password service account is already configured.
|
|
|
|
### Scope Recommendations
|
|
1. **Phase 1**: Implement 1Password secrets management
|
|
2. **Phase 2**: Add Caddy reverse proxy configuration
|
|
3. **Phase 3**: Deploy and validate all services
|
|
|
|
### Risk Mitigation Recommendations
|
|
1. Test 1Password authentication before deployment
|
|
2. Validate Caddy configuration with `caddy validate`
|
|
3. Create backup of existing data before deployment
|
|
4. Use staging/test domain initially for SSL validation
|
|
5. Document all 1Password vault items required
|
|
|
|
## Next Steps
|
|
|
|
If approved:
|
|
1. Create 1Password vault items for all required secrets
|
|
2. Create Implementation Plan with 1Password and Caddy integration
|
|
3. Test `op inject` workflow locally
|
|
4. Execute deployment following plan
|
|
5. Validate all services and Caddy routing
|
|
|
|
## Appendix
|
|
|
|
### Reference Materials
|
|
- docker-compose.yml: Main deployment configuration
|
|
- s3_config.json: SeaweedFS S3 gateway credentials (to be replaced with 1Password)
|
|
- prometheus/prometheus.yml: Monitoring configuration
|
|
- README.md: Project overview and TODOs
|
|
- op_zesticai_non_prod.sh: 1Password service account configuration
|
|
|
|
### 1Password CLI Usage
|
|
```bash
|
|
# Source the service account token
|
|
source ~/op_zesticai_non_prod.sh
|
|
|
|
# Inject secrets into template
|
|
op inject --in-file docker-compose.yml.template --out-file docker-compose.yml
|
|
|
|
# Or run with op run
|
|
op run --env-file=.env -- docker compose up -d
|
|
```
|
|
|
|
### Caddy Commands
|
|
```bash
|
|
# Validate configuration
|
|
caddy validate --config /etc/caddy/Caddyfile
|
|
|
|
# Start Caddy (as service or directly)
|
|
sudo caddy run --config /etc/caddy/Caddyfile
|
|
|
|
# Reload configuration
|
|
sudo caddy reload --config /etc/caddy/Caddyfile
|
|
```
|