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

# 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:

# 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

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:
volumes:
  your_service_data:
  1. Add service to the services section:
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
  1. Deploy the changes:
docker compose up -d

πŸ”§ Service Examples

WordPress Blog

Add to networks:

networks:
  traefik_proxy:
    name: traefik_proxy
    external: true
  wordpress_network:
    name: wordpress_network

Add to volumes:

volumes:
  wordpress_data:
  wordpress_db_data:

Add to services:

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

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

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

# 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

# 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

# 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)

# 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

# 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

# List networks
docker network ls

# Create external network if missing
docker network create traefik_proxy

# Inspect network
docker network inspect traefik_proxy

Useful Commands

# 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

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly
  5. Submit a pull request
Description
No description provided
Readme 95 KiB