Raspberry Pi 4 & Docker Config
Netplan
sudo touch /etc/netplan/99-network-config.yaml
sudo vi /etc/netplan/99-network-config.yaml
# This file is generated from information provided by the datasource.
Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the
following:
# network: {config: disabled}
network:
     version: 2
     wifis:
         renderer: networkd
         wlan0:
              access-points:
                   tchapman:
                       password:
b652401c67d806916374c87a41253762c64dd1f4dc86031a63c89becf6
1ec853
              dhcp4: true
              dhcp6: false
              accept-ra: false
              optional: true
              nameservers:
                addresses:
                - 192.168.1.99
                - 127.0.0.1
                - 1.1.1.1
     ethernets:
       eth0:
         addresses:
           - 192.168.1.100/24
         routes:
           - to: default
              via: 192.168.1.1
         nameservers:
           addresses:
            -   192.168.1.100
            -   127.0.0.1
            -   1.1.1.1
            -   1.0.0.1
sudo Netplan apply
Install glances (like top, but better!)
sudo apt install -y glances vim docker.io
Overclock RPI4
/boot/firmware/config.txt
[pi4]
max_framebuffers=2
# arm_boost=1
over_voltage=7
arm_freq=2200
gpu_freq=750
gpu_mem=128
force_turbo=1
Reboot
Test
sudo apt install -y stress
then
vcgencmd measure_clock arm
Output should look like:
tchapman@raspi:~$ vcgencmd measure_clock arm
frequency(48)=2200499968
tchapman@raspi:~$ vcgencmd measure_clock arm
frequency(48)=2200552704
tchapman@raspi:~$ vcgencmd measure_clock arm
frequency(48)=2200552704
tchapman@raspi:~$ vcgencmd measure_clock arm
frequency(48)=2200552704
tchapman@raspi:~$ vcgencmd measure_clock arm
frequency(48)=2200552704
tchapman@raspi:~$
Check temps:
watch -n 1 vcgencmd measure_temp
Make sure temps aren’t regularly over 80c.
Configure Docker
sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
sudo reboot
docker run hello-world
Multicontainer config
sudo apt install docker-compose -y
Docker Commands
Here are the most important commands to practice:
•   docker pull <image>: Pull a container image.
•   docker run <options> <image>: Run a container.
•   docker ps: List running containers.
•   docker ps -a: List all containers.
•   docker stop <container_id>: Stop a container.
•   docker rm <container_id>: Remove a container.
•   docker images: List downloaded images.
•   docker rmi <image_id>: Remove an image.
Docker Adguard
mkdir ~/adguard-data
docker run -d \
  --name adguardhome \
    -v ~/adguard-data:/opt/adguardhome/work \
    -v ~/adguard-data:/opt/adguardhome/conf \
    --network host \
    -p 3000:3000 \
    -p 53:53/tcp \
    -p 53:53/udp \
    -p 80:80 \
    -p 443:443 \
    --restart unless-stopped \
    adguard/adguardhome
◦     Or, better yet:
docker rm -f adguardhome
docker run -d \
  --name adguardhome \
  -v ~/adguard-data:/opt/adguardhome/work \
  -v ~/adguard-data:/opt/adguardhome/conf \
  --network host \
  --restart unless-stopped \
  adguard/adguardhome
-d: Run in detached mode (in the background).
--name: Assigns a name to the container.
-v: Maps volumes for persistent data.
-p: Maps host ports to container ports.
--restart unless-stopped: Ensures AdGuard restarts on reboots.
Connect to AdGuard
http://<raspberry_pi_ip>:3000
⁃   192.168.1.100:3000
Docker - check services
docker ps -a
tchapman@raspi:~$ docker ps -a
CONTAINER ID IMAGE                COMMAND
CREATED      STATUS         PORTS    NAMES
ff05d5772a30 adguard/adguardhome "/opt/adguardhome/Ad…"
9 hours ago Up 54 seconds          adguardhome
tchapman@raspi:~$
If stopped
docker start adguardhome
resolv.conf
sudo rum -rf /etc/resolv.conf
sudo touch /etc/resolv.conf
sudo vi /etc/resolve.conf
nameserver 192.168.1.100
nameserver 127.0.0.1
nameserver 1.1.1.1
Docker - Portainer
docker run -d \
  --name=portainer \
  -p 8000:8000 \
  -p 9443:9443 \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest
Explanation:
•   -p 8000:8000: Port for internal communications (not commonly
used by users).
•   -p 9443:9443: Port for accessing the web interface (HTTPS).
•   -v /var/run/docker.sock:/var/run/docker.sock: Allows Portainer to
control Docker.
•   -v portainer_data:/data: Persistent storage for Portainer’s data.
Docker - metube (download YouTube videos)
mkdir -p ~/metube/config ~/metube/downloads
docker run -d \
  --name=metube \
  -p 8081:8081 \
 -v /home/tchapman/metube/config:/app/config \
 -v /home/tchapman/metube/downloads:/app/downloads \
 -e DOWNLOAD_DIR="/app/downloads" \
 -e STATE_DIR="/app/downloads/.metube" \
 -e TEMP_DIR="/app/downloads/tmp" \
 --restart unless-stopped \
 alexta69/metube
Explanation:
•   -d: Runs the container in detached mode.
•   --name=metube: Names the container "metube".
•   -p 8081:8081: Maps port 8081 of the host to port 8081 of the
container.
•   -v ~/metube/config:/app/config: Mounts the host directory
~/metube/config to the container's /app/configdirectory.
•   -v ~/metube/downloads:/app/downloads: Mounts the host directory
~/metube/downloads to the container's /app/downloads directory.
•   --restart unless-stopped: Ensures the container restarts
automatically unless it is explicitly stopped.
•   set variables as per: https://github.com/alexta69/metube
•      -e DOWNLOAD_DIR="/app/downloads" \
•      -e STATE_DIR="/app/downloads/.metube" \
•      -e TEMP_DIR="/app/downloads/tmp" \
Docker — Github access needed!
Authenticate with GitHub Container Registry
GitHub Container Registry may require authentication. You’ll need a
GitHub Personal Access Token to log in.
1. Generate a Personal Access Token (PAT):
•   Go to GitHub Settings → Developer Settings → Personal Access
Tokens.
•   Click Generate New Token and set the following:
•   Scopes: Enable read:packages to allow access to container
images.
•   Set an expiration (e.g., 30 days).
•   Copy the token (you won’t see it again).
2. Log in to ghcr.io: Run the following command and use your
GitHub username and the generated token as the password:
docker login ghcr.io
username: heytchap
token:
github_pat_11AB655KY0qSJ0ltlIlfP8_93viPZ84p9lsq8W3M9CUGKik4YHv
aMj2XvJKCYKHSW5W4OB6WECrK2t0Elh
Docker - SMB container
If you want to write to the smb share, do this:
sudo chown -R tchapman /home/tchapman/
chmod -R 777 /home/tchapman
Otherwise, just proceed:
docker run -d \
  --name samba \
  -p 139:139 \
  -p 445:445 \
  -v /home/tchapman:/mount \
  --restart unless-stopped \
  dperson/samba \
  -u "tchapman;comma1" \
  -s "home;/mount;yes;no;no"
Key Adjustments
1. User (USER and -u):
•    Set USER="tchapman" to match your Raspberry Pi username.
•    Update -u "tchapman;your_password" with the same username
and password to simplify access.
2. Share Name:
•    Changed the share name to home (-s "home;/mount;yes;no;no").
•    The share name can be anything meaningful, but naming it home
is intuitive for your home directory.
3. Password (PASS):
•    Replace your_password with the desired password for accessing
the share.
Make the smb container writable!
docker exec -it samba bash
vi /etc/samba/smb.conf
[home]
  path = /mount
  browseable = yes
  writable = yes
  read only = no
smbd reload - restart the service
To be sure - docker restart samba
sudo ufw allow 139/tcp
sudo ufw allow 445/tcp
cmd+k, connect to samba.
Local Python 3!
docker pull python:3.11-slim
docker run -it \
  -v ~/Python_Holder:/usr/src/app \
  -w /usr/src/app \
  --name Python-Environment \
  python:3.11-slim
Attach with
docker start -ai Python-Environment
Detach with:
ctrl+d
Completely remove with
docker rm Python-Environment
Fail2Ban
docker run -d \
  --name=fail2ban \
  -v ~/fail2ban/data:/data \
  -v /var/log:/var/log:ro \
  --restart=unless-stopped \
  crazymax/fail2ban:latest
Move `jail.conf` from docker to core OS.
docker cp fail2ban:/etc/fail2ban/jail.conf ~/fail2ban/data/jail.local
Then reconfig
docker run -d \
  --name fail2ban \
  --network host \
  -v fail2ban-data:/config \
  -v ~/fail2ban/data/jail.local:/etc/fail2ban/jail.local \
  -v /var/log:/var/log:ro \
  -v /etc/fail2ban:/etc/fail2ban \
  --restart unless-stopped \
  crazymax/fail2ban:latest
docker run -d \
  --name fail2ban \
  --network host \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  -v ~/fail2ban/data:/etc/fail2ban \
  -v /var/log/auth.log:/var/log/auth.log:ro \
  --restart unless-stopped \
  crazymax/fail2ban:latest
SCRIPT!
#!/bin/bash
# Exit on error
set -e
echo "Starting Raspberry Pi configuration..."
# Step 1: Configure Network with Netplan
echo "Configuring Netplan..."
NETPLAN_FILE="/etc/netplan/99-network-config.yaml"
sudo touch $NETPLAN_FILE
cat <<EOL | sudo tee $NETPLAN_FILE
network:
    version: 2
    wifis:
        renderer: networkd
        wlan0:
              access-points:
                  tchapman:
                       password:
b652401c67d806916374c87a41253762c64dd1f4dc86031a63c89becf6
1ec853
              dhcp4: true
              dhcp6: false
              accept-ra: false
              optional: true
              nameservers:
                addresses:
                - 192.168.1.99
                - 127.0.0.1
                - 1.1.1.1
    ethernets:
      eth0:
        addresses:
           - 192.168.1.100/24
        routes:
           - to: default
              via: 192.168.1.1
        nameservers:
           addresses:
              - 192.168.1.100
              - 127.0.0.1
              - 1.1.1.1
              - 1.0.0.1
EOL
sudo netplan apply
# Step 2: Update and Upgrade System
echo "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
# Step 3: Install Tools and Overclock RPi
echo "Installing necessary tools and configuring overclocking..."
sudo apt install -y vim glances stress
PI_CONFIG="/boot/firmware/config.txt"
sudo sed -i '/\[pi4\]/a max_framebuffers=2\nover_voltage=7\
narm_freq=2200\ngpu_freq=750\ngpu_mem=128\nforce_turbo=1'
$PI_CONFIG
echo "Overclock settings applied. A reboot will finalize them."
# Step 4: Enable SSH
echo "Enabling SSH..."
sudo systemctl enable ssh
sudo systemctl start ssh
# Step 5: Install and Enable Docker
echo "Installing Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Step 6: Run Docker Containers
echo "Running Docker containers..."
# AdGuardHome
mkdir -p ~/adguard-data
docker rm -f adguardhome || true
docker run -d \
  --name adguardhome \
  -v ~/adguard-data:/opt/adguardhome/work \
  -v ~/adguard-data:/opt/adguardhome/conf \
  --network host \
  --restart unless-stopped \
  adguard/adguardhome
# Portainer
docker rm -f portainer || true
docker run -d \
  --name=portainer \
 -p 8000:8000 \
 -p 9443:9443 \
 --restart=always \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v portainer_data:/data \
 portainer/portainer-ce:latest
# MeTube
mkdir -p ~/metube/config ~/metube/downloads
docker run -d \
  --name=metube \
  -p 8081:8081 \
  -v /home/tchapman/metube/config:/app/config \
  -v /home/tchapman/metube/downloads:/app/downloads \
  -e DOWNLOAD_DIR="/app/downloads" \
  -e STATE_DIR="/app/downloads/.metube" \
  -e TEMP_DIR="/app/downloads/tmp" \
  --restart unless-stopped \
  alexta69/metube
# Samba
docker rm -f samba || true
docker run -d \
  --name samba \
  -p 139:139 \
  -p 445:445 \
  -v /home/tchapman:/mount \
  --restart unless-stopped \
  dperson/samba \
  -u "tchapman;comma1" \
  -s "home;/mount;yes;no;no"
echo "Configuring Samba for writable access..."
sudo chown -R tchapman /home/tchapman
chmod -R 777 /home/tchapman
# Fail2Ban
docker pull crazymax/fail2ban:latest
docker run -d \
  --name=fail2ban \
  -v ~/fail2ban/data:/data \
    -v /var/log:/var/log:ro \
    --restart=unless-stopped \
    crazymax/fail2ban:latest
# Step 7: Reboot to Apply Changes
echo "Setup complete. Rebooting to apply changes..."
sudo reboot