Skip to main content

DevBox

SonarQube

Repository

Official Documentation

Devbox is a command-line tool that allows you to create isolated shells for development without the need for Docker containers or virtual machines. Devbox uses the Nix Package Manager to install the necessary packages.

We define project dependencies in a devbox.json file, ensuring that everyone on the team uses the same versions of tools and libraries. This eliminates common configuration problems and facilitates continuous integration.

  • Avoids manually configuring tools and libraries in the CI pipeline.
  • Fast configuration
  • Environment portability
  • In the case of containers, we can maintain a specific base instead of preparing different runners.

Additionally, Devbox allows you to export your development environment to containers or cloud environments, ensuring portability and consistency between local development and production.

In summary, Devbox is an efficient solution for creating isolated, consistent, and portable development environments, simplifying workflow and improving team productivity.

Define the list of packages needed for your project, and Devbox creates an isolated and reproducible environment with these packages installed.

DevBox vs NIX

I had an experience with the NixOS distribution and learned about the Nix package manager. At the time, I wanted to use it on my personal desktop because I wanted an environment that I could replicate quickly and find an alternative to my Workstation project with Ansible. The idea is wonderful, as NixOS allows us to configure the operating system declaratively and adopts the concept of immutability. Each change generates a new state allowing rollout. I ended up abandoning the idea of using it on my personal desktop because I found it too laborious, but I loved the idea and have already thought about using it for various scenarios, not for my personal desktop. There is a tool called nix-shell which is a temporary shell. Everything you install while it is active is discarded when we close the session and this seemed very promising.

The barrier to entry for using Nix is high. It requires study, persistence, and a lot of patience. It is not a technology we can easily apply in a company, as it will require effort from many people to learn. This is where DevBox comes in, solving this problem!

Devbox uses Nix as a base, including functionalities similar to nix-shell, but offers a simplified experience focused on development. Devbox abstracts many of the complexities of nix-shell and the Nix ecosystem, making it easier for developers to create and manage reproducible development environments. By reducing complexity, it became much easier to propose its use within the team, as we will use Nix without knowing about Nix in a much more friendly way.

With DevBox we can create the environment without polluting the desktop or needing to change system configurations to run the project by creating an exclusive shell session for the project. We usually do this using containers, but with DevBox we will eliminate all the complexity and problems involved in using containers.

Installation

If you are on Windows, you need to use WSL as a Linux environment is required. On Mac it works perfectly.

curl -fsSL https://get.jetify.com/devbox | bash

devbox version
0.13.7

Using DevBox

Create any test folder simulating a project.

mkdir test
cd test

Now let's initialize a devbox.json, that is, a file that will be the description of everything this environment needs.

devbox init

ls
devbox.json

cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}

To enter and start a devbox shell from what we have there.

❯ devbox shell
Starting a devbox shell...

From now on we are using the devbox shell. To confirm if you want just do an env in the terminal and see the differences in environment variables

env | grep NIX

To exit this shell just type exit and redo the env above and see that we won't have all those previous variables.

exit
# Returning to the previous shell we can see that the output is much smaller having only the default devbox variables.
env | grep NIX

For example I don't have the yq binary on my machine, but I also don't want to install it, only for this project

yq
zsh: command not found: yq

So let's start adding the things we need. Remember to be inside the shell with the devbox shell command.

# Adding yq
devbox add yq
Info: Adding package "yq@latest" to devbox.json
Info: Installing the following packages to the nix store: yq@latest
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.

yq --version
yq 3.4.3

# Notice that it entered devbox.json in packages
cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": ["yq@latest"],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}

If we exit the terminal and return, yq will be there.

To remove we just need to use rm instead of add.

devbox list
* yq@latest - 3.4.3

devbox rm yq
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.

cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}

Now let's put it back manually. We don't have it installed. Exit devbox with the exit command and edit devbox.json including the package as we had above and start again.

# To exit devbox shell
exit
# Edit the file including the package
cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [
"yq@latest"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
# Starting and it already installs for us
❯ devbox shell
Info: Ensuring packages are installed.
✓ Computed the Devbox environment.
Starting a devbox shell...

yq --version
yq 3.4.3

To search for a package just use devbox search package_name. Never install latest, try to pin versions of everything because devbox gives us the power for that.

On my machine outside the shell I have terraform installed.

terraform version
Terraform v1.10.3

Let's install another version inside the project (terraform 1.9.8). We could just do devbox add [email protected] but let's do it differently to learn some details.

# Listing packages using search.
devbox search terraform
Found 25+ results for "terraform":

* terraform (1.10.3, 1.10.2, 1.10.1, 1.10.0, 1.9.8, 1.9.7, 1.9.6, 1.9.5, 1.9.4, 1.9.3 ...)
* terraform-compliance (1.3.49, 1.3.48, 1.3.47, 1.3.46, 1.3.45, 1.3.44, 1.3.43, 1.3.34, 1.2.11)
* terraform-docs (0.19.0, 0.18.0, 0.17.0, 0.16.0, 0.15.0, 0.14.1, 0.13.0, 0.12.1, 0.12.0, 0.11.2 ...)
* terraform-full (1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.9, 1.1.8, 1.1.7 ...)
* terraform-inventory (0.10, 0.7-pre)
* terraform-landscape (0.2.1)
* terraform-local (0.20.0, 0.19.0, 0.18.2)
* terraform-ls (0.36.3, 0.36.2, 0.36.0, 0.34.3, 0.34.2, 0.34.1, 0.33.1, 0.33.0, 0.32.8, 0.32.7 ...)
* terraform-lsp (0.0.12, 0.0.10)
* terraform_1 (1.3.9, 1.3.5, 1.3.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.9, 1.1.8, 1.1.7 ...)

Warning: Showing top 10 results and truncated versions. Use --show-all to show all.

# Edit the devbox.json file directly including the package.

cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [
"yq@latest",
"[email protected]"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}

# Running devbox install it will install all packages found in devbox.json
devbox install
Info: Ensuring packages are installed.
Info: Installing the following packages to the nix store: [email protected]
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.
Finished installing packages.

# Strange right? It should be 1.9.8
# This happened because it is still referencing terraform from my machine which is accessible to it.
# It is necessary to do a refresh
terraform --version
Terraform v1.10.3

# Exiting and returning
exit

devbox shell
Starting a devbox shell...

terraform --version
Terraform v1.9.8

# Exiting to my system
exit
terraform version
Terraform v1.10.3

Installing directly without doing this workaround doesn't cause this.

We can see that we have the hidden folder .devbox in the project. It is in this folder that we have the packages in an isolated way from the system. For a real project remember to put this in .gitignore to not upload this to repositories.

ls -lha
total 8.0K
drwxr-xr-x 5 davidprata 160 Jan 13 08:09 .
drwxr-x---+ 53 davidprata 1.7K Jan 13 09:08 ..
drwx------ 10 davidprata 320 Jan 13 09:15 .devbox
-rw-r--r-- 1 davidprata 355 Jan 13 09:00 devbox.json
-rw-r--r-- 1 davidprata 3.8K Jan 13 08:53 devbox.lock

Removing the project folder will eliminate everything that was installed for its execution.

Now imagine the power of this within a pipeline and how much we could facilitate development and reduce code? It would be practically putting the runner to execute the devbox shell that already installs everything that is necessary. We would reduce several steps of pipelines and could reuse the same definition in several projects.

Additionally, having all dependencies declared inside a file in the repository will facilitate the concept of GitOps.