Portainer is a powerful Docker and Kubernetes management platform that simplifies container orchestration by providing a user-friendly, graphical online interface. In this blog post, I’ll share my experience with migrating to Portainer and the benefits it brings to container management.
Why Portainer?
My decision to switch to Portainer stemmed from two main motivations. Firstly, I wanted to expand my knowledge and expertise in container orchestration, and Portainer offered an excellent learning opportunity. Secondly, I recognized the value of adding an extra layer of control between users and direct access to containerized applications. This additional layer of control not only enhances security but also streamlines collaboration in group settings, eliminating the need to grant users SSH access to my devices. Instead, I could provide controlled access to Portainer, enhancing both security and convenience.
The Migration Process
Migrating to Portainer involves several steps, and I’ll guide you through the process I followed:
Docker Compose file for Portainer
To get started, I pulled the Portainer image. However, to enable Portainer to create and manage Docker containers, it’s crucial to bind the Docker daemon using the docker.sock file, like so: -H unix:///var/run/docker.sock. Additionally, I added labels to ensure proper routing through the Traefik reverse proxy. Don’t forget to configure the subdomain in your DNS service. I have my docker-compose.yml file below for your convenience.
version: "3"
services:
portainer:
image: "portainer/portainer-ce:latest"
container_name: "portainer"
command: "-H unix:///var/run/docker.sock"
restart: "always"
networks:
- "traefik-proxy"
volumes:
- "data:/data"
- "/var/run/docker.sock:/var/run/docker.sock"
- "/etc/localtime:/etc/localtime:ro"
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-proxy"
- "traefik.http.routers.portainer.rule=Host(`portainer.atakanonol.dev`)"
- "traefik.http.routers.portainer.entrypoints=websecure,web"
- "trafeik.http.routers.portainer.tls=true"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer.tls.certresolver=production" # May want to try staging before production as production has a rate limit
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
volumes:
data:
networks:
traefik-proxy:
external: true Accessing the Web Interface:
After a smooth setup, you can access the web interface. Upon visiting the webpage for the first time, you’ll be greeted with a user-friendly setup screen where you can create your login credentials.
Migrating Services:
Now, let’s dive into the migration process. I began by moving my Uptime Kuma instance to Portainer. To do this, I stopped the Docker instance, noted the changes I had made, and took the opportunity to remove any unused images. While not strictly necessary, I also cleared any certifications in my Traefik configuration (acme.json) related to containers I would be migrating to Portainer.
Setting Up Services:
The process of adding services is straightforward. You can use Portainer’s web interface to create stacks, and if you have a Git repository, linking to it is a breeze. For my Uptime Kuma instance, which relies on a simple Docker Compose YAML file, I used Portainer’s web editor to paste in the contents of the docker-compose.yml file and configure my environment variables. Here is my docker-compose file.
version: "3.8"
services:
uptime-kuma:
image: "louislam/uptime-kuma:latest"
container_name: "uptime-kuma"
volumes:
- "./uptime-kuma-data:/app/data"
restart: "always"
networks:
- "traefik-proxy"
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-proxy"
- "traefik.http.routers.uptime-kuma.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)"
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
- "trafeik.http.routers.uptime-kuma.tls=true"
- "traefik.http.routers.uptime-kuma.tls.certresolver=production"
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
networks:
traefik-proxy:
external: true Deployment and Testing:
After configuring the stack, it’s a matter of naming it and clicking “deploy.” Give it a moment to deploy, and then navigate to the specified URL. Keep in mind that configuring the subdomain in your DNS is essential for smooth access. In my case, I initially encountered some issues due to missing DNS configuration, but once resolved, everything worked seamlessly.
Exploring Heimdall:
In my quest to streamline my containerized applications, I also discovered Heimdall, a dashboard that simplifies access to various services. Inspired by the Scandinavian god from Asgard, Heimdall provides an organized overview of your services, making it easier to access them quickly.
Just like with my other services, I followed a similar process to integrate Heimdall into Portainer. I created a new stack and pasted my docker-compose.yml file contents, allowing me to take full advantage of this valuable dashboard.
Here is that docker-compose file.
version: "3.8"
services:
heimdall:
image: "lscr.io/linuxserver/heimdall:latest"
container_name: "heimdall"
networks:
- "traefik-proxy"
restart: "always"
environment:
- "PUID=1000"
- "PGID=1000"
- "TZ=Etc/UTC"
volumes:
- "./config:/config"
labels:
# The labels are usefull for Traefik only
- "traefik.enable=true"
- "traefik.docker.network=traefik-proxy"
# Get the routes from http
- "traefik.http.routers.heimdall.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.heimdall.entrypoints=web,websecure"
# Apply autentificiation with http challenge
- "traefik.http.routers.heimdall.tls=true"
- "traefik.http.routers.heimdall.tls.certresolver=production"
networks:
traefik-proxy:
external: true Migrating to Portainer has been a rewarding journey, enhancing my container management capabilities and improving security in my setup. With its user-friendly interface and powerful features, Portainer has become an essential tool in my container orchestration toolkit. Whether you’re a seasoned container expert or just starting your journey, Portainer is worth exploring for its simplicity and effectiveness in managing Docker and Kubernetes environments.