Ghost 1.0 on NixOS

I just upgraded this blog to Ghost 1.0 (Well, 1.4 actually, because they are releasing new versions crazily). Getting things to work on NixOS is not as straight forward as other OS, so I am taking notes on how did I get it working and hopefully help someone.

The codes are here:

Ghost recommends Ghost-CLI for installing and upgrading Ghost, but that is clearly impure and does not work with NixOS. The Nix way to model the package is to create Nix derivations that include everything from NodeJS to all node modules, with something like npm2nix.

The first problem, npm2nix does not work. One of the dependencies of Ghost is specified as tarball and npm2nix cannot understand it, which results in incomplete output. The solution is to change it to git url that points to the same commit.

The second problem, missing dependencies for some modules. Knex is a package that requires the mysql package at runtime, but it is not specificed in its package.json ¯\_(ツ)_/¯ . Since the mysql package is required by Ghost, it is already installed at the top level and should be fine in a normal node project, but the structure in NixOS is different. Nix’s buildNodePackage creates folder structure that limit the loadable modules to strictly what’s specified in package.json, which means Knex is not able to require('mysql'). The “solution” is to manually add the dependency in the generated file.

There is also another package that is not specifying its dependencies properly, so that needs patching as well.

The third problem, Knex checks package.json. If you are using sqlite, you would see Knex refuse to start even it can requires sqlite3. The reason is Knex wants to be clever on dependencies, it reads package.json and assert sqlite3 to be under the dependencies dictionary. This is suppose to be done by asking the user to run npm install --save manually, but that workflow again does not work on NixOS. So another patch is needed.

After fixing the above problems, it is pretty easy to setup the rest. By the way I was trying to add Ghost to the nixpkg repository but it wasn’t going well, the generated node-packages.nix is huge and they are not accepting it… Wonder if there is a better way to package it.