Back to Home

Nix and DevContainers: reproducible development environments

The article explains how to use Nix and DevContainers to create fully reproducible and isolated development environments. It describes an approach to solving problems with version conflicts of tools and dependencies when working with different projects.

Forget about setting up environments: Nix + DevContainers
Advertisement 728x90

Full Isolation and Reproducibility: Nix and DevContainers for Development

Developers often spend days setting up environments for different projects. Outdated docs, version conflicts with tools and dependencies—these are common headaches when switching between codebases. The fix? A declarative setup for your entire dev environment with guaranteed reproducibility.

The Problem with Fragmented Environments

The real pain isn't writing code—it's getting the project running and testable. Different versions of compilers, interpreters, linters, LSP servers, and CLI tools mean manual installs and tweaks every time. Even with the same tech stack, versions drift, forcing you to juggle version managers or downgrade packages.

README instructions go stale fast, especially in internal company projects. This creates a steep onboarding ramp, adding one or two days just to get up to speed.

Google AdInline article slot

Declarative Setup with Nix

Nix is a package manager that delivers rock-solid reproducible environments. Instead of manually installing dependencies, you define them in a flake.nix file. This config pins everything needed: language compilers, LSP servers, debuggers, and third-party CLI tools.

Key Nix benefits:

  • Reproducibility: Identical environment on any machine.
  • Declarative: Environment defined by config, not a script of commands.
  • Isolation: Dependencies don't clash with system packages.

A flake.nix example for a Go project might include:

Google AdInline article slot
  • Specific Go compiler version.
  • Tools: golangci-lint, delve, gopls.
  • Code generators: sqlc, go-mockery.
  • Database: postgresql_16.

Run nix develop after setup, and it pulls in everything automatically. Initial setup takes time, but it saves hours for every teammate who follows.

Container-Based Isolation

Installing Nix directly on your machine raises security flags. The solution? Run Nix inside a Docker or Podman container for complete isolation—no Nix install needed on the host.

Basic Dockerfile for a Nix-enabled container:

Google AdInline article slot
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y curl xz-utils git ca-certificates
ENV USER=root
ENV PATH="/root/.nix-profile/bin:$PATH"
RUN curl -L https://nixos.org/nix/install | sh -s -- --no-daemon
RUN mkdir -p /root/.config/nix && \
echo "experimental-features = nix-command flakes" > /root/.config/nix/nix.conf
WORKDIR /app
CMD ["/bin/bash"]

This builds a lean Ubuntu image with Nix in single-user mode. All project dependencies stay sandboxed inside, with zero impact on your host system.

Seamless IDE Integration with DevContainers

To code in your favorite IDE inside the container, use the DevContainers standard. It lets your editor run its server-side bits in the container, giving full access to the environment's tools.

Supported IDEs:

  • VS Code (native support).
  • JetBrains IDEs (via plugin).
  • Zed (native support).
  • Terminal editors (Vim/Neovim, Helix, Emacs)—run directly in the container.

DevContainers hides the config complexity. Hit one button in your IDE, and you're connected to a ready-to-go environment.

Step-by-Step Implementation

Project setup process:

  • Create flake.nix defining dependencies.
  • Write a Dockerfile for the Nix container.
  • Add DevContainers config (.devcontainer.json file).
  • Launch via your IDE.

Example project structure:

project/
├── flake.nix
├── Dockerfile
├── .devcontainer.json
└── src/

Once set up, any dev can clone the repo, open in a compatible IDE, and dive in—no extra installs required.

Key Takeaways

  • Nix locks in reproducible environments via declarative configs.
  • Containers isolate dev setups and boost security.
  • DevContainers bridge isolated environments to top IDEs.
  • Upfront setup pays off with team-wide time savings.
  • Works universally across any programming language.

— Editorial Team

Advertisement 728x90

Read Next