Table of Contents
Building New Docker Services with Traefik (for Portainer)
This guide provides a standardized process for adding new applications to your existing Docker environment, using Docker Compose Stacks managed by Portainer and automatically routing traffic through the Traefik reverse proxy.
π Overview of the Process
To integrate a new service (e.g., a new app, a database, etc.) into your environment, you'll create a new, dedicated `docker-compose.yml` file.
- Create Service Containers: Define the application and its dependencies (like a database) in the
`services`section. - Define Traefik Labels: Apply specific Docker labels to the application container so Traefik knows how to route incoming traffic (e.g., which hostname to listen for and which port to forward to).
- Use Dedicated Networks: Containers must be on a private, isolated network for internal communication (e.g., app ⇔ DB) and connect to the existing Traefik Network for external access.
- Deploy via Portainer: Paste the Compose file into a new Stack in Portainer.
π New Service Template (docker-compose.newapp.yml)
Use this template as the basis for any new service you want to expose via Traefik. Replace all placeholders (`<β¦>` and `${β¦}`) with your service's specific details.
version: '3.7' services: # 1. The Application Service (The one that Traefik connects to) new-app: image: <your_app_docker_image>:<tag> container_name: new-app restart: unless-stopped # Environment variables for your app (e.g., database connection) environment: DB_HOST: new-app-db # Use the internal service name DB_USER: ${NEW_APP_DB_USER} DB_PASSWORD: ${NEW_APP_DB_PASSWORD} # ... other app settings ... # Connect to the private network for internal comms and Traefik's network for external exposure networks: - new-app-internal - traefik-proxy # MUST be the name of your external Traefik network # Traefik Labels (REQUIRED for routing) labels: # Enable Traefik for this service - "traefik.enable=true" # 1. Router Definition (Listens for incoming connections) - "traefik.http.routers.new-app.rule=Host(`${NEW_APP_HOSTNAME}`)" - "traefik.http.routers.new-app.entrypoints=websecure" - "traefik.http.routers.new-app.tls=true" - "traefik.http.routers.new-app.tls.certresolver=letsencrypt" # IMPORTANT: Match your Traefik resolver name (e.g., 'le') # 2. Service Definition (Where to send the traffic inside the container) # Port is the internal port the application listens on (e.g., 80, 3000, 8080) - "traefik.http.services.new-app-service.loadbalancer.server.port=<internal_app_port>" # Optional: Add any desired middleware (e.g., for security or redirects) # - "traefik.http.routers.new-app.middlewares=<middleware_name>@docker" volumes: - new-app-data:/app/data depends_on: - new-app-db # 2. The Database Service (or any other dependency) new-app-db: image: postgres:15-alpine # Example database container_name: new-app-db restart: unless-stopped environment: POSTGRES_USER: ${NEW_APP_DB_USER} POSTGRES_PASSWORD: ${NEW_APP_DB_PASSWORD} POSTGRES_DB: ${NEW_APP_DB_NAME} volumes: - new-app-db-data:/var/lib/postgresql/data networks: - new-app-internal # Database MUST be on the isolated internal network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${NEW_APP_DB_USER}"] interval: 10s timeout: 5s retries: 5 networks: # 1. Isolated Internal Bridge Network (For App <-> DB communication) new-app-internal: driver: bridge # 2. External Traefik Network (For Traefik access to the App) traefik-proxy: external: true # IMPORTANT: The 'name' must match the network Traefik is running on. # In your environment, this might be 'default', 'web', or 'traefik-proxy'. name: traefik-proxy volumes: new-app-data: new-app-db-data:
π οΈ Step-by-Step Portainer Deployment
1. Prepare Environment Variables (.env)
Before deploying, you need to define the variables used in the compose file.
Create an `.env` file (or prepare to enter these variables directly into Portainer's environment variables section):
NEW_APP_HOSTNAME=newapp.yourdomain.com NEW_APP_DB_USER=secureuser NEW_APP_DB_PASSWORD=SuperSecretDBPassword! NEW_APP_DB_NAME=newapp_production
2. Configure DNS
Go to your DNS provider and create an A record that points your chosen hostname to the public IP address of the server running Traefik:
| Type | Name (Host) | Value (Points To) |
| β- | β- | β- |
| A | `newapp.yourdomain.com` | `<Your_Server_Public_IP>` |
3. Deploy the Stack in Portainer
- Log in to Portainer and navigate to Stacks.
- Click + Add stack.
- Enter a descriptive Name for your stack (e.g.,
`new-app-stack`). - In the Web Editor, paste the content of the
`docker-compose.newapp.yml`template, with all placeholders filled in. - If you have an
`.env`file, use the βUpload environment fileβ option. Otherwise, scroll down to Environment variables and manually add the variables defined in Step 1. - Click Deploy the stack.
Traefik will detect the new container, read the labels, and automatically start the process of obtaining an SSL certificate for `newapp.yourdomain.com`. Your service should be accessible via HTTPS within a few minutes.
