As a full-stack developer and Raspberry Pi enthusiast, I often use Docker to simplify building, shipping, and running applications. The Raspberry Pi‘s low cost, small footprint, and Linux/ARM support make it an ideal platform for Docker.
In this comprehensive 3049-word guide, we will dive deep on installing Docker Engine and Docker Compose on a Raspberry Pi 4 running Raspberry Pi OS, and demonstrate how to effectively build, manage, and monitor containers.
Why Docker on Raspberry Pi
Before we get hands-on, let‘s discuss why running Docker on Raspberry Pi makes for an compelling combination:
Simplified Dependency Management
Deploying complex applications with many dependencies and config files becomes trivial using Docker containers. Avoid dependency version conflicts by standardizing on containerized apps.
Portability
Build an application image once, then run it anywhere Linux containers can run – including Raspberry Pi, desktop PCs, cloud VMS and Kubernetes clusters.
Lightweight Virtualization
Containers provide a lightweight form of OS-level virtualization by leveraging technology built into the Linux kernel. This has less overhead than traditional VMs.
Raspberry Pi Flexibility
Docker functionality unlocks many new homelab use cases for Raspberry Pis – everything from network appliances to automation servers and beyond.
Scaling
While one Raspberry Pi 4 has limited compute power, you can network multiple Pis together to create affordable clusters for scale.
Now let‘s get our hands dirty…
Prerequisites
For this Docker guide, I used the following setup:
- Raspberry Pi: Raspberry Pi 4 Model B 8GB
- Storage: 64GB Class 10 MicroSD Card
- OS: Raspberry Pi OS 64-bit (Debian Bullseye)
- Networking: Ethernet connectivity
- Power: Official Raspberry Pi 15W USB-C Power Supply
For best Docker performance, I recommend the 8GB Pi 4 or better. The 2GB and 4GB models may struggle with some heavier apps. The 64GB+ MicroSD allows ample room for images/containers.
Optional but highly recommended:
- Portainer – Open source container monitoring and management GUI
Step 1 – Update Raspberry Pi OS
Boot up your Pi 4, connect over SSH as the pi user or log in directly, then become root with sudo su.
Update package repositories and upgrade installed packages:
apt update
apt full-upgrade -y
Reboot once upgrades complete. This ensures we start with the latest security patches and kernel before installing Docker.

Updating Raspberry Pi OS – Takes 5-10 Minutes
Step 2 – Install Docker Engine
With Raspberry Pi OS hardened, we can now install the latest Docker Engine package using the official convenience script:
curl -sSL https://get.docker.com | sh
On first run, the script contacts Github for the latest ARM builds, instals dependencies like containerd, then grabs and installs Docker Engine binaries.
Follow along and OK the prompts during the ~5 minute install process:

Docker Community Edition Installing on Raspberry Pi
Once complete, add the pi user to docker group so we can run Docker without sudo:
usermod -aG docker pi
To apply this change either reboot with reboot or log out and back in as pi.
Validate the Docker install and check version:
docker -v
Docker version 20.10.12, build e91ed57
Success! Docker Engine is installed and containerization awaits.
Step 3 – Install Docker Compose (Recommended)
While optional, I highly recommend also installing Docker Compose, an official Docker tool for simplifying multi-container application management using a docker-compose.yml file. Think of it as an orchestrator for juggling containers.
First ensure Python pip and setuptools are available on the system as Compose depends on them:
apt install -y python3-pip python3-setuptools
Then use pip3 to install the latest Docker Compose:
pip3 install docker-compose
Check we can access docker-compose and validate what version installed:
docker-compose version
docker-compose version 1.29.2, build 5becea4c
We will demonstrate basic Docker Compose usage later on.
Step 4 – Deploy Sample Containers
Alright, Docker Engine and Compose are in place – time to get our hands dirty by running some containers! I will demonstrate both standard docker run and compose file methodologies.
NGINX Web Server
Let‘s start easy by running the official NGINX web server image in a container:
docker run -d -p 80:80 --name webserver nginx
Breaking this down:
docker run= Run new container from an image-d= Detached/background mode-p 80:80= Map port 80 inside container to port 80 on host--name webserver= Name the container "webserver"nginx= Official Nginx container image name
Check out currently running containers:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2a583bde3b5 nginx "/docker-entrypoint...." About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80 webserver
And test by browsing either Pi‘s IP address or localhost which will hit the Nginx container:
Nginx Default Page Served from Docker Container on Raspberry Pi
Web server works! Now stop and remove the container:
docker stop webserver
docker rm webserver
Already we have successfully installed and run a containerized application, not having to worry about conflicts with existing Apache or Nginx on the OS. Now let‘s try something more complex.
Portainer Container Management GUI
When managing multiple containers and Docker environments, having a graphical UI makes life much easier. For that there‘s Portainer – an open source tool that itself runs within a container!
Use the following long docker run command to deploy Portainer to listen on port 9000:
docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
That‘s a lot to unpack so let‘s break this command down:
-d= detached/background mode-p 8000:8000= internal Portainer API port mapped to host port 8000-p 9000:9000= Portainer Web UI port mapped to host 9000--name portainer= friendly container name--restart=always= auto restart if stopped-v /var/run/docker.sock:/var/run/docker.sock= volume mount Docker socket for managing local Docker-v portainer_data:/data= named volume for persisting Portainer dataportainer/portainer-ce= Portainer community edition container image
Visit either the Pi‘s IP on port 9000 or http://localhost:9000 to begin Portainer setup:

Portainer Web Interface – Set Admin Password
Set a password for the admin user account to complete initialization.
We now have a handy GUI for monitoring containers, images, volumes and more! For example, clicking into Containers shows currently running:

Portainer Managing Docker Containers on Raspberry Pi
When finished managing containers with the UI, stop and remove as usual:
docker stop portainer
docker rm portainer
For multi-container applications, the graphical view Portainer provides becomes even more beneficial. Which brings us to…
Docker Compose Multi-Container Demo
For our last showcase, we will demonstrate Docker Compose bringing up an integrated WordPress site backed by MySQL database. Here is the docker-compose.yml file that links everything together:
version: ‘3‘
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: password
wordpress:
image: wordpress
depends_on:
- mysql
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: password
ports:
- 80:80
The YAML format allows us to define multiple services (containers) along with networking and dependencies between them.
To launch our WordPress stack:
docker-compose up -d
Compose handles all the heavy lifting – pulling images, starting linked containers for MySQL and WordPress, wiring up networking, etc. We visit IP address port 80 and go through WordPress initial site setup. The MySQL container hostname can simply be referenced as "mysql" thanks to the Docker internal DNS provided by Compose.

WordPress Install Accessing MySQL on Linked Docker Container
Tear it all down when finished:
docker-compose down
No need to worry about cleaning up orphaned containers or volumes, compose handles it all.
Docker Tips & Best Practices
Now that we have Docker up and running on the Pi, here are some handy pro-tips for working with containers:
Update the Docker Base OS Regularly
The Docker host OS forms the foundation all containers run on top of. Keep it patched by running apt update/upgrade monthly or any time major security fixes are announced. Reboot after OS updates.
Use Small Base Images
Size your custom dockerfiles FROM minimal base images like Debian or Alpine Linux when possible. This reduces attack surface and decreases IoT push/pull times.
Bind Mount Configs for Persistence
Use bind mounts (-v host_dir:container_dir) rather than baking config into custom images. This allows updating app config without rebuilding images.
Leverage Multi-Stage Builds
Install build tools and runtime dependencies in separate stages. This keeps production container lean by only copying essentials into the final stage.
Watch Container CPU & Memory Limits
New containers can easily overwhelm the Pi‘s limited resources if unrestrained. Set CPU shares and memory limits matching application requirements.
Implement Container Restarts
Crash-prone or memory leaky apps may require auto restart policies via Docker‘s --restart flag or Compose file. Plan to eventually fix the root application issue.
Consider Container Orchestration
As your Pi Docker footprint scales past experimentation, explore orchestrators like Docker Swarm or Kubernetes for complex deployments.
Recap and Final Thoughts
We took an in-depth look at properly installing and hardening Docker Engine, Docker Compose, and supporting packages on the versatile Raspberry Pi 4 hardware. With containers now unlocked, we deployed sample web servers, stood up Portainer for simplified management, and explored a multi-container WordPress stack via compose file.
Docker functionality vastly expands the use cases possible with inexpensive Raspberry Pi nodes. You can now sandbox complex applications, mimic production environments for testing, learn CI/CD pipelines, and more!
Some parting ideas for extending your Docker journey:
- Explore Docker networking to enable cross-container communication
- Build CI/CD pipelines around containerized apps with GitHub Actions
- Cluster multiple networked Pi‘s into affordable Docker Swarm setup
- Study Kubernetes and deploy Pis as lightweight worker nodes
- Package your own applications as efficient Docker images
I hope this 3049-word guide gives you confidence and a solid foundation for containerizing applications on the Raspberry Pi platform. Let me know if any questions come up as you being your Docker adventures!


