2018-12-17 19:08:38 +01:00
# Run docker-compose without images with Nix
*Wait, what?*
With Arion you can fire up containers without creating images for each
2019-03-03 23:42:40 +01:00
service. It can use a mostly empty image, and makes the host's Nix
store available in the container, allowing the container to run
programs without having to re-package them into a docker image.
2018-12-17 19:08:38 +01:00
Arion is configured using Nix with modules, like those in
NixOS. Similar to `docker-compose` it can therefore combine
configuration from multiple files. For managing the network and
containers it delegates to the `docker-compose` command.
# Project Status
This project was born out of a process supervision need for local
development environments while working
on [Hercules CI ](https://www.hercules-ci.com ). (It was also born out
of ancient Greek deities disguised as horses. More on that later.)
2019-03-03 23:42:40 +01:00
If you do want to use Arion for production environments, you'll
probably want to either build normal container images or manage
garbage collection roots if you control the deployment host. Neither
scenario is made easier by arion at this time.
2018-12-17 19:08:38 +01:00
2018-12-18 14:53:37 +01:00
Support for other Linux than NixOS is untested.
2018-12-18 13:27:40 +01:00
# Install
2018-12-17 19:08:38 +01:00
2019-01-28 16:13:36 +01:00
Have [Nix ](https://nixos.org/nix/ ) and Docker installed. Ubuntu users:
make sure you've installed via `apt-get install docker.io` . The Docker snap
is broken and apparently unsupported by Canonical.
2018-12-17 19:08:38 +01:00
2018-12-18 13:27:40 +01:00
git clone git@github.com:hercules-ci/arion.git
2019-01-27 01:15:05 +01:00
cd arion
2018-12-18 13:27:40 +01:00
nix-env -iA arion -f .
2018-12-17 19:08:38 +01:00
2018-12-18 14:53:37 +01:00
# Example `arion-compose.nix`
This Nix expression serves the Nix manual at host port 8000 when launched with `arion up` . It is a function from a package set (`pkgs`) to a configuration.
2018-12-18 15:09:43 +01:00
```nix
2018-12-18 14:53:37 +01:00
{ pkgs, ... }:
{
config.docker-compose.services = {
webserver = {
service.useHostStore = true;
# service.depends_on = [ "backend" ];
service.command = [ "sh" "-c" ''
cd "$$WEB_ROOT"
${pkgs.python3}/bin/python -m http.server
'' ];
service.ports = [
"8000:8000" # host:container
];
service.environment.WEB_ROOT = "${pkgs.nix.doc}/share/doc/nix/manual";
};
# backend = { ... }
};
}
```
2018-12-18 13:27:40 +01:00
2019-03-03 23:42:40 +01:00
The `pkgs` argument comes from a file called `arion-pkgs.nix` . It can be as simple as `import <nixpkgs> {}` to use the Nixpkgs from your `$NIX_PATH` , or you can use it to pin a specific Nixpkgs version.
2018-12-18 14:53:37 +01:00
# A full featured example
To see how Arion can be used in a project, have a look at [todomvc-nix ](https://github.com/nix-community/todomvc-nix/tree/master/deploy/arion ).
2018-12-18 13:27:40 +01:00
git clone git@github.com:nix-community/todomvc-nix.git
cd todomvc-nix/deploy/arion
arion up
2018-12-18 14:53:37 +01:00
# How it works
Arion is essentially a thin wrapper around Nix and docker-compose.
When it runs, it does the following:
- Evaluate the configuration using Nix, producing a `docker-compose.yaml` and a garbage collection root
- Invoke `docker-compose`
- Clean up the garbage collection root
Most of the interesting stuff happens in Arion's Nix expressions,
where it runs the module system (known from NixOS) and provides the configuration that makes the Docker Compose file do the things it needs to do.
2019-03-03 23:42:40 +01:00
One of the more interesting built-in modules is the [host-store.nix module ](src/nix/modules/service/host-store.nix ) which performs the bind mounts to make the host Nix store available in the container.
2018-12-18 14:53:37 +01:00
2018-12-18 15:09:43 +01:00
# FAQ
2018-12-18 13:27:40 +01:00
### Do I need to use Hercules CI?
2018-12-18 10:30:42 +01:00
Nope, it's just Nix and Docker Compose under the hood.
2018-12-18 13:27:40 +01:00
### Does Arion support Docker images?
2019-03-03 23:42:40 +01:00
Yes, you can also specify a normal Docker image. For example:
2018-12-18 13:27:40 +01:00
postgres = {
service.image = "postgres:10";
service.volumes = [ "${toString ./.}/postgres-data:/var/lib/postgresql/data" ];
service.environment.POSTGRES_PASSWORD = "mydefaultpass";
};
### What about garbage collection?
Arion removes the need for garbage collecting docker images,
delegating this task to Nix.
Arion creates a garbage collection root and cleans it up after
completing the command. This means that `arion up` without `-d` is
safe with respect to garbage collection. A deployment that is more
serious than local development must leave a GC root on the deployment
host. This use case is not supported as of now.
2018-12-18 14:53:37 +01:00
### What is messing with my environment variables?
Docker Compose performs its own environment variable
substitution. This can be a little annoying in `services.command` for
example. Either reference a script from `pkgs.writeScript` or escape
the dollar sign as `$$` .
2018-12-18 13:27:40 +01:00
### Why "Arion"?
2018-12-17 19:08:38 +01:00
Arion comes from Greek mythology. Poseidon, the god of ~Docker~ the
seas had his eye on Demeter. Demeter tried to trick him by disguising
as a horse, but Poseidon saw through the deception and they had Arion.
So Arion is a super fast divine horse; the result of some weird
mixing. Also it talks.
(And we feel morally obliged to name our stuff after Greek mythology)