arion-compose 0.1.0.0 → 0.1.1.0
raw patch · 15 files changed
+45/−307 lines, 15 files
Files
- CHANGELOG.md +4/−1
- README.asciidoc +1/−268
- arion-compose.cabal +1/−1
- src/haskell/test/Arion/NixSpec.hs +1/−1
- src/haskell/testdata/Arion/NixSpec/arion-compose.nix +1/−1
- src/nix/eval-composition.nix +1/−6
- src/nix/modules.nix +7/−0
- src/nix/modules/composition/arion-base-image.nix +1/−1
- src/nix/modules/service/default-exec.nix +1/−1
- src/nix/modules/service/docker-compose-service.nix +9/−9
- src/nix/modules/service/extended-info.nix +2/−2
- src/nix/modules/service/host-store.nix +1/−1
- src/nix/modules/service/image.nix +10/−10
- src/nix/modules/service/nixos-init.nix +1/−1
- src/nix/modules/service/nixos.nix +4/−4
CHANGELOG.md view
@@ -2,7 +2,10 @@ ## Unreleased -<!-- TODO: use better template -->+## 0.1.1.0 -- 2020-03-19++* Support Nixpkgs 20.03+* Fixes for macOS ## 0.1.0.0 -- 2019-10-04
README.asciidoc view
@@ -1,274 +1,7 @@-== Introduction- Arion is a tool for building and running applications that consist of multiple docker containers using NixOS modules. It has special support for docker images that are built with Nix, for a smooth development experience and improved performance. -It is built on top of https://docs.docker.com/compose/overview/[Docker-Compose], which implements the container orchestration functionality. -Instead of configuring the compositions in YAML files like-`docker-compose.yaml`, Arion uses the https://nixos.org/nix/[Nix]-language to declare the compositions. Because of this, Arion gives you-the ability to declare your deployments, configuration and packaging-in the same language. By replacing multiple tools with a single-language, you decrease your mental load and you can more easily-refactor and maintain your configurations.--Although Arion can be used as a Docker Compose with an improved-configuration front end, there is more to be gained from integrating-with Nix. In particular, the more structured approach of Nix compared-to Dockerfiles allows the following:-- * Build components of your image in *parallel, automatically*- * *Share packages between images*, regardless of the order they were- added- * Improve performance by *skipping container- image creation*- * Work with *structured data instead of strings*,- templates and a multitude of expression languages- * Refactor across deployments, configuration and packaging--Arion allows to compose containers with different granularity:-- * <<Minimal: Plain command using nixpkgs>>- * <<NixOS: run only one systemd service>>- * <<NixOS: run full OS>>- * <<Docker image from DockerHub>>--== Installation--=== Nix--```bash-$ nix-env -iA arion -f https://github.com/hercules-ci/arion/tarball/master-```--=== NixOS--Add this module to your NixOS configuration:--```nix-{ ... }: {- environment.systemPackages = [ (import (builtins.fetchTarball https://github.com/hercules-ci/arion/tarball/master) {}).arion ];- virtualisation.docker.enable = true;- users.extraUsers.myuser.extraGroups = ["docker"];-}-```--////--== Not installing: use it in a project--TODO: describe: using nix-shell or in a script, building images as- part of nix-build, pinning, see also todomvc-nix.--TODO: exposed Nix functions: arion.build, arion.eval (a bit of IFD)---////---== Usage--Arion is configured declaratively with two files:--=== arion-pkgs.nix--Arion needs `arion-pkgs.nix` to import nixpkgs, it's contents can be as simple as:--```nix-import <nixpkgs> {}-```--or more sophisticated (recommended) setup with https://github.com/nmattia/niv[Niv].--=== arion-compose.nix--Describe containers using NixOS-style modules. There are a few options:--==== Minimal: Plain command using nixpkgs--`examples/minimal/arion-compose.nix`:--```nix-{ pkgs, ... }:-{- config.docker-compose.services = {-- webserver = {- service.useHostStore = true;- 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";- };- };-}---```--==== NixOS: run only one systemd service--`examples/nixos-unit/arion-compose.nix`:--```nix--{- docker-compose.services.webserver = { config, pkgs, ... }: {-- nixos.configuration = {config, pkgs, ...}: {- boot.isContainer = true;- services.nginx.enable = true;- services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";- system.build.run-nginx = pkgs.writeScript "run-nginx" ''- #!${pkgs.bash}/bin/bash- PATH='${config.systemd.services.nginx.environment.PATH}'- echo nginx:x:${toString config.users.users.nginx.uid}:${toString config.users.groups.nginx.gid}:nginx web server user:/var/empty:/bin/sh >>/etc/passwd- echo nginx:x:${toString config.users.groups.nginx.gid}:nginx >>/etc/group- ${config.systemd.services.nginx.runner}- '';- };- service.command = [ config.nixos.build.run-nginx ];- service.useHostStore = true;- service.ports = [- "8000:80" # host:container- ];- };-}--```--==== NixOS: run full OS--`examples/full-nixos/arion-compose.nix`:--```nix-{- docker-compose.services.webserver = { pkgs, ... }: {- nixos.useSystemd = true;- nixos.configuration.boot.tmpOnTmpfs = true;- nixos.configuration.services.nginx.enable = true;- nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";- service.useHostStore = true;- service.ports = [- "8000:80" # host:container- ];- };-}-```--==== Docker image from DockerHub--```nix-{- docker-compose.services.postgres = {- service.image = "postgres:10";- service.volumes = [ "${toString ./.}/postgres-data:/var/lib/postgresql/data" ];- service.environment.POSTGRES_PASSWORD = "mydefaultpass";- };-}-```--=== Run--Start containers and watch their logs:--```bash-$ arion up -d-$ arion logs -f-```--You can go to `examples/*/` and run these commands to give it a quick try.--== A full featured Nix command example--To see how Arion can be used in a project, have a look at-https://github.com/nix-community/todomvc-nix/tree/master/deploy/arion[todomvc-nix].--```bash-$ git clone https://github.com/nix-community/todomvc-nix-$ cd todomvc-nix/deploy/arion-$ arion up-```--== Project Status--This project was born out of a process supervision need for local-development environments while working on-https://www.hercules-ci.com[Hercules CI]. (It was also born out of-ancient Greek deities disguised as horses. More on that later.)--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.--Arion has run successfully on Linux distributions other than NixOS, but we only perform CI for Arion on NixOS.---== 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.--One of the more interesting built-in modules is the-link:src/nix/modules/service/host-store.nix[host-store.nix module] which-performs the bind mounts to make the host Nix store available in the-container.--== FAQ--=== Do I need to use Hercules CI?--Nope, it’s just Nix and Docker Compose under the hood.--=== 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.--=== Why is my container not running latest code?--Restart it with `arion restart <name>` or if you've changed the image rebuild-them using `arion up -d --always-recreate-deps <name>`.--=== 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-`$$`.--=== Why name it ``Arion``?--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)+# https://docs.hercules-ci.com/arion/[Intro and Documentation]
arion-compose.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: arion-compose-version: 0.1.0.0+version: 0.1.1.0 synopsis: Run docker-compose with help from Nix/NixOS description: Arion is a tool for building and running applications that consist of multiple docker containers using NixOS modules. It has special support for docker images that are built with Nix, for a smooth development experience and improved performance. homepage: https://github.com/hercules-ci/arion#readme
src/haskell/test/Arion/NixSpec.hs view
@@ -18,7 +18,7 @@ { evalUid = 123 , evalModules = NEL.fromList ["src/haskell/testdata/Arion/NixSpec/arion-compose.nix"]- , evalPkgs = "import <nixpkgs> {}"+ , evalPkgs = "import <nixpkgs> { system = \"x86_64-linux\"; }" , evalWorkDir = Nothing , evalMode = ReadOnly , evalUserArgs = ["--show-trace"]
src/haskell/testdata/Arion/NixSpec/arion-compose.nix view
@@ -1,5 +1,5 @@ {- docker-compose.services.webserver = { pkgs, ... }: {+ services.webserver = { pkgs, ... }: { nixos.useSystemd = true; nixos.configuration.boot.tmpOnTmpfs = true; nixos.configuration.services.nginx.enable = true;
src/nix/eval-composition.nix view
@@ -18,12 +18,7 @@ builtinModules = [ argsModule- ./modules/composition/docker-compose.nix- ./modules/composition/host-environment.nix- ./modules/composition/images.nix- ./modules/composition/service-info.nix- ./modules/composition/arion-base-image.nix- ];+ ] ++ import ./modules.nix; argsModule = { _file = ./eval-composition.nix;
+ src/nix/modules.nix view
@@ -0,0 +1,7 @@+[+ ./modules/composition/docker-compose.nix+ ./modules/composition/host-environment.nix+ ./modules/composition/images.nix+ ./modules/composition/service-info.nix+ ./modules/composition/arion-base-image.nix+]
src/nix/modules/composition/arion-base-image.nix view
@@ -10,7 +10,7 @@ tag = lib.head (lib.strings.splitString "-" (baseNameOf builtImage.outPath)); name = "arion-base"; - builtImage = pkgs.dockerTools.buildLayeredImage {+ builtImage = pkgs.dockerTools.buildImage { inherit name; contents = pkgs.runCommand "minimal-contents" {} '' mkdir -p $out/bin $out/usr/bin
src/nix/modules/service/default-exec.nix view
@@ -9,7 +9,7 @@ default = ["/bin/sh"]; description = '' Container program and arguments to invoke when calling- <code>arion exec <service.name></code> without further arguments.+ `arion exec <service.name>` without further arguments. ''; }; };
src/nix/modules/service/docker-compose-service.nix view
@@ -11,11 +11,11 @@ inherit (types) listOf nullOr attrsOf str either int bool; link = url: text:- ''<link xlink:href="${url}">${text}</link>'';+ ''link:${url}[${text}]''; dockerComposeRef = fragment:- ''See <link xlink:href="https://docs.docker.com/compose/compose-file/#${fragment}">Docker Compose#${fragment}</link>'';+ ''See ${link "https://docs.docker.com/compose/compose-file/#${fragment}" "Docker Compose#${fragment}"}''; dockerComposeKitchenSink = ''- Analogous to the <code>docker run</code> counterpart.+ Analogous to the `docker run` counterpart. ${dockerComposeRef "domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir"} '';@@ -33,7 +33,7 @@ out.service = mkOption { type = attrsOf types.unspecified; description = ''- Raw input for the service in <code>docker-compose.yaml</code>.+ Raw input for the service in `docker-compose.yaml`. You should not need to use this option. If anything is missing, please contribute the missing option.@@ -47,7 +47,7 @@ service.name = mkOption { type = str; description = ''- The name of the service - <code><name></code> in the composition-level <code>services.<name></code>+ The name of the service - `<name>` in the composition-level `services.<name>` ''; readOnly = true; };@@ -110,7 +110,7 @@ default = []; description = '' See ${link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"- "<code>docker run --device</code> documentation"}+ "`docker run --device` documentation"} ${dockerComposeRef "devices"} '';@@ -201,11 +201,11 @@ description = '' Enable/disable linux capabilities, or pick Docker's default. - Setting a capability to <code>true</code> means that it will be- "added". Setting it to <code>false</code> means that it will be "dropped".+ Setting a capability to `true` means that it will be+ "added". Setting it to `false` means that it will be "dropped". ${dockerComposeRef "cap_add-cap_drop"} - Omitted and <code>null</code> capabilities will therefore be set+ Omitted and `null` capabilities will therefore be set according to Docker's ${ link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities" "default list of capabilities."
src/nix/modules/service/extended-info.nix view
@@ -12,10 +12,10 @@ type = attrsOf unspecified; description = '' Information about a service to include in the Docker Compose file,- but that will not be used by the <code>docker-compose</code> command+ but that will not be used by the `docker-compose`> command itself. - It will be inserted in <code>x-arion.serviceInfo.<service.name></code>.+ It will be inserted in `x-arion.serviceInfo.<service.name>`. ''; default = {}; };
src/nix/modules/service/host-store.nix view
@@ -1,6 +1,6 @@ /* - This service-level bind mounts the host store into the container+ This service-level module bind mounts the host store into the container when the service.useHostStore option is set to true. */
src/nix/modules/service/image.nix view
@@ -40,7 +40,7 @@ build.image = mkOption { type = nullOr package; description = ''- Docker image derivation to be <code>docker load</code>ed.+ Docker image derivation to be `docker load`ed. ''; internal = true; };@@ -58,11 +58,11 @@ type = bool; description = '' Whether to build this image with Nixpkgs'- <code>dockerTools.buildLayeredImage</code>- and then load it with <code>docker load</code>.+ `dockerTools.buildLayeredImage`+ and then load it with `docker load`. - By default, an image will be built with Nix unless <option>service.image</option>- is set. See also <option>image.name</option>, which defaults to+ By default, an image will be built with Nix unless `service.image`+ is set. See also `image.name`, which defaults to the service name. ''; };@@ -73,8 +73,8 @@ description = '' A human readable name for the docker image. - Shows up in the <code>docker ps</code> output in the- <code>IMAGE</code> column, among other places.+ Shows up in the `docker ps` output in the+ `IMAGE` column, among other places. ''; }; image.contents = mkOption {@@ -92,11 +92,11 @@ been modeled in the Arion module system. This attribute set does not have an appropriate merge function.- Please use the specific <code>image</code> options instead.+ Please use the specific `image` options instead. Run-time configuration of the container. A full list of the- options are available at in the <link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">Docker Image Specification- v1.2.0</link>.+ options is available in the https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions[Docker Image Specification+ v1.2.0]. ''; }; image.command = mkOption {
src/nix/modules/service/nixos-init.nix view
@@ -13,7 +13,7 @@ description = '' When enabled, call the NixOS systemd-based init system. - Configure NixOS with <code>nixos.configuration</code>.+ Configure NixOS with the `nixos.configuration` option. ''; }; };
src/nix/modules/service/nixos.nix view
@@ -18,7 +18,7 @@ This option is unused by default, because not all images use NixOS. - One way to use this is to enable <code>nixos.useSystemd</code>, but the+ One way to use this is to enable `nixos.useSystemd`, but the NixOS configuration can be used in other ways. ''; };@@ -27,11 +27,11 @@ type = attrs; readOnly = true; description = ''- NixOS build products from <code>config.system.build</code>, such as <code>toplevel</code> and <code>etc</code>.+ NixOS build products from `config.system.build`, such as `toplevel` and `etc`. This option is unused by default, because not all images use NixOS. - One way to use this is to enable <code>nixos.useSystemd</code>, but the+ One way to use this is to enable `nixos.useSystemd`, but the NixOS configuration can be used in other ways. ''; };@@ -44,7 +44,7 @@ This option is unused by default, because not all images use NixOS. - One way to use this is to enable <code>nixos.useSystemd</code>, but the+ One way to use this is to enable `nixos.useSystemd`, but the NixOS configuration can be used in other ways. ''; };