I see many developers using Docker wrong. They still run everything locally, and only use Docker in the CI/CD pipeline. While this has it's benefits, there's still a lot of potential being missed.
It goes without saying that the title is a bit of a hyperbole, but I do see a lot of developers using Docker in a bit of a strange way. There's a Dockerfile/Docker compose file present, but the developers never use it. They run everything 100% locally on the machine, the Dockerfile is just used in the CI/CD pipeline. I think this misses a large point of Docker, let's get into it.
Preqrequisites
Docker or Podman.
Why use Docker?
An infamous phrase in software development you've probably heard before:
"It works on my machine."
While it's often used as a joke, this issue is probably more often a real one, stealing unnecessary time and causing headaches. Docker was supposed to solve this problem by making it work on your machine, then shipping your machine to the server/other developers, figuratively of course (or maybe literally?). However, if you don't use Docker locally, you're not shipping your guaranteed-to-work machine, you're still doing things the "old way", but with extra complexity mixed in.
How to properly use Docker
There are many ways to do this, but here's my preferred way:
- Create a folder in your project called
docker. - In this folder, create a
Dockerfile.localand adocker-compose.local.yml. - In the
Dockerfile.local, include the main dependencies like Node:20 or Python:3.8. - In the
docker-compose.yml, include the services you need, like a database, a backend, and a frontend. Then crucially, include avolumessection to mount your code into the container. - Now, when you want to run your app, you just run
docker-compose -f docker-compose.local.yml up -din thedockerfolder, and you should have a running container. - You can now connect to the container, and install your dependencies, run your tests, and start your app.
With this setup you no longer need to use tools like nvm, pyenv, jenv, etc. No more need to pollute your machine with 5 versions of Node, 3 versions of Python, and 2 versions of Java. The only dependency you need is Docker. This has several benefits; you can easily switch between projects without having to worry about different versions of dependencies, you can easily onboard new developers, and you can easily run your app in CI/CD for more than just production builds.
Example setup
/docker/Dockerfile.local:
FROM node:20-alpine
WORKDIR /app
EXPOSE 3000
CMD ["sh"]
Notice how we don't copy over any files, we'll mount the code as a volume instead.
/docker/docker-compose.local.yml:
version: '3.1'
services:
name-of-your-service:
build:
context: .
dockerfile: Dockerfile.local
ports:
- '3000:3000'
volumes:
- ../:/app # Mount the code into the container
tty: true
With this volume setup, your whole project becomes available inside the container. Any change you do on your local machine is immediately reflected in the container.
IDE integration
With this setup one challenge remains, many languages require you to install an SDK to get code completion (like intelliSense) in your IDE. With VS Code (or it's forks) this is pretty easy to solve, rename the docker folder to .devcontainer and add a devcontainer.json file with content like this:
{
"name": "Name of Your Service",
"workspaceFolder": "/app",
"context": ".",
"dockerComposeFile": ["docker-compose.local.yml"],
"service": "name-of-your-service", // Same as the docker-compose.local.yml
"extensions": [
"ms-azuretools.vscode-docker",
"nhoizey.gremlins",
"etc..."
],
"shutdownAction": "stopCompose",
"forwardPorts": [3000],
"remoteUser": "root"
}
With this setup in VS Code you get a fully reproducible containerized developer environment. I'm unfortunately not well versed enough in other IDE's to say how you can do this kind of setup, but there is an open source project called DevPod which is supposed to work with any IDE and uses devcontainer.json.
End notes
Docker is a very powerful tool, and hopefully this article has shown you how to use it more effectively for your local development environment. If you have any questions or feedback, feel free to reach out to me on X.