diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 978ed5d..844e558 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -133,6 +133,4 @@ jobs: echo "Traefik: https://traefik.gate.${{ secrets.DOMAIN }}" echo "Portainer: https://portainer.gate.${{ secrets.DOMAIN }}" echo "Uptime Kuma: https://uptime.gate.${{ secrets.DOMAIN }}" - echo "Grafana: https://grafana.gate.${{ secrets.DOMAIN }}" - echo "Prometheus: https://prometheus.gate.${{ secrets.DOMAIN }}" echo "Umami: https://umami.gate.${{ secrets.DOMAIN }}" diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e6a4f4 --- /dev/null +++ b/README.md @@ -0,0 +1,371 @@ +# Launchpad Gateway + +A production-ready Traefik-based reverse proxy gateway with automatic SSL/TLS, analytics, monitoring, and container management. + +## 🚀 Features + +- **Automatic SSL/TLS** certificates via Let's Encrypt +- **Reverse Proxy** with Traefik v3.1 +- **Web Analytics** with Umami and PostgreSQL +- **Container Management** via Portainer +- **Uptime Monitoring** with Uptime Kuma +- **Security Headers** and Basic Authentication +- **Flexible Domain Routing** (subdomains, paths, custom rules) + +## 🏗️ Architecture + +``` +Internet → Traefik (Port 80/443) → Internal Services (traefik_proxy network) +``` + +### Current Services +- **Traefik Dashboard**: `traefik.gate.${DOMAIN}` - Reverse proxy management +- **Portainer**: `portainer.gate.${DOMAIN}` - Docker container management +- **Uptime Kuma**: `uptime.gate.${DOMAIN}` - Service monitoring +- **Umami Analytics**: `umami.gate.${DOMAIN}` - Web analytics dashboard + +## 🛠️ Quick Start + +### Prerequisites +- Docker and Docker Compose V2 installed (using `docker compose` command) +- Domain name with DNS pointing to your server +- Ports 80 and 443 open + +### 1. Setup Environment +```bash +# Clone the repository +git clone https://github.com/elfateh4/launchpad-gateway.git +cd launchpad-gateway + +# Copy environment file +cp .env.example .env + +# Edit your configuration +nano .env +``` + +### 2. Configure Environment Variables +Update `.env` with your settings: +```bash +# Domain and timezone +DOMAIN=your-domain.com +TZ=Your/Timezone + +# Let's Encrypt email +ACME_EMAIL=admin@your-domain.com + +# Basic auth (generate with: htpasswd -nB admin) +BASIC_AUTH_USERS=admin:$$2y$$05$$your_hashed_password + +# Database credentials +UMAMI_DB_USER=umami +UMAMI_DB_PASS=your_secure_password +UMAMI_DB_NAME=umami +UMAMI_APP_SECRET=your_64_character_secret +``` + + +### 3. Deploy the Gateway +```bash +docker compose up -d +``` + +### 4. Access Services +- **Traefik Dashboard**: `https://traefik.gate.your-domain.com` +- **Portainer**: `https://portainer.gate.your-domain.com` +- **Uptime Kuma**: `https://uptime.gate.your-domain.com` +- **Umami Analytics**: `https://umami.gate.your-domain.com` + +## 📋 Adding New Services + +### Domain Pattern Options + +Choose the best domain pattern for your service: + +| Pattern | Example | Best For | +|---------|---------|----------| +| **Root Domain** | `example.com` | Main application | +| **Direct Subdomain** | `app.example.com` | Standalone services | +| **Functional Subdomain** | `api.example.com`, `admin.example.com` | Role-based access | +| **Path-Based** | `example.com/api` | Microservices, APIs | +| **Environment-Based** | `staging.example.com` | Dev/staging environments | + +### Basic Service Template + +1. **Add volumes** (if needed) to the top of `docker-compose.yml`: +```yaml +volumes: + your_service_data: +``` + +2. **Add service** to the services section: +```yaml +your-service: + image: your-service:latest + container_name: your-service + restart: unless-stopped + networks: [traefik_proxy] + volumes: + - your_service_data:/app/data # if persistent storage needed + labels: + - traefik.enable=true + - traefik.http.routers.your-service.rule=Host(`app.${DOMAIN}`) + - traefik.http.routers.your-service.entrypoints=websecure + - traefik.http.routers.your-service.tls.certresolver=le + - traefik.http.routers.your-service.middlewares=security-headers + - traefik.http.services.your-service.loadbalancer.server.port=3000 +``` + +3. **Deploy the changes**: +```bash +docker compose up -d +``` + +## 🔧 Service Examples + +### WordPress Blog +**Add to networks:** +```yaml +networks: + traefik_proxy: + name: traefik_proxy + external: true + wordpress_network: + name: wordpress_network +``` + +**Add to volumes:** +```yaml +volumes: + wordpress_data: + wordpress_db_data: +``` + +**Add to services:** +```yaml +wordpress: + image: wordpress:latest + container_name: wordpress + restart: unless-stopped + networks: + - traefik_proxy # For Traefik access + - wordpress_network # For database access + environment: + WORDPRESS_DB_HOST: wordpress-db + WORDPRESS_DB_USER: ${WP_DB_USER} + WORDPRESS_DB_PASSWORD: ${WP_DB_PASS} + WORDPRESS_DB_NAME: ${WP_DB_NAME} + depends_on: [wordpress-db] + volumes: + - wordpress_data:/var/www/html + labels: + - traefik.enable=true + - traefik.http.routers.wordpress.rule=Host(`blog.${DOMAIN}`) + - traefik.http.routers.wordpress.entrypoints=websecure + - traefik.http.routers.wordpress.tls.certresolver=le + - traefik.http.routers.wordpress.middlewares=umami-analytics,security-headers + - traefik.http.services.wordpress.loadbalancer.server.port=80 + +wordpress-db: + image: mysql:8.0 + container_name: wordpress-db + restart: unless-stopped + networks: + - wordpress_network # Only on internal network + environment: + MYSQL_DATABASE: ${WP_DB_NAME} + MYSQL_USER: ${WP_DB_USER} + MYSQL_PASSWORD: ${WP_DB_PASS} + MYSQL_ROOT_PASSWORD: ${WP_DB_ROOT_PASS} + volumes: + - wordpress_db_data:/var/lib/mysql +``` + +### API Service with Path Routing +```yaml +api-service: + image: your-api:latest + container_name: api-service + restart: unless-stopped + networks: [traefik_proxy] + labels: + - traefik.enable=true + - traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`) + - traefik.http.routers.api.entrypoints=websecure + - traefik.http.routers.api.tls.certresolver=le + - traefik.http.routers.api.middlewares=security-headers + - traefik.http.services.api.loadbalancer.server.port=8000 +``` + +## 🔒 Security Features + +### Network Security Best Practices +- **Separate networks** for different service stacks +- **Only expose application containers** to `traefik_proxy` network +- **Keep databases isolated** on internal networks +- **Use multiple networks** for services that need both external and internal access + +### Network Architecture Example +```yaml +networks: + traefik_proxy: + external: true # For Traefik routing + app_network: + name: app_network # For app-specific services + db_network: + name: db_network # For database isolation + +services: + frontend: + networks: [traefik_proxy, app_network] # Accessible via Traefik + internal + + backend: + networks: [app_network, db_network] # Internal only + database access + + database: + networks: [db_network] # Database network only - not exposed +``` + +### Available Middlewares +- **`security-headers`**: HSTS, XSS protection, content type sniffing prevention +- **`basic-auth`**: HTTP Basic Authentication for admin interfaces +- **`umami-analytics`**: Automatic web analytics tracking + +### Usage Examples +```yaml +# Public application with analytics +- traefik.http.routers.app.middlewares=umami-analytics,security-headers + +# Admin interface with authentication +- traefik.http.routers.admin.middlewares=basic-auth,security-headers + +# API endpoint (security headers only) +- traefik.http.routers.api.middlewares=security-headers +``` + +## 🌐 Advanced Routing + +### Multiple Domains +```yaml +# Main app on root domain +- traefik.http.routers.main.rule=Host(`${DOMAIN}`) + +# API on subdomain +- traefik.http.routers.api.rule=Host(`api.${DOMAIN}`) + +# Admin with path +- traefik.http.routers.admin.rule=Host(`${DOMAIN}`) && PathPrefix(`/admin`) +``` + +### Environment-Based Routing +```yaml +# Production +- traefik.http.routers.app-prod.rule=Host(`app.${DOMAIN}`) + +# Staging (with basic auth) +- traefik.http.routers.app-staging.rule=Host(`staging.${DOMAIN}`) +- traefik.http.routers.app-staging.middlewares=basic-auth,security-headers +``` + +## 📊 Monitoring & Analytics + +### Built-in Monitoring +- **Uptime Kuma**: Service availability monitoring +- **Traefik Dashboard**: Traffic and routing metrics +- **Umami Analytics**: Web traffic analytics (privacy-focused) + +### Adding Services to Uptime Kuma +Uptime Kuma requires manual configuration through its web interface. After deploying a new service: + +1. **Access Uptime Kuma**: `https://uptime.gate.${DOMAIN}` +2. **Add New Monitor**: Click "Add New Monitor" +3. **Configure Monitor**: + - **Monitor Type**: HTTP(s) + - **Friendly Name**: Your Service Name + - **URL**: `https://your-service.${DOMAIN}` + - **Heartbeat Interval**: 60 seconds (recommended) + - **Max Retries**: 3 +4. **Save**: Click "Save" + +**Note**: The standard Uptime Kuma image does not support Docker label auto-discovery. All monitors must be configured manually through the web interface. + +## 🔧 Troubleshooting + +### Common Issues + +#### Service Not Accessible (404/502/503) +```bash +# Check service status +docker compose ps + +# Check service logs +docker compose logs your-service + +# Check Traefik logs +docker compose logs traefik + +# Verify network connectivity +docker exec traefik ping your-service +``` + +#### SSL Certificate Issues +```bash +# Check Let's Encrypt logs +docker compose logs traefik | grep -i acme + +# Verify DNS records +nslookup your-domain.com + +# Check certificate status +curl -I https://your-domain.com +``` + +#### Network Issues +```bash +# List networks +docker network ls + +# Create external network if missing +docker network create traefik_proxy + +# Inspect network +docker network inspect traefik_proxy +``` + +### Useful Commands +```bash +# View all services +docker compose ps + +# Follow logs for specific service +docker compose logs -f service-name + +# Restart specific service +docker compose restart service-name + +# Update and restart all services +docker compose pull && docker compose up -d + +# Check Traefik configuration +docker exec traefik traefik version +``` + +## 📚 Documentation + +### Key Files +- `docker-compose.yml`: Main service configuration +- `.env.example`: Environment variables +- `README.md`: This documentation + +### External Resources +- [Traefik Documentation](https://doc.traefik.io/traefik/) +- [Docker Compose Documentation](https://docs.docker.com/compose/) +- [Let's Encrypt Documentation](https://letsencrypt.org/docs/) + +## 🤝 Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly +5. Submit a pull request