Giter Club home page Giter Club logo

heroku-buildpack-nix-proot's Introduction

heroku-buildpack-nix-hydra

This buildpack installs software using the Nix package manager. The software is assumed to have been built by Hydra, leading to speedy and predictable deployments that do no compilation of their own.

The resulting app must be run within PRoot, incurring a performance penalty.

Usage

Create a Procfile something like this (run_proot.sh will be created by the build scripts):

web: run_proot.sh myapp

Then create your application on Heroku, setting the location of your Hydra server:

heroku create -b https://github.com/ocharles/heroku-buildpack-nix-hydra.git
heroku config:set NIX_EXTRA_BINARY_CACHE=http://hydra.acme.net:3000

If you are using nix-serve or another way to provide a binary cache, simply provide the binary cache URL in place of the Hydra url.

Hydra Configuration

Next, you need to configure your Hydra instance. The full details are outside the scope of this readme, but you shouldn’t need more than the following (in release.nix) to get started:

{
  my-project = import <my-project/shell.nix>;
}

Add a new input to this jobset called my-project.

Project Configuration

Your project now needs a fully self-contained Nix expression to build it. Assuming you already have a normal default.nix build function, you can work with a shell.nix expression such as:

{
  nixpkgs ?
    let
      inherit (import <nixpkgs> {}) fetchFromGitHub;
    in
      import
        ( fetchFromGitHub
          {
            owner = "NixOS";
            repo = "nixpkgs";
            rev = "3f96280da0ebc578599130c55c283036b51a9e91";
            sha256 = "1sv8rznqna02z642hfjykdr9xjn228932jkc03y8a4rqplqqg6l1";
          }
        ) { config.allowUnfree = true; }
}:

let

  inherit (nixpkgs) pkgs;

in pkgs.callPackage ./. {};

Notice that nixpkgs is explicitly provided inside this expression, to maximize reproducibility.

Deployment

Push your application to the Git remote that Hydra is configured to build from. Once the build has completed, you can perform a deployment by pushing to your Heroku remote:

git push heroku master

Considerations, gotchas and implementation details

For this to work, it’s essential that you get identical Nix store paths during Heroku deployment. Which is easier said than done. The main gotcha seems to be that whenever you refer to a path in a Nix file, a copy operation happens within the Nix store, even if that file is already in the Nix store.

Why is this a problem? The first thing Hydra does is pull the Git repository down, and inserts it straight into the Nix store. This means that <my-project> in the original example is going to expand to something like /nix/store/deadbeef33333-git-export. However, in shell.nix for my-project we refer to ./., which causes a copy operation, which means a path like /nix/store/new-sha-here-deadbeef33333-git-export.

This buildpack tries to take care of that by essentially copying what Hydra does - the $BUILD_DIR is immediately inserted into the Nix store, and all subsequent evaluation is derived from that. However, if you keep finding that Heroku builds rather than downloads from Hydra, drop me a message and let’s see if we can figure out what’s going wrong.

Thanks

This work builds on top of Cora Johnson-Roberson’s =heroku-buildpack-nix-proot= build pack. Many thanks for doing the initial exploration into this. Also, I send my thanks to those who made Cora’s original work possible.

heroku-buildpack-nix-proot's People

Contributors

corajr avatar ocharles avatar rehno-lindeque avatar

Stargazers

Sviat Chumakov avatar Vaibhav Sagar avatar Kamil Chmielewski avatar

Watchers

 avatar  avatar James Cloos avatar Sviat Chumakov avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.