Skip to content

Single Container Template

This template is for deploying a single containerized application with Traefik.

Use Cases

  • Web applications (Node.js, Python, Go)
  • APIs and microservices
  • Static sites (documentation, landing pages)
  • Any standalone service

Template

docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    container_name: my-app
    restart: unless-stopped
    labels:
      # Enable Traefik for this container
      - traefik.enable=true

      # Router configuration
      - traefik.http.routers.my-app.rule=Host(`app.egygeeks.com`)
      - traefik.http.routers.my-app.entrypoints=websecure
      - traefik.http.routers.my-app.tls.certresolver=letsencrypt

      # Service configuration (port your app listens on)
      - traefik.http.services.my-app.loadbalancer.server.port=8000
    networks:
      - traefik_public

networks:
  traefik_public:
    external: true

Customization Steps

1. Replace App Name

Find and replace my-app in 3 places:

  • container_name: my-app
  • traefik.http.routers.my-app.*
  • traefik.http.services.my-app.*

2. Set Your Domain

Replace app.egygeeks.com with your domain:

- traefik.http.routers.my-app.rule=Host(`yourdomain.com`)

3. Configure Port

Replace 8000 with the port your application listens on:

- traefik.http.services.my-app.loadbalancer.server.port=8000

Common ports:

  • Node.js/Express: 3000
  • Python/Flask: 5000
  • Python/FastAPI: 8000
  • Go apps: 8080
  • Static sites: 8000

Requirements

1. Dockerfile

Your project must have a Dockerfile. Example for a static site:

Dockerfile
FROM python:3.11-alpine
WORKDIR /app
COPY site ./site
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD wget --quiet --tries=1 --spider http://127.0.0.1:8000/ || exit 1
CMD ["python", "-m", "http.server", "8000", "--directory", "site"]

2. Health Check

Critical: Add a HEALTHCHECK to your Dockerfile. Traefik only routes to healthy containers.

Use 127.0.0.1, not localhost

In Alpine-based images, use 127.0.0.1 instead of localhost in health checks to avoid DNS resolution issues.

3. Network

The traefik_public network must exist on the server (it already does).

Complete Example

Here's a complete setup for a Next.js app:

docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    container_name: nextjs-app
    restart: unless-stopped
    labels:
      - traefik.enable=true
      - traefik.http.routers.nextjs-app.rule=Host(`myapp.egygeeks.com`)
      - traefik.http.routers.nextjs-app.entrypoints=websecure
      - traefik.http.routers.nextjs-app.tls.certresolver=letsencrypt
      - traefik.http.services.nextjs-app.loadbalancer.server.port=3000
    networks:
      - traefik_public

networks:
  traefik_public:
    external: true

Deployment

After creating your docker-compose.yml:

  1. Copy the GitHub Actions workflow template
  2. Push to GitHub
  3. Deployment runs automatically

Or deploy manually on the server:

docker compose up -d

Troubleshooting

Container not accessible (404)

Check if container is healthy:

docker ps

Look for "healthy" status. If "unhealthy":

# Check logs
docker logs my-app

# Test health check manually
docker exec my-app wget -O- http://127.0.0.1:8000/

SSL certificate issues

Traefik automatically provisions Let's Encrypt certificates. Wait 30-60 seconds after deployment.

Port conflicts

If another container uses the same port:

# Find what's using the port
docker ps --format "table {{.Names}}\t{{.Ports}}"

Multi-Container Template Deployment Workflow