skip to content
Maathuran's Blog
Setting up Docker on Proxmox 8.0

Setting up Docker on Proxmox 8.0

/ 6 min read

Introduction

Many mainstream applications are now built for docker deployment as it is easier to update than standard Linux binaries. On one of the Proxmox hosts, I will deploy a Docker container under Alpine Linux with Portainer on top to have a web GUI.

Installing Alpine

if this is your first time installing Alpine as an iso, follow the steps below. If not, skip until you get to the VM creation part.

Adding Aliplne Linux

For Proxmox, we will add the Alpine Virtual ISO and then boot off it to install. Navigate to the Alpine Download page and copy the link for Virtual -> x86_64 AL0

Under Datacenter (Lab) -> pve01 -> local (pve01) -> ISO Images, Click on -> Download from URL, in the URL field, paste in the link and click on Query URL, After that click Download. PM1

After the download is complete, you can close Task Viewer. PM2

Creating Alpine VM

Back on pve01 right, click and Create VM. PM3

Keep the auto-filled values the same for Node and VM ID. You can set a name I’m using, Docker. Click Next PM4

For OS select alpine-virt-3.18.4-x86_64.iso, Set Type to Linux and Version to 6.x - 2.6 Kernel, after that click on Next PM5

Keep everything the same for System. PM6

You can keep the Disk Size at 32 and the Storage volume as local-lvm. Click on Next PM6

For CPU, I am keeping it at 1 socket and setting it to 2 Cores. The Type is going to be Host. Click Next PM7

Memory is going to be set at 2048 PM8

The network is going to be kept as the default values PM9

On the confirmation page, check to see if all the settings are correct, then click on Finish. PM10

Booting Alpine VM

After creation, navigate over to the new VM, click on Console, then start the VM PM10

After booting to install Alpine to the Disk, login as root PM11

Installing Alpine VM to Disk

To Setup run setup-alpine, choose us as the keyboard layout PM12

Choose us again PM13

for the hostname, I am selecting docker.lab.ata.al PM14

for the Network interface, I am selecting eth0 PM15

I am setting a static IP address which is 10.0.200.101 PM16

set the rest of the network to your liking and type in n for any manual configuration PM17

For the Name server, I used 1.1.1.1. You will be asked for a new root password and a timezone. PM18

for Proxy put none PM19

For Mirrors, you can select any number, but I choose 1. PM19

you can skip the new user part PM20

For SSH, you can keep the default SSH server and check Allow root Login to Yes. PM21

For Disk setup, select sda or whichever disk is there PM22

On disk setup, choose sys PM23

After agreeing to erase the disk, it will start to install PM24

After the installation, you will need to remove the install iso in Proxmox. Under Hardware, find CD/DVD and click Remove. PM25

Shut down and start the system again. The rest of the setup can be done over ssh

% ssh root@10.0.210.101
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <https://wiki.alpinelinux.org/>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

docker:~# 

Updating Alpine VM

Before installing any package, you will need to update the system by running this command apk update followed by apk upgrade

to add the community resource, run the following

cat > /etc/apk/repositories << EOF; $(echo)

https://dl-cdn.alpinelinux.org/alpine/v$(cut -d'.' -f1,2 /etc/alpine-release)/main/
https://dl-cdn.alpinelinux.org/alpine/v$(cut -d'.' -f1,2 /etc/alpine-release)/community/
https://dl-cdn.alpinelinux.org/alpine/edge/testing/

EOF

then

apk update

Adding Docker to Alpine VM

To install Docker, run the following commands

apk add docker
addgroup username docker
rc-update add docker default
service docker start

if it works, you will see the following

(15/17) Installing docker-cli (23.0.6-r6)
(16/17) Installing docker-cli-buildx (0.10.4-r9)
(17/17) Installing docker (23.0.6-r6)
Executing docker-23.0.6-r6.pre-install
Executing busybox-1.36.1-r4.trigger
Executing ca-certificates-20230506-r0.trigger
OK: 312 MiB in 76 packages
docker:~# addgroup username docker
addgroup: unknown user username
docker:~# rc-update add docker default
 * service docker added to runlevel default
docker:~# service docker start
 * Caching service dependencies ...                                                              [ ok ]
 * Mounting cgroup filesystem ...                                                                [ ok ]
 * /var/log/docker.log: creating file
 * /var/log/docker.log: correcting owner
 * Starting Docker Daemon ...                                                                    [ ok ]
docker:~# 

Adding Portainer to Docker

To add portainer, you will need to create a database first

docker volume create portainer_data

then add the portainer image

docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

if both commands are successful, you will see the following

docker:~# docker volume create portainer_data
portainer_data
docker:~# docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.
sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Unable to find image 'portainer/portainer-ce:latest' locally
latest: Pulling from portainer/portainer-ce
795a208431d7: Pull complete 
4f272ca3dde3: Pull complete 
5171176db7f2: Pull complete 
52e9438966a5: Pull complete 
43d4775415ac: Pull complete 
c1cad9f5200f: Pull complete 
27d6dca9cab4: Pull complete 
231d7e50ef35: Pull complete 
589f2af34593: Pull complete 
5fc2ddaa6f07: Pull complete 
4f4fb700ef54: Pull complete 
Digest: sha256:f29cbc7b26ebd701b1fe92b4df42edea350e871372a6296a1fa16ba999481fb2
Status: Downloaded newer image for portainer/portainer-ce:latest
07463a06079d678536414271b35b411f20f23bc4ebebd11de9ce81b365c06480
docker:~# 

and with docker ps you will see the running image

docker:~# docker ps
CONTAINER ID   IMAGE                           COMMAND        CREATED          STATUS          PORTS                                                                                            NAMES
07463a06079d   portainer/portainer-ce:latest   "/portainer"   46 seconds ago   Up 44 seconds   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp   portainer
docker:~# 

To access Portainer, you can visit the VM’s URL with HTTPS and Port 9443. After the page loads, you will be asked to make a new admin user. PD25

Adding Watchguard to Portainer

to keep all your Docker images up to date, you can add Watchguard to check Docker and pull the latest images automatically.

Under Stack click on Add stack PD26

Call it watchtower and select Web Editor, past in the following

version: "3.5"
services:
  watchtower:
    image: containrrr/watchtower:latest
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_INCLUDE_RESTARTING=true
      - WATCHTOWER_INCLUDE_STOPPED=true
      - WATCHTOWER_REVIVE_STOPPED=false
      - WATCHTOWER_NO_RESTART=false
      - WATCHTOWER_TIMEOUT=30s
      - WATCHTOWER_SCHEDULE=0 0 4 * * *
      - WATCHTOWER_DEBUG=false
      - TZ=America/Toronto
    network_mode: bridge

Disable Access Control, as we are not using roles with portainer

for help with enviroment variable visit this link as it conaintes info on each one of them PD27

After that, click on Deploy the Stack PD28

You can check the logs under Container -> watchtower -> Logs to see when it will next check for any updates Under Container, you should see two running containers now PD29

Bonus

While writing this, Portainer ran a free upgrade for three nodes to Portianer Business edition https://www.portainer.io/take-3. You can sign up with your custom email and get three free keys.

To start the upgrade, click Upgrade to Business Edition on the home page of the portainer and enter your key. PD30

After validating your key, you will see this message below. Then it will ask you to resign in PD31

HTTPS Reverse Proxy with Caddy

With Caddy, add the following to enable auto SSL cert generation and HTTP to HTTPS redirect for portainer

{
    "apps": {
        "http": {
            "servers": {
                "srv0": {
                    "listen": [
                        ":443"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": [
                                        "portainer.ata.al"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy", 
                                                    "transport": {
                                                        "protocol": "http",
                                                        "tls": {
                                                            "insecure_skip_verify": true
                                                        }
                                                    },
                                                    "upstreams": [
                                                        {
                                                            "dial": "10.0.210.101:9443"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ]
                }
            }
        }
    }
}