Development Containers
containers.dev
containers.dev
I am a dev container addict. I work on tons of different projects across languages, and it's so nice for the dev environment to just work (mostly- if it doesn't, it's because of M1 issues). I also love Github Codespaces (that uses dev containers), I've been using it for all my workshops lately and attendees tend to prefer Codespaces instead of local dev.
If you're looking for example dev containers, I've got a bunch of repos linked from my read me that have support: https://github.com/pamelafox
The trickiest ones have involved databases, but I was happy to be able to get PostgreSQL running inside the container, along with an admin for it! We did a Youtube stream showing that here: https://t.co/0Kl57Ew46C
Yesterday I got docker-in-docker working as I'm running a Docker workshop today and want Codespaces to be an option. So cool. That's at https://github.com/pamelafox/flask-surveys-container-app/tre...
https://github.com/pamelafox/django-quiz-app/blob/main/.devc...
There are a few config options there that took some tweaking.
I love the experience so far, we've done a few features (modules) - e.g. this one to install `nvtop` to see GPU utilization [0]
The whole CUDA + nvtop + (some other tools) setup for a project to be run on a remote machine (e.g. via VS Code) becomes like this [1]
And that's enough to run ML training on GH Codespaces with GPU support. Super cool experience.
[0] https://github.com/iterative/features/blob/main/src/nvtop/in...
[1] https://github.com/shcheklein/hackathon/blob/main/.devcontai...
It’s an open standard and we’re starting to see more members of the community adopt it or integrate support into their stuff too (including some larger Nix players like devenv and Jetpack.io) and I really hope others adopt it too. For me, for however many years I’ve been using these (it’s at least 2 but it could be longer, time is a circle), it has definitely improved my QoL.
Disclosure: I work at GitHub which uses devcontainers in Codespaces and I used to work at Microsoft which developed this and used it with VS Code and the amazing VS Code remote extension.
I’m not debating that that isn’t a lot of extra work, but the spec itself is absolutely open for anyone else to integrate. I’d posit that the reason we haven’t seen alternatives (to my knowledge) to remote extension because of how much work is involved when most people (maybe not you, but most people), are comfortable just turning off the telemetry flag in VS Code rather than using Codium.
But if you’d rather use something like Nix, using something like devbox or devenv will achieve something similar to dev containers and that’s fine foo.
It's always weird to me how the response to 'its great for showing new users stuff' is 'WHAT!? why arn't you having them install this new os/whatever instead'. I feel like hacker news commenters completely lack perspective sometimes.
- installing dependencies
- performance
- compatibility
- ...
I read an unrelated comment that installing PostgreSQL "was among the trickiest issue" ... Cool, but no matter the machine, getting a PostgreSQL DB up and running is usually rather straightforward. So, not sure what to exactly think of this but would be happy to hear from someone with hands-on experience.
Codespaces makes this really ideal, but just using the VS Code extension (after getting everyone to get Docker installed), saves a lot of time and ensures everyone is using the same version of everything.
Also lts, lts-hydrogen, etc are available to install I can see when running `asdf list all nodejs`
It supports named volumes, configmaps and that is enough for local dev environments, and editor agnostic.
- Mount volumes in your dev container
- Run commands after the container is built
- Pass environment variables from the host to containers
- Specify which containers will be ran in a docker-compose definition and which one will host the vs code server
- Use arbitrary flags in docker run / docker build / docker-compose
You will end up with a Makefile or bash script that roughly looks like a .devcontainer.json file.
Devcontainer files are also neat from an UX pov because new devs can just click on "open remote" and wait. I've been using this feature since 2019 and it did wonders for project onboarding.
> - Pass environment variables from the host to containers
> - Specify which containers will be ran in a docker-compose definition and which one will host the vs code server
Docker compose yaml files are pretty cool to define these.
Whereas these are just asking for trouble/non-reproducible docker environment and could be part of container definitions:
> - Run commands after the container is built
> - Use arbitrary flags in docker run / docker build / docker-compose
The UX that you mention on the other hand is pretty cool:
Devcontainer files are also neat from an UX pov because new devs can just click on "open remote" and wait. I've been using this feature since 2019 and it did wonders for project onboarding.
What you end up cobbling together to really create a fully fledged environment ends up being what the yaml does for you in a consistent manner.
Also, getting off of "DOCKER", and specifically "docker desktop" and its magic, is beneficial.
As I've blogged about here [1], there are other specs such as Devfile.io or GitPod's proprietary gitpod.yml file.
[1] https://www.augmentedmind.de/2022/10/30/container-based-deve...
json... with comments
But JSON wasn't intended for configuration or meddling around with much. But it's incredibly useful to have a file format parsable with vanilla JS so it just became de facto configuration syntax - without comments!
Being able to able to open an open source project on the go just by launching a codespace is no small feat.
I have also been recently programming in quite heavy environments which my computer could not handle (especially when screen sharing) properly so launching the environment in a remote cloud instance with 8 core and 16GB of ram was useful.
All my personal projects are developed in codespaces too to minimize time I spend setting up or syncing those to lower the friction as much as possible. Going from desktop to tablet to my laptop all I need to do is to launch the codespace.
I hope other vendors will contribute to the spec, there's nothing to benefit here from every cloud implementing their own spec, they will eventually lose to Microsoft rather than leverage the spec.
Dev Containers are basically Docker Containers (either pulled from a repo or built from a Dockerfile) with some additional metadata attached so they can work as a Development Environment. Metadata includes stuff to configure debuggers, IDEs, etc.
The devcontainer spec combines 3 things:
- How to build containers for a development environment (using Docker or docker-compose)
- How to run containers for a development environment (volumes to mount, environment variables, commands to execute after containers are running, where the project will be mounted...)
- Which VS Code configuration to install and use (including extensions) within the development environment
Otherwise you are going to miss bugs/vulnerabilities and spend a lot of time keeping dev/prod provisioning in sync.
Deploying to containers/k8s? Develop in a container.
Deploying to VM/bare metal? Develop in a VM (Vagrant).
Developing a portable library? Nix may be a good fit.
So it's a docker-compose that runs up in your IDE.
Then you have all your tools ready to go i.e. postgres.
Most importantly you can share it with your team.
I long for the opportunity where the software I develop would work with plain vanilla Debian stable and would require nothing else.
Working in crap: doing someones elses work
Working on crap: doing some work on legacy
All I need is Emacs, and podman.
Also, if you fail to see the value in this, then I'd ask what you would use:
- When you need to work on multiple products with different environments.
- When you want to temporarily spin up development environments on powerful machines for parts of your work and rest of the time develop locally?
- When you want to pass an identical environment to someone else and have it just work.
You interact with APIs. You don't have to install a database or another daemon to your local computer.
- When you want to temporarily spin up development environments on powerful machines for parts of your work and rest of the time develop locally?
This has never happened.
- When you want to pass an identical environment to someone else and have it just work.
All the dev stacks has something like package.json
How about the people writing the APIs?, or the ones writing the servers?, or the os, or database, etc?
> This has never happened
In your case, use a bit of imagination.
> All the dev stacks has something like package.json
That is a very broad statement and in my experience, no.
And it's nice to have all that work across an entire team, no "works on my machine" weirdness.
Also you need some hacky things to make vbox running on OSX so it becomes totally a "works on my machine".
Fine. What about compilers? System libraries? PostgreSQL version & config? Does package.json manage your node version? Oh and we switched from npm to some hipster new thing a while back, and older package.json files of ours will fail to install properly with the new thing. Have fun git-bisecting.
> Also you need some hacky things to make vbox running on OSX so it becomes totally a "works on my machine".
Been doing this for like a decade and it's not much more than "brew install docker" and a line or two in your shell rc file. It used to be slightly worse because you had to manage docker-machine separately, but it's never been hard or complicated.
Email them? "Hey, everybody should upgrade to OpenCV version 4.1.5"? Garbage.
Web developers always just assume the entire world is other web developers, and confidently dispense advice without any caveat re. its limited purview. The world is bigger than python notebooks and shitty ruby apps.