Reputation: 576
In the Dev Containers's document it said The Visual Studio Code Dev Containers extension lets you use a container as a full-featured development environment
. In my understanding, it creates a container that contain all required resourses/library to develop an application locally. Isn't this the exact purpose of Docker and Docker Compose? Not to mention that Dev Container aslo require Docker and dockerfile.
At the end of the day their purpose was to allow developer to instant start a development environtment without worrying about dependencies. So what exactly is the difference between these two?
Upvotes: 27
Views: 12992
Reputation: 159750
Docker is not principally a developer tool, and the main goal of Compose is not to spin up a developer environment.
In fact, Docker has a couple of core features that seem contrary to using it as a developer environment. Each container has an isolated filesystem, so the container can't normally see code on the host system, and the host system can't see tools that are only installed in the container. Furthermore, a container is based on an immutable image: you can't normally change the code a container is running without rebuilding the image and recreating the container. This is a familiar workflow for developers using compiled languages (C++, Java, Go, Rust), where even without Docker you still need to recompile and restart the application after every change.
A good example of this more typical immutable-image setup is running a database container. You'll very frequently run
docker run -d -p 5432:5432 -v pgdata:/var/lib/postgresql/data postgres:14
but to run this you do not need to download PostgreSQL's source code, and in normal use you can interact with it entirely through the published port. The image itself does not contain any source code or build tools.
On top of this you can use Compose to build up larger applications built out of multiple containers; for example
version: '3.8'
volumes:
pgdata:
services:
db:
image: postgres:14
ports: ['5432:5432']
volumes: ['pgdata:/var/lib/postgresql/data']
app:
image: registry.example.com/myapp:${MYAPP_TAG:-latest}
ports: ['8000:8000']
depends_on: [db]
environment: {PGHOST: db}
Again, this setup doesn't depend on having any of the source code available; so long as you have a prebuilt image you can just run this.
Especially if you do have an interpreted language, it's possible to inject your local source code over the code in the image using a bind mount. If you do this, the container is running the code you have on your host system. You see this fairly often for Node-based applications
services:
app:
build: .
ports: ['3000:3000']
volumes:
- .:/app # replace everything in the image with local code
- /app/node_modules # hack: use an anonymous volume rather than host library tree
However, even with this, you can't directly interact with the tools inside the container. I see several SO questions about wanting to use a Docker-based setup instead of host-based tools, and you sort of can, provided you don't mind wrapping everything in a docker
invocation of some sort
# doesn't work if yarn isn't installed locally
yarn add somelib
# uses the yarn in the `node` image, but long-winded
docker-compose run app \
yarn add somelib
This does lead to a style of Docker image that's just a collection of tools without any particular application in it. The unmodified golang
or node
images can be used this way, for example. You might plug these into a CI tool like Jenkins that knows how to do all of the bind mounts and make it look like the container tools are available in the context of a normal pipeline working on the repository being built.
Dev containers are not unlike this. Specifically if you're using Visual Studio Code they will let you use tools out of containers for applications you're developing. You can start multiple containers using a devcontainer.json
file but it's not necessarily the primary use case; often the expectation is that you'll have a container-of-tools but not embed the application in the image. And to my knowledge it's tied to VSCode and not neccesarily usable in other contexts, where you could use Compose or plain Docker for your production deployments too.
Upvotes: 23