TLDR; At Jetify, our Docker development container initialization script used to be like this:
image: ubuntu:22.04
...
# Install Go.
wget --progress=bar:force:noscroll https://golang.org/dl/go1.19.linux-amd64.tar.gz -O go.tar.gz
sudo tar -C /usr/local -xzf go.tar.gz
echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.zshrc
rm go.tar.gz
# Add symlinks for the binaries to be accessible in non-login sessions.
sudo ln -s /usr/local/go/bin/go /usr/local/bin/go
sudo ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt
View 516 more lines...
Now with Devbox, it looks like this:
{
"packages": ["go@1.20", "nodejs@16", "nodePackages.yalc@latest", "poetry@1.4.2", "python@3.10", "buf@1.17.0", "sops@latest", "kubectl@latest"],
}
Our struggles with code onboarding at Jetify
Jetify's main repository is a monorepo housing over 10+ distinct projects. Accommodating a wide range of languages and technologies necessitates support for C, Go 1.19, Node.js 16, Python 3.10, Protobuf, Kubectl, Sops, AWS, GCP, Terraform, and various tools and credentials. Setting this up correctly from scratch can be very challenging.
We started with Docker for dev containers
To ensure consistent experiences among our team members and simplify the setup, we intially turned to Docker for rescue. We developed a unified dev environment in a Docker image, with the entire monorepo mounted to the local container. For each language toolchain, we followed a series of steps:
Obtained the appropriate Ubuntu base image
Installed necessary packages using apt-get
Retrieved and installed tar files in the correct location
Configured variables and symlinks
Removed unnecessary files
Although creating this container presented challenges, it significantly streamlined our initial setup.
Result: Our laptops can't handle such a massive Docker container.
Regrettably, our development Docker container rapidly grew to 9 GB, resulting in lengthy environment creation or package upgrades. CPU usage occasionally exceeds 100%, causing laptops to overheat. In the absence of proper clean-ups, memory consumption easily surpasses 30+ GB. Despite ongoing team complaints, we encountered difficulties in finding viable alternatives.
Set up nix shell environments with Devbox.
Inspired by this frustration, we developed Devbox - a solution that provides isolated development shell environments without the complexities and overhead of a Docker container. Using a straightforward devbox.json
configuration, our team can swiftly onboard new code:
{
"packages": ["go@1.20", "nodejs@16", "nodePackages.yalc@latest", "poetry@1.4.2", "python@3.10", "buf@1.17.0", "kubectl@latest"],
"shell": {
"init_hook": [
"source ./devtools/scripts/shell.sh"
]
}
}
With packages
, all team members have the same tools, languages, and dependencies. This eliminates the need for managing apt-get, tarball files, symlinks, or garbage clean-ups. Utilizing shell init_hook
, each Devbox shell can automatically configure the necessary credentials and environment variables for a session:
#!/bin/bash
# Script of commands to run when an interactive devbox shell is started.
if [ -z ${AWS_SECRET_ACCESS_KEY+1} ]; then
echo $AWS_SECRET_ACCESS_KEY
echo "You must provide AWS credentials in AWS_SECRET_ACCESS_KEY."
fi
Result: Lightweight, repeatable dev environments (and cooler laptops)
By transitioning from a Docker container to the containerless Devbox shell, we significantly reduced CPU usage and freed up multiple Gigabytes of memory on our machines. Startup time decreased from hours to mere seconds. Our init script, which was previously over 1000 lines, now consists of just 9 lines. This change allowed us to enjoy the benefits of both worlds: developers can effortlessly set up a dependable dev environment in a single step, without the performance drawbacks and intricacies associated with Docker containers.
Try Devbox Today!
To help other teams that struggle with dev environments, we open-sourced Devbox and released it for free! Head to GitHub for the installation guide and check the source code. Visit devbox to learn more. Have questions? Join the Discord community