Portainer Docker Compose with Traefik and Lets Encrypt Certificates
Portainer is a great solution that provides excellent management of Docker and Kubernetes environments. With Portainer, you can have a fully managed Docker container environment, managing multiple Docker hosts and Kubernetes clusters. Let’s take a look at getting up and running with Portainer using Docker compose code and also how you can manage Docker compose code for your Docker application stacks.
Table of contents
- Brief overview of Portainer
- What is Docker Compose?
- Install Portainer using Docker Compose
- Portainer Docker Compose with Let’s Encrypt certificates using Traefik
- Creating a Docker Stack with Portainer
- Securing Portainer and logins
- Portainer and Docker Compose best practices
- Troubleshooting
- Wrapping up
- Resources for more Portainer information
Brief overview of Portainer
Portainer is a free solution to download in the Community Edition. There is also a Business Edition that is free up to 3 managed nodes that provides additional features and capabilities like webhooks for container updates, etc. It provides GUI management of Docker container hosts. It easily allows you to see your Docker containers, images, volumes, and networks.
Managing Docker Containers with Portainer
Also, in addition to creating containers, you can use the Portainer web interface for Docker management to view container logs and statistics. You can also use the Portainer web interface to manage container networks and volumes after these are created for day-to-day management.
Below you can see the detailed view of containers on the managed Docker container host.
Below, we can see the details of a specific Docker container.
What is Docker Compose?
A Docker Compose file is a YAML file that sets out the configuration for services, networks, and storage volumes for a Docker application (container stack). You can create the file manually or using a template.
Docker Compose functionality provides an easy way to spin up multi-container Docker applications in an easy way. Instead of having to issue a docker run command for every container, you instead create your Docker compose file and issue the docker compose up -d command to bring up your Docker Compose stack.
Below is an example of a Docker compose file.
Install Portainer using Docker Compose
You can easily install a Portainer Docker container using Docker Compose in your docker environment with the following Docker Compose code. As a prerequisite, you will need to have Docker installed along with Docker Compose.
It will create the volume needed for Portainer and also create the Portainer CE container. To use the below, you need to create the Docker Compose file manually, by creating the docker-compose.yml with the below. Once up, you can access portainer on port 9443. You will see the local Docker socket mounted as part of your volumes mount.
version: '3'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "8000:8000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
Business edition
If you want to install the Business Edition of the Portainer Docker Docker Compose you can create a docker-compose.yml with the below.
version: '3'
services:
portainer:
image: portainer/portainer-ee:latest
container_name: portainer
restart: always
ports:
- "8000:8000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
Outside of installing Portainer with Docker Compose, you can also manage and deploy solutions. After you create your docker-compose.yml file, issue the Docker compose up command:
docker-compose up -d
You should see your Portainer instance come up and running.
Portainer Docker Compose with Let’s Encrypt certificates using Traefik
In case you want to setup Portainer Docker Compose installation with Traefik and Let’s Encrypt certificates, below is an example of Docker compose code you can use.
version: '3.8'
services:
traefik2:
image: traefik:latest
restart: always
command:
# Tell Traefik to discover containers using the Docker API
- --providers.docker=true
# Enable the Trafik dashboard
- --api.dashboard=true
# Set up LetsEncrypt
- --certificatesresolvers.letsencrypt.acme.dnschallenge=true
- --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
- --certificatesresolvers.letsencrypt.acme.email=youremail.domain.com
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
# Set up an insecure listener that redirects all traffic to TLS
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.websecure.address=:443
# Set up the TLS configuration for our websecure listener
- --entrypoints.websecure.http.tls=true
- --entrypoints.websecure.http.tls.certResolver=letsencrypt
- --entrypoints.websecure.http.tls.domains[0].main=yourdomain.com
- --entrypoints.websecure.http.tls.domains[0].sans=*.yourdomain.com
- --serverstransport.insecureskipverify=true
environment:
- [email protected]
- CLOUDFLARE_DNS_API_TOKEN=<your token>
ports:
- 80:80
- 443:443
networks:
traefik:
ipv4_address: 172.19.0.10
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ~/homelabservices/letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
- 'traefik.http.routers.traefik.rule=Host(`10.1.149.19`)'
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.service=api@internal"
- 'traefik.http.routers.traefik.middlewares=strip'
- 'traefik.http.middlewares.strip.stripprefix.prefixes=/traefik'
container_name: traefik
portainer:
image: portainer/portainer-ee:latest
container_name: portainer
restart: always
networks:
traefik:
ipv4_address: 172.19.0.19
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.rule=Host(`portainer.yourdomain.com`)"
- "traefik.http.routers.portainer.tls=true"
- "traefik.http.routers.portainer.entrypoints=websecure"
- "traefik.http.services.portainer.loadbalancer.server.scheme=https"
- "traefik.http.services.portainer.loadbalancer.server.port=9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
networks:
traefik:
driver: bridge
name: traefik
ipam:
driver: default
config:
- subnet: 172.19.0.0/16
Creating a Docker Stack with Portainer
In addition to installing Portainer with Docker compose, you can also create what Portainer calls stacks. These are Docker Compose YAMl file configurations that define your containers you want to deploy.
Portainer provides a GUI for deploying and managing Docker applications via Docker Compose code. You can use the Portainer web interface to deploy a new application. Use Docker Compose to deploy the application.
Portainer stacks
Below you will see the Portainer stacks functionality. When you are live connected to a Docker host, click the Stacks button. Then you will see the Build method. Here you have several choices:
- Web editor – You can use the editor in the browser window using code from Docker hub or other sources
- Upload – Upload a Docker Compose file
- Repository – Pull from a git repository
- Custom template – Use a custom template
After pasting in the Portainer Docker Compose file.
Securing Portainer and logins
Portainer comes with an internal authentication system. You can use multifactor authentication, such as Google OAuth or Authelia Self-hosted MFA for better security. Portainer doesn’t have a built-in 2FA capability, so you will need to add your own.
Authentication options
You can use Portainerโs built-in OAuth or LDAP authentication (or Microsoft Active Directory with a Pro plan) for authentication. Use a secure connection (HTTPS) to access the Portainer web interface and consider adding your own trusted certificate and not just the default self-signed SSL certificate that comes out of the box.
Portainer and Docker Compose best practices
There are a few best practices to keep in mind for Portainer and Docker Compose. Most of these are common sense type best practices that are a good idea to adopt. These include things like:
- A consistent naming convention for containers and services such as your application stacks
- Use a naming convention for your networks and volumes
- Always use an HTTPS connection for your Portainer instance – Use a trusted cert and not just the untrusted self-signed certificate out of the box
- Limit from a network perspective, who can connect to Portainer
- Scan any containers or application stacks for vulnerabilities
- Have lifecycle management as part of your containerized infrastructure to redeploy apps as needed
Troubleshooting
If the containers in your app stack don’t come up correctly:
- Check your Docker logs: docker logs <containername>
- Use a YAML file checker to check the syntax of your YAML code found in your Docker Compose file
Wrapping up
Portainer is a really great tool for managing not just Docker environments, but also Kubernetes environments. It allows using app stacks easily to spin up multiple docker containers via a docker compose file.
You can download the Business Edition for free for 3 nodes here: Take 3 – Get your first 3 nodes free (portainer.io).
Resources for more Portainer information
Portainer official documentation: https://portainer.io/documentation. You can look at the official Docker Compose documentation here: https://docs.docker.com/compose/ and the Docker official documentation here: https://docs.docker.com/.