package main
import (
"fmt"
"log"
"net/http"
)
const color = "blue7"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from app1 with COLOR=%s", color)
})
log.Fatal(http.ListenAndServe(":80", nil))
}
The build finishes in less than a second on my macOS system:
$ sw_vers
ProductName: macOS
ProductVersion: 13.6
BuildVersion: 22G120
$ time go build app1.go
real 0m0.084s
user 0m0.117s
sys 0m0.183s
But with the following multi-stage Dockerfile, the build takes about 1 minute:
FROM golang AS builder
WORKDIR /code
COPY app1.go .
RUN go build app1.go
FROM debian
WORKDIR /app
COPY --from=builder /code/app1 .
EXPOSE 80
ENTRYPOINT ["/app/app1"]
Thank you for considering my issue! Dang, that’s rough to hear; it’s a bummer that after all these years I find myself on the other side of well it works on my computer lol. I wonder what the important difference is. What sort of mac do you have?
I cranked up all my CPU and memory to full—see screenshot. Surprisingly, no time improvement—see shell session and notice that I included my machine details.
$ docker build -t app1 .
[+] Building 51.3s (13/13) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 206B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/debian:latest 0.0s
=> [internal] load metadata for docker.io/library/golang:latest 0.0s
=> [builder 1/4] FROM docker.io/library/golang 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 302B 0.0s
=> [stage-1 1/3] FROM docker.io/library/debian 0.0s
=> CACHED [builder 2/4] WORKDIR /code 0.0s
=> [builder 3/4] COPY app1.go . 0.0s
=> [builder 4/4] RUN go build app1.go 51.2s
=> CACHED [stage-1 2/3] WORKDIR /app 0.0s
=> [stage-1 3/3] COPY --from=builder /code/app1 . 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:590ef784d9dc0aa6ba880f786c9a4ccddd94a065d220c 0.0s
=> => naming to docker.io/library/app1 0.0s
$ neofetch --off
max@mac2021.local
-----------------
OS: macOS 13.6 22G120 arm64
Host: MacBookPro18,1
Kernel: 22.6.0
Uptime: 2 days, 1 hour, 41 mins
Packages: 121 (brew)
Shell: bash 5.2.15
Resolution: 2056x1329
DE: Aqua
WM: Quartz Compositor
WM Theme: Blue (Dark)
Terminal: iTerm2
Terminal Font: Monaco 12
CPU: Apple M1 Pro
GPU: Apple M1 Pro
Memory: 3470MiB / 32768MiB
Edit: I kept at it and searched around my env vars for anything relevant and I notice that I set DOCKER_DEFAULT_PLATFORM=linux/amd64 env var; when I unset that env, then I went down to 3 seconds!
So case closed: Resolution: linux/amd64 Go builds under Docker on Apple M1 Pro (arm) are slow; avoid pinning the platform to linux/amd64 with the DOCKER_DEFAULT_PLATFORM=linux/amd64 env var.
People often say that when you use Docker everything runs the same way on every machine. That is not true it just gives you a better chance to run the same way on different machines.
MacBook Air with the M1 chip
Emulation was my first guess, but then I saw golang was supported on arm, so I thought that couldn’t be the problem. Good that you found the env variable. Emulated processes are always at least a little slower depending on what has to be emulated.