Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Install Docker Example Output
debian@wrd-01:~$ curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Executing docker install script, commit: 4c94a56999e10efcf48c5b8e3f6afea464f9108e
+ sh -c apt-get -qq update >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install ca-certificates curl >/dev/null
+ sh -c install -m 0755 -d /etc/apt/keyrings
+ sh -c curl -fsSL "https://download.docker.com/linux/debian/gpg" -o /etc/apt/keyrings/docker.asc
+ sh -c chmod a+r /etc/apt/keyrings/docker.asc
+ sh -c echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get -qq update >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null
+ sh -c docker version
Client: Docker Engine - Community
Version: 28.0.4
API version: 1.48
Go version: go1.23.7
Git commit: b8034c0
Built: Tue Mar 25 15:07:22 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 28.0.4
API version: 1.48 (minimum version 1.24)
Go version: go1.23.7
Git commit: 6430e49
Built: Tue Mar 25 15:07:22 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.26
GitCommit: 753481ec61c7c8955a23d6ff7bc8e4daed455734
runc:
Version: 1.2.5
GitCommit: v1.2.5-0-g59923ef
docker-init:
Version: 0.19.0
GitCommit: de40ad0
================================================================================
To run Docker as a non-privileged user, consider setting up the
Docker daemon in rootless mode for your user:
dockerd-rootless-setuptool.sh install
Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.
To run the Docker daemon as a fully privileged service, but granting non-root
users access, refer to https://docs.docker.com/go/daemon-access/
WARNING: Access to the remote API on a privileged Docker daemon is equivalent
to root access on the host. Refer to the 'Docker daemon attack surface'
documentation for details: https://docs.docker.com/go/attack-surface/
================================================================================
debian@wrd-01:~$
Setup Docker Groups for Non-Privileged User
sudo usermod -aG docker $USER
newgrp docker
Test Non-Privileged User (Optional)
docker run hello-world
Expected Output
debian@wrd-01:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
e6590344b1a5: Pull complete
Digest: sha256:7e1a4e2d11e2ac7a8c3f768d4166c2defeb09d2a750b010412b6ea13de1efb19
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
debian@wrd-01:~$
All this does is confirm the Non-Privileged user can properly start a docker contianer.
Cleanup Docker (Optional)
This simply cleans up any images that are not running and tidies things up a bit from hello-world above
docker system prune -af --volumes
Expected Cleanup Docker Example
debian@wrd-01:~$ docker system prune -af --volumes
Deleted Containers:
1e18f395b2e005406599c2ec17175f6d6b4da4da14073375d4a504d6804a50bb
Deleted Images:
untagged: hello-world:latest
untagged: hello-world@sha256:7e1a4e2d11e2ac7a8c3f768d4166c2defeb09d2a750b010412b6ea13de1efb19
deleted: sha256:74cc54e27dc41bb10dc4b2226072d469509f2f22f1a3ce74f4a59661a1d44602
deleted: sha256:63a41026379f4391a306242eb0b9f26dc3550d863b7fdbb97d899f6eb89efe72
Total reclaimed space: 10.07kB
debian@wrd-01:~$
Add Protainer
Simple enough and allows for easier upgrade of Portainer. Below is the docker-compose file.
cd ~
mkdir portainer
cd portainer
nano docker-compose.yaml
Paste in the compose data below and follow the rest of procedure from Pull Portainer Images section.
# version: "3"
services:
portainer:
image: portainer/portainer-ce:lts
ports:
- 9443:9443
volumes:
- data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
volumes:
data:
I got this from this site and I did not modify it much if you look the volumes is spaced wrong on original. So, I fixed that here. Now, all I have to do is run this:
Pull Portainer Images
docker compose pull
Expected Output of Compose Pull
debian@wrd-01:~/portainer$ docker compose pull
[+] Pulling 11/11
✔ portainer Pulled 4.7s
✔ e2e06b27b87e Pull complete 0.4s
✔ 1fed1531b45b Pull complete 0.5s
✔ 04de093ad5ed Pull complete 1.0s
✔ 86a7cce72d42 Pull complete 1.5s
✔ e09df2601140 Pull complete 2.1s
✔ eae3ebf29ea8 Pull complete 2.2s
✔ c12aa3fbd31a Pull complete 2.8s
✔ f111bda3f9a6 Pull complete 3.3s
✔ 81021110ed01 Pull complete 3.4s
✔ 4f4fb700ef54 Pull complete 3.6s
debian@wrd-01:~/portainer$
Bring Up Portainer
docker compose up -d
Expected Output of Portianer Up
debian@wrd-01:~/portainer$ docker compose up -d
[+] Running 3/3
✔ Network portainer_default Created 0.1s
✔ Volume "portainer_data" Created 0.0s
✔ Container portainer-portainer-1 Started 0.6s
debian@wrd-01:~/portainer$
Bringing Down Portainer
docker compose down
Expected Portainer Down Example
debian@wrd-01:~/portainer$ docker compose down
[+] Running 2/2
✔ Container portainer-portainer-1 Removed 0.4s
✔ Network portainer_default Removed 0.4s
debian@wrd-01:~/portainer$
Upgrading Portainer
So, since this is a docker compose all that has to be done is bring down portainer and the bring it back up and it should reload and auto migrate to new version. This is the main reason I use this approach is to make it easy to upgrade Portainer.
Prune after Upgrade
I recommend running prune after an upgrade to clean up any floaters.
docker system prune -af --volumes