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 
Edit