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.
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.
`services` section.
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:
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
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>` |
`new-app-stack`).`docker-compose.newapp.yml` template, with all placeholders filled in.`.env` file, use the βUpload environment fileβ option. Otherwise, scroll down to Environment variables and manually add the variables defined in Step 1.
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.