Docker
Multi-Stage Docker Builds
https://docs.docker.com/develop/develop-images/multistage-build/
Without multi-stage builds, this was the only reasonable way to package up a go binary (for example) for production:
# Dockerfile.build
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
&& CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
# Dockerfile
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]
And you needed a script to pass artifacts between these “stages”:
#!/bin/sh
echo Building alexellis2/href-counter:build
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
-t alexellis2/href-counter:build . -f Dockerfile.build
docker container create --name extract alexellis2/href-counter:build
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker container rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app
It’s annoying to have to use two files and a script for this, so multi-stage builds allow you to represent this workflow in a single Dockerfile
:
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
And build with:
$ docker build -t alexellis2/href-counter:latest .
Connect to a Docker Daemon on Windows 10
The Docker for Desktop installation on Windows 10 ignores the hosts
setting, so you can’t directly use DOCKER_HOST
from outside the machine. There’s a container that sets this up automatically, though, so this is possible without too much extra effort. This assumes that Docker for Desktop is using the WSL2 engine, not the Hyper-V one.
## In WSL
❯ docker run -d
--name docker-remote-api
-p 2377:2375
--restart unless-stopped
-v /var/run/docker.sock:/var/run/docker.sock
jarkt/docker-remote-api
## In an elevated Windows (powershell/cmd) prompt
## Forward external requests for port 2377 into WSL
## Get `wsl_addr` by running `ip a` inside WSL
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=2377 connectaddress=<wsl_addr> connectport=2377
## Externally
❯ DOCKER_HOST=tcp://10.0.0.9:2377 docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ead1ed00d0f5 jarkt/docker-remote-api "/bin/sh -c 'socat T…" 4 seconds ago Up 2 seconds 0.0.0.0:2377->2375/tcp docker-remote-api