375 lines
9.8 KiB
Markdown
375 lines
9.8 KiB
Markdown
# 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.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
|
|
- **`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
|