Container images practice
Build two images, verify the application, inspect its configuration and clean up. Allow about 25 minutes.
Review the container images lessonPrepare your workspace
You need a running Docker engine with Linux containers, internet access, curl and a free local port 8083. No Kubernetes cluster or registry account is needed. Commands run in your terminal, not in this page. Keep all five files below in a new directory and run the commands there. Use the reserved exercise names only for this lab; if they already exist, choose new names consistently.
Starter files (5)
module example.com/academy-web
go 1.26.0package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from Proxy Academy")
})
server := &http.Server{
Addr: ":8080",
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
}
log.Fatal(server.ListenAndServe())
}FROM golang:1.26-alpine
WORKDIR /src
COPY go.mod main.go ./
RUN CGO_ENABLED=0 go build -trimpath -o /server .
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/server"].git
.env
.env.*
*.pem
*.key
bin/
coverage/FROM golang:1.26-alpine AS build
WORKDIR /src
COPY go.mod main.go ./
RUN CGO_ENABLED=0 go build -trimpath -o /server .
FROM scratch AS runtime
COPY --from=build /server /server
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/server"]docker build -t academy-container-lab:single .
docker build -f Dockerfile.multistage -t academy-container-lab:multi .
docker image ls academy-container-labBoth tags should exist. Compare their SIZE values; the multistage image should be smaller. Exact sizes vary.docker run -d --name academy-container-lab -p 127.0.0.1:8083:8080 academy-container-lab:multi
curl --fail http://127.0.0.1:8083Hello from Proxy Academydocker image inspect academy-container-lab:multi --format '{{.Config.User}}'65532:65532docker tag academy-container-lab:multi academy-container-lab:release
docker image inspect academy-container-lab:multi academy-container-lab:release --format '{{.Id}}'Two identical image IDs. Their exact value depends on your build.docker stop academy-container-lab
docker rm academy-container-lab
docker image rm academy-container-lab:single academy-container-lab:multi academy-container-lab:releaseThe exercise container and image references are removed. Build cache may remain.Explain your result
Why can both images serve the same response while having different sizes? Why does the second tag keep the same image ID? What would be required to make this image available to a different machine?
Compare your explanation
Both contain the server executable; the single-stage image also retains the build tools. A tag adds a reference without rebuilding. Another machine needs access to the image, typically through a registry after a push, with credentials for private images and a compatible platform.