A fully open-source, self-hosted DevOps platform using Docker Compose. Includes Git hosting, CI/CD, artifact storage, monitoring, security, and SSO.
| Service | Local URL | Purpose |
|---|---|---|
| Traefik | http://localhost:8080 | Reverse proxy & SSL |
| Authentik | http://localhost:9000 | Identity Provider (SSO) |
| Forgejo | http://localhost:3000 | Git Server |
| Woodpecker CI | http://localhost:8000 | Continuous Integration |
| Artipie | http://localhost:8081 | Artifact Repository |
| Grafana | http://localhost:3001 | Metrics & Dashboards |
| Prometheus | http://localhost:9090 | Metrics Collection |
| Uptime Kuma | http://localhost:3002 | Status Page |
┌─────────────────┐
│ Internet │
└────────┬────────┘
│
┌──────────────▼──────────────┐
│ Traefik (Reverse Proxy) │
│ :80 / :443 / CrowdSec │
└──────────────┬──────────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
│ Docker Network: devops-net │
│ │ │
┌───────▼───────┐ ┌───────────────▼───────────────┐ ┌───────▼───────┐
│ Authentik │ │ Core Services │ │ Monitoring │
│ (SSO/IdP) │ │ │ │ │
│ ├─Postgres │ │ Forgejo ──► Woodpecker │ │ Prometheus │
│ └─Redis │ │ │ │ │ │ Grafana │
└───────────────┘ │ │ │ │ │ Loki │
│ ▼ ▼ │ │ Promtail │
│ Postgres Agent(s) │ └───────────────┘
│ │
│ Artipie (Artifacts) │
└───────────────────────────────┘
- Docker and Docker Compose v2+
- 8GB RAM minimum (16GB recommended)
- 4 CPU cores recommended
- 50GB+ disk space
For production:
- Domain with DNS pointing to your server
- Ports 80, 443, and 2222 open
Run a single command to set up everything automatically:
./setup.shThis automatically:
- Generates secure random secrets and creates
.env - Starts the Docker Compose stack
- Waits for all services to become healthy
- Creates admin users (Forgejo, Uptime Kuma)
- Configures SSO between Forgejo and Authentik
- Sets up CrowdSec security bouncer
- Creates Woodpecker OAuth integration with Forgejo
- Configures Uptime Kuma monitoring
- Saves all credentials to
CREDENTIALS.md
Setup takes approximately 3-5 minutes depending on your system.
./setup.sh # Full automated setup
./setup.sh --force # Reset state and start fresh
./setup.sh --env-only # Generate .env only, don't start stack
./setup.sh --skip-stack # Configure existing running stack
./setup.sh --dry-run # Show what would be done without changes
./setup.sh --help # Show all optionsAccess your services:
| Service | URL | Default Credentials |
|---|---|---|
| Forgejo | http://localhost:3000 | See CREDENTIALS.md |
| Woodpecker | http://localhost:8000 | Login via Forgejo |
| Authentik | http://localhost:9000 | akadmin / see CREDENTIALS.md |
| Grafana | http://localhost:3001 | admin / see CREDENTIALS.md |
| Uptime Kuma | http://localhost:3002 | See CREDENTIALS.md |
If you prefer manual control:
# 1. Generate secrets only
./setup.sh --env-only
# 2. Edit .env if needed
nano .env
# 3. Start the stack
docker compose up -d
# 4. Configure services manually (see below)Authentik (http://localhost:9000):
- Navigate to
/if/flow/initial-setup/ - Username:
akadmin - Password: Value of
AUTHENTIK_BOOTSTRAP_PASSWORDfrom.env
Forgejo - Admin user is created automatically. To create manually:
docker exec -u git forgejo forgejo admin user create \
--admin --username admin --email admin@example.com \
--password YOUR_PASSWORD --must-change-password=falseWoodpecker OAuth - Configured automatically. To configure manually:
./scripts/setup-woodpecker-integration.shCrowdSec Bouncer - Configured automatically. To configure manually:
docker exec crowdsec cscli bouncers add traefik-bouncer
# Add the key to .env as CROWDSEC_BOUNCER_API_KEY
docker compose restart crowdsec-bouncerThe ./setup.sh script automatically configures SSO for all services:
- Forgejo ↔ Authentik: OpenID Connect integration
- Woodpecker ↔ Forgejo: OAuth2 for CI authentication
- Grafana ↔ Authentik: OAuth2 for dashboard access
All OAuth applications are created automatically via Authentik blueprints.
If you used --env-only or need to reconfigure:
# Forgejo SSO with Authentik
docker exec -u git forgejo forgejo admin auth add-oauth \
--name "Authentik" \
--provider "openidConnect" \
--key "$FORGEJO_OAUTH_CLIENT_ID" \
--secret "$FORGEJO_OAUTH_CLIENT_SECRET" \
--auto-discover-url "http://authentik-server:9000/application/o/forgejo/.well-known/openid-configuration" \
--scopes "openid profile email"Grafana OAuth is pre-configured in docker-compose.yml. Click "Sign in with Authentik" after Authentik is running.
./scripts/test-pipeline.shThis creates a test repository with a sample pipeline configuration.
# Get a token from Woodpecker UI first
WOODPECKER_TOKEN=your-token ./scripts/configure-woodpecker-secrets.shCreate .woodpecker.yaml in your repository:
when:
- event: push
steps:
- name: build
image: alpine:3.19
commands:
- echo "Building..."
- name: test
image: alpine:3.19
commands:
- echo "Testing..."steps:
- name: deploy
image: alpine:3.19
secrets: [artipie_user, artipie_password]
commands:
- echo "User: $ARTIPIE_USER"# Login
docker login localhost:8081
# Tag and push
docker tag myimage:latest localhost:8081/docker/myimage:latest
docker push localhost:8081/docker/myimage:latestAdd to pom.xml:
<repositories>
<repository>
<id>artipie</id>
<url>http://localhost:8081/maven</url>
</repository>
</repositories>npm config set registry http://localhost:8081/npm
npm login --registry=http://localhost:8081/npm
npm publishpip install --index-url http://localhost:8081/pypi/simple/ package-namePre-configured dashboards:
- Woodpecker CI: Pipeline metrics, worker status, logs
- System metrics via Node Exporter and cAdvisor
Access at http://localhost:3001
17 alerting rules are pre-configured in prometheus/alerts.yml:
| Category | Alerts |
|---|---|
| Service Health | ServiceDown, ServiceHighErrorRate |
| Container Health | CpuHigh, MemoryHigh, Restarting |
| Host Health | CpuLoad, Memory, DiskSpace |
| Applications | Forgejo, Woodpecker, Authentik down |
| SSL | Certificate expiration warnings |
View alerts: http://localhost:9090/alerts
Loki collects all container logs. Query in Grafana:
{container="forgejo"}
{container=~"woodpecker.*"}
Intrusion detection integrated with Traefik.
# Generate bouncer API key
docker exec crowdsec cscli bouncers add traefik-bouncer
# Add to .env and restart
docker compose restart crowdsec-bouncer
# View blocked IPs
docker exec crowdsec cscli decisions list
# Manual ban
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --reason "manual ban"docker compose --profile backup run --rm backupCreates PostgreSQL dumps and file backups using Restic.
Add to crontab (crontab -e):
0 2 * * * cd /path/to/devops-stack && docker compose --profile backup run --rm backup >> /var/log/backup.log 2>&1# List snapshots
docker run --rm -v devops-stack_backup-destination:/backups \
-e RESTIC_REPOSITORY=/backups \
-e RESTIC_PASSWORD=your-password \
restic/restic snapshots
# Restore
docker run --rm -v devops-stack_backup-destination:/backups \
-v devops-stack_forgejo-data:/restore \
-e RESTIC_REPOSITORY=/backups \
-e RESTIC_PASSWORD=your-password \
restic/restic restore latest --target /restore./tests/run-tests.sh./tests/test-stack.sh # Stack health tests
./tests/test-integration.sh # API integration tests
./tests/bootstrap.sh # Create test users/tokens- 43 stack health tests
- 18 integration tests
- Covers: containers, networking, APIs, OAuth, logging
docker compose logs -f # All services
docker compose logs -f forgejo # Specific servicedocker compose pull
docker compose up -ddocker statsdevops-stack/
├── docker-compose.yml # Main stack definition
├── .env # Configuration (gitignored)
├── .env.example # Configuration template
├── setup.sh # Zero-touch setup script
├── shell.nix # NixOS development shell
├── CREDENTIALS.md # Generated credentials (gitignored)
├── authentik/
│ └── blueprints/ # OAuth application configs
├── artipie/
│ └── repos/ # Repository configurations
├── grafana/
│ └── provisioning/ # Dashboards & datasources
├── prometheus/
│ ├── prometheus.yml # Scrape configuration
│ └── alerts.yml # Alerting rules
├── loki/ # Log aggregation config
├── traefik/ # Reverse proxy config
├── crowdsec/ # Security config
├── backup/ # Backup scripts
├── scripts/
│ ├── setup/ # Python setup package
│ │ ├── __main__.py # Main orchestration
│ │ ├── config.py # Configuration management
│ │ ├── secrets.py # Secret generation
│ │ ├── docker_utils.py # Docker helpers
│ │ └── services/ # Service configuration modules
│ ├── requirements.txt # Python dependencies
│ ├── configure-woodpecker-secrets.sh
│ └── test-pipeline.sh
└── tests/ # Test suites
├── run-tests.sh
├── test-stack.sh
├── test-integration.sh
└── bootstrap.sh
docker compose ps # Check status
docker compose logs <service> # Check logs
docker compose restart <service> # Restart service# Check PostgreSQL health
docker exec authentik-postgres pg_isready
docker exec forgejo-postgres pg_isready- Verify OAuth credentials in
.env - Check Woodpecker logs:
docker compose logs woodpecker-server - Ensure Forgejo is healthy:
docker compose ps forgejo
For production with real domains:
- Ensure DNS is configured correctly
- Check Traefik logs:
docker compose logs traefik - Verify ports 80/443 are accessible
This configuration is provided as-is for educational and personal use.