Here are a bunch of Docker related commands and scripts I never remember.
Create minimal Ubuntu image
Create a Dockerfile with the following:
# Use the official minimal Ubuntu base image
FROM ubuntu:20.04
# Set environment variables to avoid interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
# Update the package list and install necessary packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
vim \
&& apt-get clean && \
rm -rf /var/lib/apt/lists/*Build it:
docker build -t minimal-ubuntu .Create a docker-compose.yml:
version: '3.3'
services:
minimal-ubuntu:
image: minimal-ubuntu
container_name: my_minimal_ubuntu
networks:
- isolated_network
volumes:
- ./shared:/shared
stdin_open: true
tty: true
networks:
isolated_network:
external: trueCreate the container and shell into the container:
docker compose up -d
docker exec -it minimal-ubuntu bashOf course you can create even more minimal Ubuntu images, but they are usually missing too much functionality during the delevopment cycle. But if you want to either way, try this:
# Use the scratch base image
FROM scratch
# Copy the necessary files from a minimal Ubuntu installation
COPY --from=ubuntu:20.04 /bin /bin
COPY --from=ubuntu:20.04 /lib /lib
COPY --from=ubuntu:20.04 /lib64 /lib64
COPY --from=ubuntu:20.04 /usr /usr
COPY --from=ubuntu:20.04 /etc /etc
COPY --from=ubuntu:20.04 /var /var
# Set environment variables to avoid interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractiveCanonical officially publishes images that are ~30MB on Docker Hub. Alpine probably has seriously small images at ~3MB.
Find network interface for Docker network
If you don’t have Docker network yet, create one:
docker network create --driver=bridge isolated_networkNETWORK_NAME=isolated_network
docker network inspect $NETWORK_NAME | jq -r '.[0].Id' | cut -c1-12 | xargs -I {} ip link show | grep -oP 'br-\K\w+' | sort | uniq | grep -Ff <(docker network inspect $NETWORK_NAME | jq -r '.[0].Id' | cut -c1-12) | sed 's/^/br-/'Set NETWORK_NAME to whichever network you are looking for.
The output should be something like br-7bd541de061b.
Allow Docker network to access Internet, but block host and LAN access
First make sure forwarding is turned on:
sudo sysctl -w net.ipv4.ip_forward=1
# Make it permanent
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -pThen let’s update iptables.
Before we do that, let’s back up the existing iptables:
iptables-save > iptables-backup.rulesIf you ever need to restore the original iptables:
sudo iptables-restore < iptables-backup.rulesNow let’s make the necessary changes to the iptables:
# Drop traffic from the Docker network to the host's local addresses
sudo iptables -I INPUT -s 172.22.0.0/16 -m addrtype --dst-type LOCAL -j DROP
# Drop traffic to the LAN (private IP ranges) in the DOCKER-USER chain
sudo iptables -I DOCKER-USER 1 -i <DOCKER NETWORK INTERFACE> -d 192.168.0.0/16 -j DROP
sudo iptables -I DOCKER-USER 2 -i <DOCKER NETWORK INTERFACE> -d 10.0.0.0/8 -j DROP
sudo iptables -I DOCKER-USER 4 -i <DOCKER NETWORK INTERFACE> -d 172.16.0.0/12 -j DROP
# Allow traffic to the internet
sudo iptables -A FORWARD -i <DOCKER NETWORK INTERFACE> -o enp3s0f0 -j ACCEPT
sudo iptables -A FORWARD -i enp3s0f0 -o <DOCKER NETWORK INTERFACE> -m state --state ESTABLISHED,RELATED -j ACCEPT
# Enable IP masquerading for the Docker network
sudo iptables -t nat -A POSTROUTING -s 172.22.0.0/16 ! -o <DOCKER NETWORK INTERFACE> -j MASQUERADEReplace <DOCKER NETWORK INTERFACE> with the network interface (like br-7bd541de061b) for your Docker network.
Run a shell in your Docker container and make sure the iptables changes work.
To persist the iptables now:
iptables-save > /etc/iptables/rules.v4Make sure you have netfilter-persistent and iptables-persistent installed. If not:
sudo apt install iptables-persistent netfilter-persistentThen verify netfilter-persistent is running:
sudo systemctl status netfilter-persistentIf not, enable it:
sudo systemctl enable netfilter-persistentReboot to make sure it works.
Find space taken by docker logs
sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"Truncate docker logs
truncate -s 0 /var/lib/docker/containers/**/*-json.logFind space used by journalctl
journalctl --disk-usageSet max size of journalctl log files
journalctl --vacuum-size=50MStop all containers specific to image
docker ps -a -q --filter ancestor=archivebox/archivebox:master | xargs docker stopRemove all containers specific to an image
Use the stop command above first, then run the following:
docker ps -a -q --filter ancestor=archivebox/archivebox:master | xargs docker rmPodman rootless: overlayfs: fs on ‘/home/…’ does not support file handles, falling back to xino=off
Edit (or create) ~/.config/containers/storage.conf and put this in there:
[storage]
driver = "overlay"
[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"Podman rootless: The cgroupv2 manager is set to systemd but there is no systemd user session available
When trying to create a container, if you see this:
WARN[0000] The cgroupv2 manager is set to systemd but there is no systemd user session available
WARN[0000] For using systemd, you may need to login using an user session
WARN[0000] Alternatively, you can enable lingering with: `loginctl enable-linger 1002` (possibly as root)
WARN[0000] Falling back to --cgroup-manager=cgroupfs
WARN[0000] The cgroupv2 manager is set to systemd but there is no systemd user session available
WARN[0000] For using systemd, you may need to login using an user session
WARN[0000] Alternatively, you can enable lingering with: `loginctl enable-linger 1002` (possibly as root)
WARN[0000] Falling back to --cgroup-manager=cgroupfs
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob c1ec31eb5944 done
Copying config d2c94e258d done
Writing manifest to image destination
Storing signatures
Do actually what line 3 says. Run the following:
loginctl enable-linger $USERDon’t substitute for $USER, leave it as a variable.
This problem to occur if you sudo as the user. If you directly login with ssh, you don’t get these errors.
Podman rootless: Error validating CNI config file [plugin bridge does not support config version “1.0.0”…
This is tested on Ubuntu 22.04 running Podman 3.4.4.
When trying to create a new network for a rootless Podman container, you might get the following error:
WARN[0000] Error validating CNI config file /home/user/.config/cni/net.d/n1.conflist: [plugin bridge does not support config version "1.0.0" plugin portmap does not support config version "1.0.0" plugin firewall does not support config version "1.0.0" plugin tuning does not support config version "1.0.0"]Change "cniVersion": "1.0.0" in your ~/.config/net.d/<network name>.conflist to "cniVersion": "0.4.0". Then do a podman network ls to make sure there are no more errors.
Podman 5 on Ubuntu
None of the Ubuntu repositories have the latest version of podman.
Thankfully someone is maintaining a static binary that works: mgoltzsche/podman-static.