Community Tutorials Alpine Linux How to Run Alpine Linux in a Docker Container
How to Run Alpine Linux in a Docker Container
ALPINE LINUX

How to Run Alpine Linux in a Docker Container

SKYLINE Knowledge Base
Photo by Praveen Thirumurugan on Unsplash

A field-tested, step-by-step guide. How to Run Alpine Linux in a Docker Container — prerequisites, the actual commands, verification, and links to related Alpine Linux topics.

Alpine's ~7 MB base image is why so many Dockerfiles start with FROM alpine:3.20. This guide writes a sane Alpine-based image, explains the musl-vs-glibc traps, and shows the patterns that keep image size honest.

Prerequisites

  • Docker (or Podman) installed locally — see Docker + Compose on Ubuntu.
  • A small app to package — we will use a Python Flask hello-world.

Step 1: A minimal Dockerfile

# syntax=docker/dockerfile:1.7
FROM alpine:3.20

RUN apk add --no-cache python3 py3-flask

WORKDIR /app
COPY app.py .

EXPOSE 5000

USER nobody
CMD ["python3", "app.py"]

app.py:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello from Alpine\n"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Build and run:

docker build -t skyline/hello-alpine .
docker run --rm -p 5000:5000 skyline/hello-alpine
curl http://localhost:5000/

Image size:

docker images skyline/hello-alpine
# Expect ~ 80 MB total (Alpine + Python).

Step 2: musl vs glibc — the one trap you must know

Alpine uses musl libc, not glibc. Most software is fine; pre-compiled glibc binaries (some commercial DBs, NodeJS native modules) will fail with cryptic errors. Two fixes:

  1. Build inside Alpine — set up the build chain in a multi-stage build (see Step 4).
  2. Use a glibc-based basedebian:slim is ~30 MB more but accepts every binary.

Quick way to detect a glibc binary:

docker run --rm -v $(pwd):/check alpine sh -c 'apk add --no-cache file && file /check/your-binary'

If file reports interpreter /lib64/ld-linux-x86-64.so.2 you have glibc — Alpine has no such loader.

Step 3: --no-cache everywhere

RUN apk add --no-cache curl jq        # no apk cache → smaller layer

For ephemeral build dependencies, use virtual packages:

RUN apk add --no-cache --virtual .build-deps gcc musl-dev make \
 && pip install --no-cache-dir uvicorn \
 && apk del .build-deps

That installs the build chain, builds the wheel, deletes the build chain — all in one layer, so the final image stays small.

Step 4: Multi-stage builds for compiled languages

# --- build stage ---
FROM golang:1.22-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags='-s -w' -o /out/app ./cmd/api

# --- runtime stage ---
FROM alpine:3.20
RUN apk add --no-cache ca-certificates
COPY --from=build /out/app /usr/local/bin/app
USER nobody
ENTRYPOINT ["/usr/local/bin/app"]

Final image is ~12 MB even with Go's static runtime included.

Step 5: Useful Alpine quirks

  • /bin/sh is ash, not bash. Either install bash (apk add bash) or write POSIX-compliant scripts.
  • No useradd by default — use addgroup + adduser (BusyBox flags):
RUN addgroup -S app && adduser -S -G app app
USER app
  • timezone data is not installed by default. Add tzdata:
RUN apk add --no-cache tzdata && \
    cp /usr/share/zoneinfo/Asia/Riyadh /etc/localtime && \
    echo "Asia/Riyadh" > /etc/timezone
  • Health checks work normally:
HEALTHCHECK --interval=30s --timeout=5s CMD wget -qO- http://localhost:5000/ || exit 1

Step 6: Lock the base image

Pin the digest, not just the tag, for reproducible builds:

FROM alpine:3.20@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5

Bump the digest deliberately, in a code review, not silently.

Verify

docker images skyline/hello-alpine --format 'table {{.Repository}}\t{{.Size}}'
docker run --rm skyline/hello-alpine id    # confirm non-root user
docker scout cves skyline/hello-alpine     # vulnerability scan

Conclusion

Alpine is a great default for stateless containers — small surface, fast pulls, decent security defaults. Reach for debian:slim instead the moment you need a glibc binary, native NodeJS modules, or libraries that bundle their own libc.

Next steps

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Alpine Linux for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.