This episode runs containers on Alpine: installing Docker with OpenRC, using the daemonless and rootless Podman, using alpine:latest as a base image, and building multi-stage images with apk add --no-cache.

Alpine and containers are nearly identical twins: Alpine images are small, secure, and quick to pull. Episode 16 uses Alpine both as a container host and as a base image. You'll learn to install Docker, use the daemonless Podman, and build minimal images with multi-stage techniques.
After this episode, you'll be able to run and build containers on Alpine with two different runtimes, and understand why so many real-world Dockerfiles start with FROM alpine.
Docker is available in Alpine's community repository. Install and enable it:
apk add docker docker-cli-compose
rc-service docker start
rc-update add docker default
docker versionExplanation:
docker-cli-compose provides the compose plugin.rc-update add docker default runs the daemon at boot.docker version verifies the client and server.Run your first container:
docker run --rm alpine:latest echo "hello from alpine"
docker run -d -p 8080:80 --name web nginx
docker psdocker run -d -p 8080:80 --name web nginx runs nginx on port 8080. Don't forget to open the port in the nft firewall from episode 10 if the container needs to be reachable from outside.
Podman offers command compatibility with Docker without a central daemon. Install and test it:
apk add podman
podman info
podman run --rm alpine:latest echo "hello from podman"Podman's advantages:
For regular users, set up rootless Podman:
adduser -G podman arman
podman system migrateadduser -G podman arman adds the user to the podman group so they can manage containers.
The alpine:latest image is only about 5 MB, making it the most popular base image in the container world. Look inside the image:
docker run --rm alpine:latest sh -c "cat /etc/alpine-release; apk --version"
docker imagesTo compare sizes, pull another distro's image:
docker pull debian:bookworm-slim
docker images | grep -E "alpine|debian"The docker images output shows the striking size difference between alpine and debian-slim.
Write a Dockerfile that installs packages with apk add --no-cache:
FROM alpine:latest
RUN apk add --no-cache nginx && \
mkdir -p /run/nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]apk add --no-cache prevents package index storage that would bloat the image. Build and run it:
docker build -t my-web .
docker run -d -p 8081:80 --name myweb my-web
curl -s http://localhost:8081/The curl -s http://localhost:8081/ output shows the index page copied into the image.
Multi-stage separates the build and runtime, producing a very small final image:
FROM golang:1.24-alpine AS builder
WORKDIR /src
COPY main.go .
RUN go build -o /app/app
FROM alpine:latest
COPY --from=builder /app/app /usr/local/bin/app
ENTRYPOINT ["app"]COPY --from=builder /app/app /usr/local/bin/app only copies the built binary to the runtime stage, without the Go toolchain.
Tip
The apk add --no-cache habit in Dockerfiles not only prevents the index from being stored, but also ensures the layer order caches well. Put package installation before the COPY of source so source changes don't trigger reinstalls.
Episode 16 ran containers on Alpine: installing Docker with OpenRC, using the daemonless and rootless Podman, understanding the advantages of the alpine:latest base image, and building images with apk --no-cache and multi-stage builds.
Key takeaways:
In the next episode, episode 17, we'll cover Alpine 3.24 and its newest features — what's new in the June 2026 release, Alpine 3.23's legacy of apk v3 and linux-stable, and how to upgrade between major versions safely.