Skip to content
Open
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This project's release branch is `master`. This log is written from the perspect
* Use `--keep NIX_PATH` for all pure shells so references to `<nixpkgs>` continues to work.
* Backport ACMEv2 support in obelisk server to regain LetsEncrypt account creation.
* Enable https in `ob run`
* Add Docker support, for building minimal and customizable images

## v0.2.0.0 - 2019-8-17

Expand Down
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,61 @@ This should copy over and install the application on your device (if you see a
##### Build a release version

After having configured signing for your app, you may proceed to build a release version of the app. This is no different to how you build the non-release version, so consult the section [Android](#android) further above for exact instructions on building and deploying to your device.


## Docker

### Variables

Setting the following environment variables will be helpful for keeping build and run parameters consistent:

```bash
export NAME=app
export VERSION=$(git rev-parse HEAD)
export CONFIGDIR=/path/to/obelisk/config
```

### Building

#### Default

To build a Docker image using a default configuration, run:
```
docker load < $(nix-build -A dockerImage --no-out-link --argstr name $NAME --argstr version $VERSION)
```

#### Custom

To build with a custom configuration, Obelisk's default configuration can be imported and overriden in a `release.nix` file added to your top-level directory:

```nix
{ }:
let
project = import ./. {};
obelisk = import ./.obelisk/impl {
system = builtins.currentSystem;
};
mkBaseDockerImageConfig = { version }: obelisk.dockerImageConfig {
name = "app";
exe = project.linuxExe;
version = version;
};
in {
customDockerImage = args@{ version ? "latest" }:
obelisk.nixpkgs.dockerTools.buildImage (mkBaseDockerImageConfig args // {
config.expose = 3000; # overriding default port 8000
});
}
```

The custom image can then be built with: `nix-build release.nix -A customDockerImage --no-out-link --argstr version $VERSION`

### Running

Using the default configuration, the image can then be run with:

```bash
docker run -p 127.0.0.1:8000:8000/tcp --volume "$CONFIGDIR:/var/run/backend/config" "${NAME}:${VERSION}"
```

And the application should be accessible at `http://localhost:8000`.
31 changes: 31 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,35 @@ in rec {
};
};

dockerImageConfig = args@{exe, name, version, extraContents ? [], extraPaths ? []}:
let
appDirSetupScript = nixpkgs.runCommand "appDirSetupScript.sh" {} ''
mkdir -p $out/var/lib/backend
ln -sft $out/var/lib/backend '${exe}'/*
${nixpkgs.findutils}/bin/find $out/var/lib/backend
'';
in {
name = name;
tag = version;
contents = [ nixpkgs.iana-etc nixpkgs.cacert appDirSetupScript ] ++ extraContents;
keepContentsDirlinks = true;
config = {
Env = [
("PATH=" + builtins.concatStringsSep(":")(extraPaths ++ [
"/var/lib/backend" # put the obelisk project on the path.
"/bin" # put contents on path
] ++ map (pkg: "${pkg}/bin") pkgs.stdenv.initialPath # put common tools in path so docker exec is useful
))
];
Expose = 8000;
Entrypoint = ["/var/lib/backend/backend"];
WorkingDir = "/var/lib/backend";
User = "99:99";
};
};

dockerImage = args: nixpkgs.dockerTools.buildImage (dockerImageConfig args);

serverExe = backend: frontend: assets: optimizationLevel: version:
pkgs.runCommand "serverExe" {} ''
mkdir $out
Expand Down Expand Up @@ -349,6 +378,8 @@ in rec {
exe = serverOn system dummyVersion;
server = args@{ hostName, adminEmail, routeHost, enableHttps, version }:
server (args // { exe = linuxExe version; });
dockerImage = args@{ name, version }:
dockerImage (args // { exe = linuxExe version; });
obelisk = import (base + "/.obelisk/impl") {};
};
haskellPackageSets = {
Expand Down