App source + Nix packages + Docker = Image
Nixpacks takes a source directory and produces an OCI compliant image that can be deployed anywhere. The project was started by the Railway team as an alternative to Buildpacks and attempts to address a lot of the shortcomings and issues that occurred when deploying thousands of user apps to the Railway platform. The biggest change is that system and language dependencies are pulled from the Nix ecosystem, which provides a bunch of benefits.
You can follow along with the roadmap in the GitHub project.
- ✨ Intuitive defaults: In most cases, building and deploying an app with nixpacks should just work with no configuration needed.
- ⚙️ Customization where necessary: Every part of the pipeline should be customizable. These include the Nix packages to add to the environment and build/start commands.
- 🚀 Easily extendible: New providers (languages) should be able to be easily added to nixpacks with minimal knowledge of Nix and Docker.
Nix packages are used for OS and language level dependencies (e.g. nodejs and ffmpeg). These packages are built and loaded into the environment where we then use these dependencies to install, build, and run the app (e.g. npm install
, cargo build
, etc.).
At the moment nixpacks generates a Dockerfile
based on all information available. To create an image this is then built with docker build
. However, this may change so providers should not need to know about the underlying Docker implementation.
- Install Nixpacks
- Build an image from app source code
nixpacks build ~/path/to/source --name my-app
- Run the image
docker run -it my-app
Note: Docker must be running and available locally to use Nixpacks
At the moment Nixpacks supports the following languages out of the box
Install Nixpacks with Homebrew (MacOS Only)
brew install railwayapp/tap/nixpacks
Download Nixpacks from GH releases and install automatically
curl -fsSL https://raw.githubusercontent.com/railwayapp/nixpacks/master/install.sh | bash
Build and install from source using Rust.
cargo install nixpacks
Environment variables can be made available to the install, build, and start phases of Nixpacks with the --env
flag. For example
nixpacks build . --env "HELLO=world" "FOO"
If no equal sign is present, then the value is pulled from the current environment.
The main Nixpacks commands are build
and plan
.
Create an image from an app source directory. The resulting image can then be run using Docker.
For example
nixpacks build ./path/to/app --name my-app --env "HELLO=world" --pkgs cowsay
View all build options with
nixpacks build --help
The plan command will show the full set of options (nix packages, build cmd, start cmd, etc) that will be used to when building the app. This plan can be saved and used to build the app with the same configuration at a future date.
For example,
nixpacks plan examples/node
View all plan options with
nixpacks plan --help
For a full list of CLI commands run
nixpacks --help
Nixpacks works in two steps
Analyze the app source directory and generates a reproducible build plan. This plan can be saved (in JSON format) and re-used at a later date to build the image in the exact same way every time.
Language providers are matched against the app source directory and suggest Nix packages, an install command, build command, and start command. All of these can be overwritten by the user.
The build step takes the build plan and creates an OCI compliant image (with Docker) that can be deployed and run anywhere. This happens in the following steps
- Create build plan
- Copy app source to temp directory
- Use the Nix packages in the build plan and generate an
environment.nix
file - Build the app in multiple phases
- Setup: Install all necessary Nix packages
- Install: Download all build dependencies
- Build: Generate everything necessary to run the app
- Start: Configure a default command to run when starting the container
- Done!
Overall the process is fairly simple.
Contributions are welcome with the big caveat that this is a very early stage project and the implementation details and API will most likely change between now and a stable release. For more details on how to contribute, please see the Contributing guidelines.