feat(deployment): update Semaphore stack and Traefik configuration
- Add QUICKSTART.md and SETUP_REPOSITORY.md for Semaphore stack - Add playbooks directory for Semaphore deployment - Update Semaphore docker-compose.yml, env.example, and README - Add Traefik local configuration files - Disable semaphore.yml in Traefik dynamic config - Update docker-compose.local.yml and build-image workflow
This commit is contained in:
@@ -16,6 +16,63 @@ Traefik acts as the central reverse proxy for all services, handling:
|
||||
- Zus?tzlich durch BasicAuth gesch?tzt
|
||||
- ?ffentlicher Zugriff ist blockiert
|
||||
|
||||
## Local Development
|
||||
|
||||
For local development, use the separate local configuration to avoid port conflicts and Let's Encrypt errors:
|
||||
|
||||
### Quick Start (Local Development)
|
||||
|
||||
```bash
|
||||
# Ensure Docker network exists
|
||||
docker network create traefik-public 2>/dev/null || true
|
||||
|
||||
# Start Traefik with local configuration
|
||||
cd deployment/stacks/traefik
|
||||
docker compose -f docker-compose.local.yml up -d
|
||||
|
||||
# Check logs
|
||||
docker compose -f docker-compose.local.yml logs -f
|
||||
|
||||
# Access dashboard at http://localhost:8080/dashboard/
|
||||
```
|
||||
|
||||
### Local Development Configuration
|
||||
|
||||
The local configuration (`docker-compose.local.yml` and `traefik.local.yml`) differs from production:
|
||||
|
||||
- **Bridge network** instead of `host` mode (avoids port conflicts)
|
||||
- **Port mappings**: `8080:80` only (HTTP-only for local development)
|
||||
- Note: HTTPS not needed locally - avoids port conflicts with web container (8443:443)
|
||||
- **HTTP-only** (no ACME/Let's Encrypt) for local development
|
||||
- **Dashboard**: Accessible at `http://localhost:8080/dashboard/` (HTTP, no authentication)
|
||||
- Also available: `http://localhost:8080/api/rawdata` and `http://localhost:8080/api/http/routers`
|
||||
- **No `acme.json`** required
|
||||
- **Console logging** (human-readable) instead of JSON file logs
|
||||
|
||||
### Local Development vs Production
|
||||
|
||||
| Feature | Local (`docker-compose.local.yml`) | Production (`docker-compose.yml`) |
|
||||
|---------|-----------------------------------|----------------------------------|
|
||||
| Network Mode | Bridge | Host |
|
||||
| Ports | 8080:80 (HTTP only) | Direct binding (80, 443) |
|
||||
| SSL/TLS | HTTP-only | HTTPS with Let's Encrypt |
|
||||
| Dashboard | `http://localhost:8080/dashboard/` | `https://traefik.michaelschiemer.de` |
|
||||
| Authentication | None (local dev) | VPN + BasicAuth |
|
||||
| Logging | Console (human-readable) | JSON files |
|
||||
| ACME | Disabled | Enabled |
|
||||
|
||||
### Troubleshooting Local Development
|
||||
|
||||
**Container restarts in loop:**
|
||||
- Check if port 8080 is already in use: `netstat -tlnp | grep ':8080' || ss -tlnp | grep ':8080'`
|
||||
- Verify Docker network exists: `docker network ls | grep traefik-public`
|
||||
- Check logs: `docker compose -f docker-compose.local.yml logs -f traefik`
|
||||
|
||||
**Services not accessible through Traefik:**
|
||||
- Ensure services are on `traefik-public` network
|
||||
- Verify Traefik labels are correctly configured
|
||||
- Check that services are running: `docker compose ps`
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Docker Network**
|
||||
|
||||
59
deployment/stacks/traefik/docker-compose.local.yml
Normal file
59
deployment/stacks/traefik/docker-compose.local.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
# Local Development Configuration for Traefik
|
||||
# Usage: docker compose -f docker-compose.local.yml up -d
|
||||
#
|
||||
# This configuration is optimized for local development:
|
||||
# - Bridge network instead of host mode
|
||||
# - Port mapping: 8080:80 (HTTP only - HTTPS not needed for local dev)
|
||||
# Note: 8443:443 is used by the web container, and we don't need HTTPS for Traefik locally
|
||||
# - No ACME/Let's Encrypt (HTTP-only)
|
||||
# - Simplified healthcheck
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.0
|
||||
container_name: traefik-local
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# Use bridge network for local development (avoids port conflicts)
|
||||
# Ports 80/443 might be in use by other services
|
||||
# For local development, we only use HTTP (no HTTPS needed)
|
||||
# Note: 8443:443 is used by the web container
|
||||
ports:
|
||||
- "8080:80" # HTTP on port 80 (mapped to host port 8080)
|
||||
- "8080:8080" # Traefik API entrypoint (for api.insecure=true dashboard)
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
volumes:
|
||||
# Docker socket for service discovery
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
# Static configuration for local development
|
||||
- ./traefik.local.yml:/traefik.yml:ro
|
||||
# Dynamic configuration (shared with production config)
|
||||
# Note: These configs reference letsencrypt resolver which we don't configure locally
|
||||
# This will cause harmless errors in logs but won't break functionality
|
||||
- ./dynamic:/dynamic:ro
|
||||
networks:
|
||||
- traefik-public
|
||||
labels:
|
||||
# Note: With api.insecure=true, Traefik should automatically serve the dashboard
|
||||
# at /dashboard/ and /api/ without needing router labels.
|
||||
# However, if this doesn't work in bridge network mode, we may need explicit routing.
|
||||
# For now, we'll try without labels and see if api.insecure=true works directly.
|
||||
- "traefik.enable=true"
|
||||
healthcheck:
|
||||
# Use wget or curl to check Traefik ping endpoint
|
||||
# The ping endpoint is configured in traefik.local.yml on the 'web' entrypoint
|
||||
# Try ping endpoint first, if that fails, try API endpoint
|
||||
test: ["CMD-SHELL", "wget --quiet --spider http://localhost:80/ping || wget --quiet --spider http://localhost:80/api/rawdata || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
# Create this network if it doesn't exist:
|
||||
# docker network create traefik-public
|
||||
|
||||
98
deployment/stacks/traefik/traefik.local.yml
Normal file
98
deployment/stacks/traefik/traefik.local.yml
Normal file
@@ -0,0 +1,98 @@
|
||||
# Local Development Configuration for Traefik
|
||||
# This configuration is optimized for local development without Let's Encrypt/ACME
|
||||
|
||||
# Global Configuration
|
||||
global:
|
||||
checkNewVersion: true
|
||||
sendAnonymousUsage: false
|
||||
|
||||
# API and Dashboard
|
||||
# For local development, we enable insecure access on port 8080
|
||||
# Dashboard automatically accessible at:
|
||||
# - http://localhost:8080/dashboard/ (with trailing slash)
|
||||
# - http://localhost:8080/api/rawdata
|
||||
# - http://localhost:8080/api/http/routers
|
||||
api:
|
||||
dashboard: true
|
||||
insecure: true # HTTP-only for local development - enables direct dashboard access
|
||||
# Note: With insecure=true, dashboard is accessible at:
|
||||
# - http://localhost:8080/dashboard/
|
||||
# - http://localhost:8080/api/rawdata
|
||||
# - http://localhost:8080/api/http/routers
|
||||
# The insecure mode works directly on the entrypoint (web) without needing router labels
|
||||
|
||||
# Entry Points
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
# No redirects for local development - HTTP is acceptable
|
||||
|
||||
websecure:
|
||||
address: ":443"
|
||||
# Note: Even though we don't use HTTPS locally, we need this entrypoint
|
||||
# because dynamic configurations (gitea.yml, semaphore.yml) reference it
|
||||
# We use HTTP only, but the entrypoint must exist to avoid errors
|
||||
|
||||
traefik:
|
||||
address: ":8080"
|
||||
# This entrypoint is used by api.insecure=true for dashboard access
|
||||
# It must be on port 8080 (which maps to host port 8080) to match our port mapping
|
||||
|
||||
# Certificate Resolvers
|
||||
# Note: For local development, we don't configure ACME/Let's Encrypt
|
||||
# Dynamic configs (gitea.yml, semaphore.yml) that reference letsencrypt will show errors
|
||||
# but won't break Traefik functionality. We can ignore these errors for local dev.
|
||||
# If you need to test with real certificates locally, configure ACME manually.
|
||||
# certificatesResolvers:
|
||||
# letsencrypt:
|
||||
# acme:
|
||||
# email: your-email@example.com
|
||||
# storage: /tmp/acme.json
|
||||
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
# Providers
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
exposedByDefault: false
|
||||
# Use Docker bridge network for local development
|
||||
network: traefik-public
|
||||
watch: true
|
||||
|
||||
file:
|
||||
directory: /dynamic
|
||||
watch: true
|
||||
# Note: Dynamic configs (gitea.yml, semaphore.yml) will show errors
|
||||
# because they reference letsencrypt resolver which we don't configure locally
|
||||
# These errors are harmless and won't affect local development
|
||||
|
||||
# Forwarded Headers Configuration
|
||||
# Simplified for local development
|
||||
forwardedHeaders:
|
||||
trustedIPs:
|
||||
- "127.0.0.1/32" # Localhost
|
||||
- "172.17.0.0/16" # Docker bridge network
|
||||
- "172.18.0.0/16" # Docker user-defined networks
|
||||
insecure: true # Allow insecure forwarded headers for local dev
|
||||
|
||||
# Logging - Console output for local development (easier to debug)
|
||||
log:
|
||||
level: INFO
|
||||
format: common # Human-readable format for local development
|
||||
|
||||
# Access Logs - Console output for local development
|
||||
accessLog:
|
||||
format: common # Human-readable format for local development
|
||||
|
||||
# Metrics (optional for local development)
|
||||
# Can be enabled if needed for monitoring
|
||||
# metrics:
|
||||
# prometheus:
|
||||
# addEntryPointsLabels: true
|
||||
# addRoutersLabels: true
|
||||
# addServicesLabels: true
|
||||
|
||||
# Ping endpoint for health checks
|
||||
ping:
|
||||
entryPoint: web
|
||||
|
||||
Reference in New Issue
Block a user