Files
launchpad-gateway/README.md
elfateh4 6f953a090d Add Duplicati backup service and update Authelia configuration
- Add Duplicati encrypted cloud backup service
- Add AUTHELIA_DB_NAME and AUTHELIA_DB_USER environment variables
- Add DUPLICATI_ENCRYPTION_KEY and DUPLICATI_PASSWORD to .env.example
- Update README.md with Duplicati documentation
- Configure Gitea with English-only language setting
2025-12-02 05:54:59 +01:00

407 lines
11 KiB
Markdown

# Launchpad Gateway
A production-ready Traefik-based reverse proxy gateway with automatic SSL/TLS, analytics, monitoring, authentication, and container management.
## 🚀 Features
- **Automatic SSL/TLS** certificates via Let's Encrypt
- **Reverse Proxy** with Traefik v3.1
- **Authentication** with Authelia (2FA, password reset)
- **Web Analytics** with Umami and PostgreSQL
- **Container Management** via Portainer
- **Uptime Monitoring** with Uptime Kuma
- **Server Monitoring** with Beszel
- **Git Repository Hosting** with Gitea
- **Encrypted Backups** with Duplicati
- **Security Headers** and Flexible Routing
- **Flexible Domain Routing** (subdomains, paths, custom rules)
## 🏗️ Architecture
```
Internet → Traefik (Port 80/443) → Authelia (Auth) → Internal Services (traefik_proxy network)
```
### Current Services
- **Traefik Dashboard**: `traefik.${DOMAIN_PREFIX}.${DOMAIN}` - Reverse proxy management
- **Authelia**: `auth.${DOMAIN_PREFIX}.${DOMAIN}` - Authentication portal
- **Portainer**: `portainer.${DOMAIN_PREFIX}.${DOMAIN}` - Docker container management
- **Uptime Kuma**: `uptime.${DOMAIN_PREFIX}.${DOMAIN}` - Service monitoring
- **Umami Analytics**: `umami.${DOMAIN_PREFIX}.${DOMAIN}` - Web analytics dashboard
- **pgAdmin**: `pgadmin.${DOMAIN_PREFIX}.${DOMAIN}` - PostgreSQL administration
- **Beszel**: `beszel.${DOMAIN_PREFIX}.${DOMAIN}` - Server monitoring
- **Gitea**: `git.${DOMAIN_PREFIX}.${DOMAIN}` - Self-hosted Git service (SSH on port 222)
- **Duplicati**: `backup.${DOMAIN_PREFIX}.${DOMAIN}` - Encrypted cloud backup
## 🛠️ 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
DOMAIN_PREFIX=test
TZ=Africa/Cairo
# Let's Encrypt email
ACME_EMAIL=admin@your-domain.com
# Database credentials
UMAMI_DB_USER=umami
UMAMI_DB_PASS=your_secure_password
UMAMI_DB_NAME=umami
UMAMI_APP_SECRET=your_64_character_secret
# Authelia secrets (generate with openssl rand -hex 32)
AUTHELIA_DB_NAME=authelia
AUTHELIA_DB_USER=authelia
AUTHELIA_DB_PASSWORD=your_secure_password
AUTHELIA_JWT_SECRET=your_64_char_secret
AUTHELIA_SESSION_SECRET=your_64_char_secret
AUTHELIA_STORAGE_ENCRYPTION_KEY=your_64_char_secret
AUTHELIA_NOTIFIER_SMTP_PASSWORD=your_smtp_password
# Gitea secrets
GITEA_DB_USER=gitea
GITEA_DB_PASSWORD=your_secure_password
GITEA_DB_NAME=gitea
GITEA_SECRET_KEY=your_64_char_secret
GITEA_INTERNAL_TOKEN=your_internal_token
# Duplicati secrets
DUPLICATI_ENCRYPTION_KEY=your_encryption_key
DUPLICATI_PASSWORD=your_backup_password
```
### 3. Deploy the Gateway
```bash
docker compose up -d
```
### 4. Access Services
- **Traefik Dashboard**: `https://traefik.${DOMAIN_PREFIX}.${DOMAIN}`
- **Authelia**: `https://auth.${DOMAIN_PREFIX}.${DOMAIN}`
- **Portainer**: `https://portainer.${DOMAIN_PREFIX}.${DOMAIN}`
- **Uptime Kuma**: `https://uptime.${DOMAIN_PREFIX}.${DOMAIN}`
- **Umami Analytics**: `https://umami.${DOMAIN_PREFIX}.${DOMAIN}`
- **pgAdmin**: `https://pgadmin.${DOMAIN_PREFIX}.${DOMAIN}`
- **Beszel**: `https://beszel.${DOMAIN_PREFIX}.${DOMAIN}`
- **Gitea**: `https://git.${DOMAIN_PREFIX}.${DOMAIN}` (SSH: port 222)
- **Duplicati**: `https://backup.${DOMAIN_PREFIX}.${DOMAIN}`
## 📋 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.docker.network=traefik_proxy
- 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.docker.network=traefik_proxy
- 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.docker.network=traefik_proxy
- 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
- **`authelia`**: Authentication and authorization with 2FA support
### Usage Examples
```yaml
# Public application with analytics
- traefik.http.routers.app.middlewares=security-headers
# Admin interface with authentication
- traefik.http.routers.admin.middlewares=authelia@docker,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
- **Beszel**: Server resource monitoring (CPU, RAM, disk, network)
- **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