While I get my fair share of Docker learning done via self-hosting, I’ve also been acquiring new knowledge at work recently. One of these new bits is Docker-outside-of-Docker (DooD).
It sounds weird, but it makes sense once you see why it can be required.
Here’s a high level overview:
- We have an app that can be built into a Docker image and run via docker-compose.
- We want to host a CI/CD server that itself is a Docker container.
- The CI/CD server must be able to create our app’s Docker image, optionally run the containers as defined in the app’s docker-compose file, and make both of these available to the host.
On the host, maybe you’ve got a reverse proxy set up, or maybe you want to directly make it available to the web without going through your CI/CD server. Perhaps you just want to be able to access the built and tagged images. It would not make sense for these images to live inside of our CI/CD container’s docker.
This is quick to set up. Bind the Docker UNIX socket from the host to the container:
// docker-compose.yml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Done! Now when you run docker or docker-compose from inside your container, it’ll talk to your host system’s docker. So when the CI container builds a Docker image, it uses the host docker to do so.
I would encourage further reading on sockets:
- What is a socket?
- What is the difference between a port and a socket?
- What is the difference between Unix sockets and TCP/IP sockets?