After setting up your server with docker-setup, you have a powerful environment ready for hosting applications. The setup provides Traefik for routing and SSL, Portainer for management, and Watchtower for automatic updates. Let's explore how to deploy applications in this environment.
Understanding Docker-Setup's Architecture
Docker-setup creates a streamlined environment where three core services work together to handle your applications. Traefik sits at the edge, managing incoming traffic and SSL certificates. Portainer provides an intuitive web interface for deployment management, while Watchtower keeps your containers updated automatically.
All services connect through a single network called traefik_network
. This network allows Traefik to route traffic to your applications while providing necessary isolation between containers. When we deploy new applications, they'll need to join this network to be accessible through Traefik.
Preparing Your Application
To deploy an application successfully, you'll need a docker-compose.yml file with specific Traefik labels. Here's a practical example deploying a web application:
version: '3'
services:
webapp:
image: nginx
container_name: my-webapp
networks:
- traefik_network
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`webapp.yourdomain.com`)"
- "traefik.http.routers.webapp.entrypoints=websecure"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
# If your app doesn't use port 80 internally, specify the port:
- "traefik.http.services.webapp.loadbalancer.server.port=8080"
networks:
traefik_network:
external: true
Let's understand these Traefik labels. The traefik.enable=true
label tells Traefik to manage this container. The rule
label defines how traffic reaches your app using the domain name you specify. The entrypoints
label ensures HTTPS access, while the certresolver
enables automatic SSL certificate management through Let's Encrypt.
Deployment Methods
Method 1: Using Portainer's Web Interface
Portainer provides a user-friendly way to deploy applications:
Access your Portainer instance at portainer.yourdomain.com or http://<your-ip>:9000
Navigate to "Stacks" in the left sidebar
Click "Add stack"
Name your stack (e.g., "webapp")
Paste your docker-compose.yml content
Click "Deploy the stack"
Method 2: Using Command Line
For those who prefer terminal access:
# Create a directory for your application
mkdir -p ~/apps/webapp
cd ~/apps/webapp
# Create docker-compose.yml with your preferred editor
nano docker-compose.yml
# Deploy the stack
docker compose up -d
Advanced Configuration Examples
Example 1: Multi-Container Application with Database
Here's how to deploy a web application with a database, ensuring proper communication between services:
version: '3'
services:
webapp:
image: your-web-app
container_name: my-webapp
networks:
- traefik_network
- backend
environment:
- DB_HOST=db
- DB_PASSWORD_FILE=/run/secrets/db_password
depends_on:
- db
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`webapp.yourdomain.com`)"
- "traefik.http.routers.webapp.entrypoints=websecure"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
secrets:
- db_password
db:
image: postgres:13
container_name: my-webapp-db
networks:
- backend
volumes:
- db_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
volumes:
db_data:
networks:
traefik_network:
external: true
backend:
name: webapp_backend
secrets:
db_password:
file: ./db_password.txt
In this example, we create an additional internal network (backend
) for secure database communication. Only the webapp container connects to both networks, while the database remains isolated from external access.
Example 2: Application with Multiple Subdomains
For applications requiring different subdomains:
version: '3'
services:
frontend:
image: your-frontend
networks:
- traefik_network
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`app.yourdomain.com`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
api:
image: your-backend
networks:
- traefik_network
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.yourdomain.com`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
networks:
traefik_network:
external: true
Monitoring Your Deployment
After deployment, you can monitor your application through several means:
Portainer's dashboard shows container status and logs
Traefik's dashboard displays routing and SSL certificate status
Docker logs provide detailed container information:
# View container logs
docker logs my-webapp
# Follow logs in real-time
docker logs -f my-webapp
Common Issues and Solutions
SSL Certificate Issues When SSL certificates fail to generate, first check your domain's DNS configuration. Ensure it points to your server's IP address and allow a few minutes for DNS propagation. You can verify Traefik's certificate generation process in its logs.
Network Connectivity If containers can't communicate, verify they're properly connected to the
traefik_network
. For applications with databases, ensure your internal networks are correctly configured.Container Access When containers won't start, check their logs for startup errors. Verify environment variables are set correctly and all required volumes are properly mounted.
Best Practices
When deploying applications in this environment:
Use specific image tags instead of 'latest' to ensure deployment consistency
Implement health checks to monitor application status
Store sensitive data using Docker secrets
Regularly backup persistent data
Monitor container resource usage through Portainer
This setup provides a robust foundation for deploying containerized applications. As you become more familiar with it, you can explore advanced Traefik features like rate limiting, middleware, and custom error pages to enhance your deployments.