Merge #85
85: Use antora for documentation r=roberth a=domenkozar Fixes #10 Co-authored-by: Domen Kožar <domen@dev.si> Co-authored-by: Robert Hensing <roberth@users.noreply.github.com> Co-authored-by: Robert Hensing <robert@roberthensing.nl>
This commit is contained in:
commit
1ed2161bcd
24 changed files with 1295 additions and 852 deletions
269
README.asciidoc
269
README.asciidoc
|
@ -1,274 +1,7 @@
|
||||||
== Introduction
|
|
||||||
|
|
||||||
Arion is a tool for building and running applications that
|
Arion is a tool for building and running applications that
|
||||||
consist of multiple docker containers using NixOS modules.
|
consist of multiple docker containers using NixOS modules.
|
||||||
It has special support for docker images that are built with Nix,
|
It has special support for docker images that are built with Nix,
|
||||||
for a smooth development experience and improved performance.
|
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
|
# [Intro and Documentation](https://docs.hercules-ci.com/arion/)
|
||||||
`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)
|
|
||||||
|
|
13
antora-playbook.yml
Normal file
13
antora-playbook.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# This is not used when the docs are imported into the docs site.
|
||||||
|
# It is only here for development preview.
|
||||||
|
content:
|
||||||
|
sources:
|
||||||
|
- url: .
|
||||||
|
start_path: docs
|
||||||
|
branches: HEAD
|
||||||
|
ui:
|
||||||
|
bundle:
|
||||||
|
url: ./docs/ui-bundle.zip
|
||||||
|
output:
|
||||||
|
dir: ./public
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{ pkgs ? import ../nix {} }:
|
|
||||||
let
|
|
||||||
inherit (pkgs) recurseIntoAttrs callPackage;
|
|
||||||
in
|
|
||||||
|
|
||||||
recurseIntoAttrs {
|
|
||||||
manual = callPackage ./manual {};
|
|
||||||
}
|
|
2
doc/manual/.gitignore
vendored
2
doc/manual/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
manual.html
|
|
||||||
options-composition.xml
|
|
|
@ -1,35 +0,0 @@
|
||||||
xsltproc = xsltproc --nonet \
|
|
||||||
--param section.autolabel 0 \
|
|
||||||
--param section.label.includes.component.label 0 \
|
|
||||||
--param chapter.autolabel 0 \
|
|
||||||
--param chapter.label.includes.component.label 0 \
|
|
||||||
--param appendix.autolabel 0 \
|
|
||||||
--param appendix.label.includes.component.label 0 \
|
|
||||||
--param generate.toc "'book toc,title chapter nop section nop sect1 nop sect2 nop sect3 nop sect4 nop sect5 nop'" \
|
|
||||||
--param html.stylesheet \'style.css\' \
|
|
||||||
--param xref.with.number.and.title 0 \
|
|
||||||
--param toc.section.depth 3 \
|
|
||||||
--param admon.style \'\' \
|
|
||||||
--param callout.graphics.extension \'.gif\' \
|
|
||||||
--param contrib.inline.enabled 0
|
|
||||||
|
|
||||||
docbookxsl = http://docbook.sourceforge.net/release/xsl/current
|
|
||||||
|
|
||||||
all: manual.html
|
|
||||||
|
|
||||||
manual.html: manual.xml options-composition.xml
|
|
||||||
$(xsltproc) --xinclude --stringparam profile.condition manual \
|
|
||||||
$(docbookxsl)/profiling/profile.xsl manual.xml | \
|
|
||||||
$(xsltproc) --output manual.html $(docbookxsl)/xhtml/docbook.xsl -
|
|
||||||
|
|
||||||
# -e 's_<book lang="en">__' -e 's_</book>__'
|
|
||||||
%.xml: %.asciidoc
|
|
||||||
asciidoctor --backend docbook45 --doctype article $<
|
|
||||||
sed -e 's/<!DOCTYPE.*//' -e 's/<?asciidoc-[a-z]*?>//' -i $@
|
|
||||||
|
|
||||||
options-composition.xml:
|
|
||||||
echo "options-composition.xml should be written by the derivation. Are you running in 'nix-shell -A manual'?"; exit 1; fi
|
|
||||||
|
|
||||||
install: all
|
|
||||||
mkdir -p $(docdir)
|
|
||||||
cp manual.html style.css $(docdir)
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
nix-shell -A manual --run 'patchPhase && make'
|
|
|
@ -1,110 +0,0 @@
|
||||||
{ pkgs ? import ../../nix {}
|
|
||||||
, version ? "none"
|
|
||||||
# Default sourceUrl is for local development. Works with
|
|
||||||
# nix-build -A doc.manual
|
|
||||||
# For release, use: https://github.com/hercules-ci/arion/blob/${version}
|
|
||||||
, sourceUrl ? "../../.."
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (pkgs) recurseIntoAttrs callPackage runCommand lib stdenv ;
|
|
||||||
|
|
||||||
nixosManualPath = s: "${pkgs.path}/nixos/doc/manual/${s}";
|
|
||||||
|
|
||||||
# NixOS module system options in JSON format.
|
|
||||||
options = { moduleType, description, /*optionsList*/ optionsExpr }: recurseIntoAttrs rec {
|
|
||||||
optionsXML =
|
|
||||||
# builtins.toFile "options.xml" (builtins.toXML optionsList);
|
|
||||||
pkgs.runCommand "options.xml" {
|
|
||||||
buildInputs = [pkgs.nix pkgs.jq];
|
|
||||||
inherit optionsExpr;
|
|
||||||
} ''
|
|
||||||
export NIX_LOG_DIR=$PWD
|
|
||||||
export NIX_STATE_DIR=$PWD
|
|
||||||
nix-instantiate \
|
|
||||||
--option sandbox false \
|
|
||||||
--readonly-mode \
|
|
||||||
--eval \
|
|
||||||
--expr "$optionsExpr" \
|
|
||||||
--xml \
|
|
||||||
--strict \
|
|
||||||
--show-trace \
|
|
||||||
>$out
|
|
||||||
'';
|
|
||||||
|
|
||||||
optionsDocBook = runCommand "options-db.xml" {} ''
|
|
||||||
optionsXML=${optionsXML}
|
|
||||||
${pkgs.buildPackages.libxslt.bin}/bin/xsltproc \
|
|
||||||
--stringparam revision '${version}' \
|
|
||||||
--stringparam sourceUrl '${sourceUrl}' \
|
|
||||||
-o intermediate.xml ${./options-to-docbook.xsl} $optionsXML
|
|
||||||
${pkgs.buildPackages.libxslt.bin}/bin/xsltproc \
|
|
||||||
-o "$out" ${nixosManualPath "postprocess-option-descriptions.xsl"} intermediate.xml
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
compositionOptions = options {
|
|
||||||
moduleType = "composition";
|
|
||||||
description = "List of Arion composition-level options in JSON format";
|
|
||||||
optionsExpr = let
|
|
||||||
src = ../../src/nix;
|
|
||||||
in ''
|
|
||||||
let pkgs = import ${pkgs.path} {};
|
|
||||||
fixPaths = opt: opt // {
|
|
||||||
declarations = map (d: "src/nix" + (lib.strings.removePrefix (toString ${src}) (toString d))) opt.declarations;
|
|
||||||
};
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
composition = import ${src}/eval-composition.nix { inherit pkgs; };
|
|
||||||
in map fixPaths (lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList composition.options))
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
generatedDocBook = runCommand "generated-docbook" {} ''
|
|
||||||
mkdir $out
|
|
||||||
ln -s ${compositionOptions.optionsDocBook} $out/options-composition.xml
|
|
||||||
'';
|
|
||||||
|
|
||||||
manual = stdenv.mkDerivation {
|
|
||||||
src = lib.sourceByRegex ./. [
|
|
||||||
"Makefile$"
|
|
||||||
".*\.asciidoc$"
|
|
||||||
".*\.xsl$"
|
|
||||||
".*\.css$"
|
|
||||||
"^manual.xml$"
|
|
||||||
"^manual.xml$"
|
|
||||||
];
|
|
||||||
name = "arion-manual";
|
|
||||||
version = version;
|
|
||||||
buildInputs = [
|
|
||||||
(pkgs.libxslt.bin or pkgs.libxslt)
|
|
||||||
pkgs.asciidoctor
|
|
||||||
];
|
|
||||||
XML_CATALOG_FILES = "${pkgs.docbook_xsl}/xml/xsl/docbook/catalog.xml";
|
|
||||||
inherit generatedDocBook;
|
|
||||||
configurePhase = ''
|
|
||||||
export docdir=$out/doc
|
|
||||||
'';
|
|
||||||
postPatch = ''
|
|
||||||
substituteInPlace manual.xml --subst-var version
|
|
||||||
'';
|
|
||||||
prePatch = ''
|
|
||||||
cp ${generatedDocBook}/* .
|
|
||||||
substituteInPlace options-composition.xml \
|
|
||||||
--replace 'xml:id="appendix-configuration-options"' 'xml:id="appendix-composition-options"' \
|
|
||||||
--replace '<title>Configuration Options</title>' '<title>Composition Options</title>' \
|
|
||||||
--replace 'xml:id="configuration-variable-list"' 'xml:id="composition-variable-list"' \
|
|
||||||
;
|
|
||||||
'';
|
|
||||||
shellHook = ''
|
|
||||||
live-build() {
|
|
||||||
patchPhase
|
|
||||||
inotifywait -e MODIFY -m -r . | while read; do
|
|
||||||
make
|
|
||||||
done
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
passthru = {
|
|
||||||
inherit generatedDocBook;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
manual
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env nix-shell
|
|
||||||
#!nix-shell -A manual
|
|
||||||
#!nix-shell --run live-build
|
|
|
@ -1,21 +0,0 @@
|
||||||
<book xmlns="http://docbook.org/ns/docbook"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
||||||
|
|
||||||
<info>
|
|
||||||
|
|
||||||
<title>Arion Manual</title>
|
|
||||||
<subtitle>Version none</subtitle>
|
|
||||||
|
|
||||||
<author>
|
|
||||||
<affiliation>
|
|
||||||
<orgname>Hercules Labs and other Arion contributors</orgname>
|
|
||||||
</affiliation>
|
|
||||||
<contrib>Author</contrib>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
</info>
|
|
||||||
|
|
||||||
<xi:include href="options-composition.xml" />
|
|
||||||
|
|
||||||
</book>
|
|
|
@ -1,224 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<xsl:stylesheet version="1.0"
|
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
||||||
xmlns:str="http://exslt.org/strings"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:nixos="tag:nixos.org"
|
|
||||||
xmlns="http://docbook.org/ns/docbook"
|
|
||||||
extension-element-prefixes="str"
|
|
||||||
>
|
|
||||||
|
|
||||||
<xsl:output method='xml' encoding="UTF-8" />
|
|
||||||
|
|
||||||
<xsl:param name="revision" />
|
|
||||||
<xsl:param name="program" />
|
|
||||||
<xsl:param name="sourceUrl" />
|
|
||||||
<xsl:param name="nixPathKey" />
|
|
||||||
|
|
||||||
<xsl:template match="/expr/list">
|
|
||||||
<appendix xml:id="appendix-configuration-options">
|
|
||||||
<title>Configuration Options</title>
|
|
||||||
<variablelist xml:id="configuration-variable-list">
|
|
||||||
<xsl:for-each select="attrs">
|
|
||||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
|
||||||
<varlistentry>
|
|
||||||
<term xlink:href="#{$id}">
|
|
||||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
|
||||||
<option>
|
|
||||||
<xsl:value-of select="attr[@name = 'name']/string/@value" />
|
|
||||||
</option>
|
|
||||||
</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<nixos:option-description>
|
|
||||||
<para>
|
|
||||||
<xsl:value-of disable-output-escaping="yes"
|
|
||||||
select="attr[@name = 'description']/string/@value" />
|
|
||||||
</para>
|
|
||||||
</nixos:option-description>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'type']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Type:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:value-of select="attr[@name = 'type']/string/@value"/>
|
|
||||||
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<emphasis>(read only)</emphasis>
|
|
||||||
</xsl:if>
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'default']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Default:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'example']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Example:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
|
||||||
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'relatedPackages']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Related packages:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:value-of disable-output-escaping="yes"
|
|
||||||
select="attr[@name = 'relatedPackages']/string/@value" />
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
|
||||||
<para>
|
|
||||||
<emphasis>Declared by:</emphasis>
|
|
||||||
</para>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'declarations']" />
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
|
|
||||||
<para>
|
|
||||||
<emphasis>Defined by:</emphasis>
|
|
||||||
</para>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'definitions']" />
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</xsl:for-each>
|
|
||||||
|
|
||||||
</variablelist>
|
|
||||||
</appendix>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="*" mode="top">
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="string[contains(@value, '
')]">
|
|
||||||
<programlisting>
|
|
||||||
<xsl:text>''
|
|
||||||
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "''${")' /><xsl:text>''</xsl:text></programlisting>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<literal><xsl:apply-templates /></literal>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="null">
|
|
||||||
<xsl:text>null</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="string">
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="(contains(@value, '"') or contains(@value, '\')) and not(contains(@value, '
'))">
|
|
||||||
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "''${")' /><xsl:text>''</xsl:text>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '"', '\"'), '
', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="int">
|
|
||||||
<xsl:value-of select="@value" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="bool[@value = 'true']">
|
|
||||||
<xsl:text>true</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="bool[@value = 'false']">
|
|
||||||
<xsl:text>false</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="list">
|
|
||||||
[
|
|
||||||
<xsl:for-each select="*">
|
|
||||||
<xsl:apply-templates select="." />
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:for-each>
|
|
||||||
]
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
|
||||||
<xsl:value-of select="attr[@name = 'text']/string/@value" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="attrs">
|
|
||||||
{
|
|
||||||
<xsl:for-each select="attr">
|
|
||||||
<xsl:value-of select="@name" />
|
|
||||||
<xsl:text> = </xsl:text>
|
|
||||||
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
|
|
||||||
</xsl:for-each>
|
|
||||||
}
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="derivation">
|
|
||||||
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
|
|
||||||
<simplelist>
|
|
||||||
<xsl:for-each select="list/string">
|
|
||||||
<member><filename>
|
|
||||||
<!-- Hyperlink the filename either to the NixOS Subversion
|
|
||||||
repository (if it’s a module and we have a revision number),
|
|
||||||
or to the local filesystem. -->
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="not(starts-with(@value, '/'))">
|
|
||||||
<xsl:attribute name="xlink:href"><xsl:value-of select="$sourceUrl"/>/<xsl:value-of select="@value"/></xsl:attribute>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
<!-- Print the filename and make it user-friendly by replacing the
|
|
||||||
/nix/store/<hash> prefix by the default location of nixos
|
|
||||||
sources. -->
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="$nixPathKey != ''">
|
|
||||||
<<xsl:value-of select="$nixPathKey"/>/<xsl:value-of select="@value"/>>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:value-of select="@value" />
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</filename></member>
|
|
||||||
</xsl:for-each>
|
|
||||||
</simplelist>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="function">
|
|
||||||
<xsl:text>λ</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
|
|
@ -1,159 +0,0 @@
|
||||||
|
|
||||||
hr { color: #ddd; margin-top: 3ex; }
|
|
||||||
h1, h2, h3, h4 { font-weight: bold; }
|
|
||||||
h1 { font-size: 200%; margin-top: 5ex; }
|
|
||||||
h2 { font-size: 160%; margin-top: 4ex; }
|
|
||||||
h3,h4 { font-size: 120%; margin-top: 3ex; }
|
|
||||||
|
|
||||||
/* From Semantic UI */
|
|
||||||
body {
|
|
||||||
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.4285em;
|
|
||||||
color: rgba(0,0,0,.87);
|
|
||||||
}
|
|
||||||
|
|
||||||
code.literal {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
background-color:transparent;
|
|
||||||
-webkit-text-decoration-skip:objects
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color:#4183c4;
|
|
||||||
text-decoration:none
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color:#1e70bf;
|
|
||||||
text-decoration:none
|
|
||||||
}
|
|
||||||
::-webkit-selection {
|
|
||||||
background-color:#cce2ff;
|
|
||||||
color:rgba(0,0,0,.87)
|
|
||||||
}
|
|
||||||
::-moz-selection {
|
|
||||||
background-color:#cce2ff;
|
|
||||||
color:rgba(0,0,0,.87)
|
|
||||||
}
|
|
||||||
::selection {
|
|
||||||
background-color:#cce2ff;
|
|
||||||
color:rgba(0,0,0,.87)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* toc menu */
|
|
||||||
@media screen and (min-width: 60em) {
|
|
||||||
body {
|
|
||||||
margin-left: 16.5em;
|
|
||||||
}
|
|
||||||
div.toc {
|
|
||||||
position: fixed;
|
|
||||||
top: 0pt;
|
|
||||||
left: 1em;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
width: 15.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (min-width: 90em) {
|
|
||||||
div.toc {
|
|
||||||
left: 5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* hide per chapter toc */
|
|
||||||
div.chapter div.toc {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* From Nixpkgs: */
|
|
||||||
|
|
||||||
div.book
|
|
||||||
{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.book > div
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* based on https://medium.com/@zkareemz/golden-ratio-62b3b6d4282a
|
|
||||||
* we do 70 characters per line to fit code listings better
|
|
||||||
* 70 * (font-size / 1.618)
|
|
||||||
* expression for emacs:
|
|
||||||
* (* 70 (/ 1 1.618))
|
|
||||||
*/
|
|
||||||
max-width: 43.2em;
|
|
||||||
text-align: left;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Special elements:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
.term
|
|
||||||
{
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variablelist dd p, div.glosslist dd p
|
|
||||||
{
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variablelist dd, div.glosslist dd
|
|
||||||
{
|
|
||||||
margin-left: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.glosslist dt
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.varname
|
|
||||||
{
|
|
||||||
color: #004000;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.command strong
|
|
||||||
{
|
|
||||||
font-weight: normal;
|
|
||||||
color: #004000;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.calloutlist table
|
|
||||||
{
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-collapse: collapse;
|
|
||||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.simplelist
|
|
||||||
{
|
|
||||||
text-align: left;
|
|
||||||
color: #005aa0;
|
|
||||||
border: 0;
|
|
||||||
padding: 5px;
|
|
||||||
background: #fffff5;
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
box-shadow: none;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navheader table, div.navfooter table {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.affiliation
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
6
docs/antora.yml
Normal file
6
docs/antora.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
name: arion
|
||||||
|
title: Arion Documentation
|
||||||
|
version: 'master'
|
||||||
|
nav:
|
||||||
|
- modules/ROOT/nav.adoc
|
||||||
|
- modules/reference/nav.adoc
|
2
docs/modules/ROOT/nav.adoc
Normal file
2
docs/modules/ROOT/nav.adoc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
* xref:index.adoc[Getting Started]
|
||||||
|
* xref:options.adoc[Arion Options]
|
276
docs/modules/ROOT/pages/index.adoc
Normal file
276
docs/modules/ROOT/pages/index.adoc
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
= Welcome to Arion documentation
|
||||||
|
|
||||||
|
== 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)
|
1
docs/modules/ROOT/pages/options.adoc
Normal file
1
docs/modules/ROOT/pages/options.adoc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include::partial$NixOSOptions.adoc[]
|
941
docs/modules/ROOT/partials/NixOSOptions.adoc
Normal file
941
docs/modules/ROOT/partials/NixOSOptions.adoc
Normal file
|
@ -0,0 +1,941 @@
|
||||||
|
= Arion options
|
||||||
|
|
||||||
|
== docker-compose.extended
|
||||||
|
|
||||||
|
Attribute set that will be turned into the x-arion section of the docker-compose.yaml file.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== docker-compose.raw
|
||||||
|
|
||||||
|
Attribute set that will be turned into the docker-compose.yaml file, using Nix's toJSON builtin.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== host.nixStorePrefix
|
||||||
|
|
||||||
|
Prefixes store paths on the host, allowing the Nix store to be
|
||||||
|
stored at an alternate location without altering the format of
|
||||||
|
store paths.
|
||||||
|
|
||||||
|
For example: instead of mounting the host's /nix/store as the
|
||||||
|
container's /nix/store, this will mount /mnt/foo/nix/store
|
||||||
|
as the container's /nix/store.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
""
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Example::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
"/mnt/foo"
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
== host.uid
|
||||||
|
|
||||||
|
The numeric user id (UID) of the user running arion.
|
||||||
|
|
||||||
|
This lets you to write modules that interact with the host
|
||||||
|
user's files, which is helpful for local development, but not
|
||||||
|
intended for production-like deployment scenarios.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: signed integer
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== out.dockerComposeYaml
|
||||||
|
|
||||||
|
A derivation that produces a docker-compose.yaml file for this composition.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: package
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== out.dockerComposeYamlAttrs
|
||||||
|
|
||||||
|
The text of out.dockerComposeYaml.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of unspecifieds
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== out.dockerComposeYamlText
|
||||||
|
|
||||||
|
The text of out.dockerComposeYaml.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: string
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services
|
||||||
|
|
||||||
|
An attribute set of service configurations. A service specifies how to run an image as a container.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of submodules
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.composition
|
||||||
|
|
||||||
|
The composition configuration.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.host
|
||||||
|
|
||||||
|
The composition-level host option values.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.image.command
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.image.contents
|
||||||
|
|
||||||
|
Top level paths in the container.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of packages
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.image.name
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{"_type":"literalExample","text":"config.service.name"}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.image.nixBuild
|
||||||
|
|
||||||
|
Whether to build this image with Nixpkgs'
|
||||||
|
<code>dockerTools.buildLayeredImage</code>
|
||||||
|
and then load it with <code>docker load</code>.
|
||||||
|
|
||||||
|
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
|
||||||
|
the service name.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: boolean
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.image.rawConfig
|
||||||
|
|
||||||
|
This is a low-level fallback for when a container option has not
|
||||||
|
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.
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of unspecifieds
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.nixos.build
|
||||||
|
|
||||||
|
NixOS build products from <code>config.system.build</code>, such as <code>toplevel</code> and <code>etc</code>.
|
||||||
|
|
||||||
|
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
|
||||||
|
NixOS configuration can be used in other ways.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.nixos.configuration
|
||||||
|
|
||||||
|
Modules to add to the NixOS configuration.
|
||||||
|
|
||||||
|
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
|
||||||
|
NixOS configuration can be used in other ways.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of unspecifieds or unspecified convertible to it
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.nixos.evaluatedConfig
|
||||||
|
|
||||||
|
Evaluated NixOS configuration, to be read by service-level modules.
|
||||||
|
|
||||||
|
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
|
||||||
|
NixOS configuration can be used in other ways.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.nixos.useSystemd
|
||||||
|
|
||||||
|
When enabled, call the NixOS systemd-based init system.
|
||||||
|
|
||||||
|
Configure NixOS with <code>nixos.configuration</code>.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
false
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.out.extendedInfo
|
||||||
|
|
||||||
|
Information about a service to include in the Docker Compose file,
|
||||||
|
but that will not be used by the <code>docker-compose</code> command
|
||||||
|
itself.
|
||||||
|
|
||||||
|
It will be inserted in <code>x-arion.serviceInfo.<service.name></code>.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of unspecifieds
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.out.service
|
||||||
|
|
||||||
|
Raw input for the service in <code>docker-compose.yaml</code>.
|
||||||
|
|
||||||
|
You should not need to use this option. If anything is
|
||||||
|
missing, please contribute the missing option.
|
||||||
|
|
||||||
|
This option is user accessible because it may serve as an
|
||||||
|
escape hatch for some.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of unspecifieds
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.build.context
|
||||||
|
|
||||||
|
Locates a Dockerfile to use for creating an image to use in this service.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#context">Docker Compose#context</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.capabilities
|
||||||
|
|
||||||
|
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".
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#cap_add-cap_drop">Docker Compose#cap_add-cap_drop</link>
|
||||||
|
|
||||||
|
Omitted and <code>null</code> capabilities will therefore be set
|
||||||
|
according to Docker's <link xlink:href="https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities">default list of capabilities.</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of null or booleans
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Example::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{"ALL":true,"NET_ADMIN":false,"SYS_ADMIN":false}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
== services.<name>.service.command
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#command">Docker Compose#command</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or unspecified
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.container_name
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#container_name">Docker Compose#container_name</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.defaultExec
|
||||||
|
|
||||||
|
Container program and arguments to invoke when calling
|
||||||
|
<code>arion exec <service.name></code> without further arguments.
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
["/bin/sh"]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.depends_on
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#depends_on">Docker Compose#depends_on</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.devices
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"><code>docker run --device</code> documentation</link>
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#devices">Docker Compose#devices</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.entrypoint
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#entrypoint">Docker Compose#entrypoint</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.env_file
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#env_file">Docker Compose#env_file</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.environment
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#environment">Docker Compose#environment</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of string or signed integers
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.expose
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#expose">Docker Compose#expose</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.external_links
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#external_links">Docker Compose#external_links</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.extra_hosts
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#extra_hosts">Docker Compose#extra_hosts</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.hostStoreAsReadOnly
|
||||||
|
|
||||||
|
Adds a ':ro' (read-only) access mode to the host nix store bind mount.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
true
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.hostname
|
||||||
|
|
||||||
|
Analogous to the <code>docker run</code> counterpart.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir">Docker Compose#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.image
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#image">Docker Compose#image</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: string
|
||||||
|
No Default:: {blank}
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.links
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#links">Docker Compose#links</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.name
|
||||||
|
|
||||||
|
The name of the service - <code><name></code> in the composition-level <code>services.<name></code>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: string
|
||||||
|
No Default:: {blank}
|
||||||
|
Read Only:: {blank}
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.network_mode
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#network_mode">Docker Compose#network_mode</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.networks
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#networks">Docker Compose#networks</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.ports
|
||||||
|
|
||||||
|
Expose ports on host. "host:container" or structured.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#ports">Docker Compose#ports</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of unspecifieds
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.privileged
|
||||||
|
|
||||||
|
Analogous to the <code>docker run</code> counterpart.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir">Docker Compose#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.restart
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#restart">Docker Compose#restart</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.stop_signal
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#stop_signal">Docker Compose#stop_signal</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.sysctls
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#sysctls">Docker Compose#sysctls</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: attribute set of string or signed integers
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
{}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.tmpfs
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#tmpfs">Docker Compose#tmpfs</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of strings
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.tty
|
||||||
|
|
||||||
|
Analogous to the <code>docker run</code> counterpart.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir">Docker Compose#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.useHostNixDaemon
|
||||||
|
|
||||||
|
Make the host Nix daemon available.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
false
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.useHostStore
|
||||||
|
|
||||||
|
Bind mounts the host store if enabled, avoiding copying.
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: boolean
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
false
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.user
|
||||||
|
|
||||||
|
Analogous to the <code>docker run</code> counterpart.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir">Docker Compose#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.volumes
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#volumes">Docker Compose#volumes</link>
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: list of unspecifieds
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
||||||
|
== services.<name>.service.working_dir
|
||||||
|
|
||||||
|
Analogous to the <code>docker run</code> counterpart.
|
||||||
|
|
||||||
|
See <link xlink:href="https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir">Docker Compose#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir</link>
|
||||||
|
|
||||||
|
|
||||||
|
[discrete]
|
||||||
|
=== details
|
||||||
|
|
||||||
|
Type:: null or string
|
||||||
|
Default::
|
||||||
|
+
|
||||||
|
----
|
||||||
|
null
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
No Example:: {blank}
|
||||||
|
|
15
docs/options.nix
Normal file
15
docs/options.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ pkgs ? import ../nix {} }:
|
||||||
|
|
||||||
|
let
|
||||||
|
eval = pkgs.lib.evalModules {
|
||||||
|
modules = import ../src/nix/modules.nix;
|
||||||
|
};
|
||||||
|
options = pkgs.nixosOptionsDoc {
|
||||||
|
options = eval.options;
|
||||||
|
};
|
||||||
|
|
||||||
|
in pkgs.writeText "agent-options" ''
|
||||||
|
= Arion options
|
||||||
|
|
||||||
|
${options.optionsAsciiDoc}
|
||||||
|
''
|
BIN
docs/ui-bundle.zip
Normal file
BIN
docs/ui-bundle.zip
Normal file
Binary file not shown.
13
nix/ci.nix
13
nix/ci.nix
|
@ -8,20 +8,15 @@ dimension "Nixpkgs version" {
|
||||||
"nixos-19_03" = {
|
"nixos-19_03" = {
|
||||||
nixpkgsSource = "nixpkgs";
|
nixpkgsSource = "nixpkgs";
|
||||||
isReferenceNixpkgs = true;
|
isReferenceNixpkgs = true;
|
||||||
|
enableDoc = false;
|
||||||
};
|
};
|
||||||
"nixos-19_09" = {
|
"nixos-19_09" = {
|
||||||
nixpkgsSource = "nixos-19.09";
|
nixpkgsSource = "nixos-19.09";
|
||||||
|
enableDoc = true;
|
||||||
# Broken since 19.09, wontfix because doc tooling will be changed.
|
|
||||||
# TODO: reenable
|
|
||||||
enableDoc = false;
|
|
||||||
};
|
};
|
||||||
"nixos-unstable" = {
|
"nixos-unstable" = {
|
||||||
nixpkgsSource = "nixos-unstable";
|
nixpkgsSource = "nixos-unstable";
|
||||||
|
enableDoc = true;
|
||||||
# Broken since 19.09, wontfix because doc tooling will be changed.
|
|
||||||
# TODO: reenable
|
|
||||||
enableDoc = false;
|
|
||||||
};
|
};
|
||||||
} (
|
} (
|
||||||
_name: { nixpkgsSource, isReferenceNixpkgs ? false, enableDoc ? true }:
|
_name: { nixpkgsSource, isReferenceNixpkgs ? false, enableDoc ? true }:
|
||||||
|
@ -39,7 +34,7 @@ dimension "Nixpkgs version" {
|
||||||
{
|
{
|
||||||
inherit (pkgs) arion tests;
|
inherit (pkgs) arion tests;
|
||||||
} // lib.optionalAttrs enableDoc {
|
} // lib.optionalAttrs enableDoc {
|
||||||
doc = pkgs.recurseIntoAttrs (import ../doc { inherit pkgs; });
|
inherit (pkgs) doc doc-options doc-options-check;
|
||||||
} // lib.optionalAttrs isReferenceTarget {
|
} // lib.optionalAttrs isReferenceTarget {
|
||||||
inherit (pkgs.arion-project.haskellPkgs) arion-compose-checked;
|
inherit (pkgs.arion-project.haskellPkgs) arion-compose-checked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{ sources ? import ./sources.nix
|
{ sources ? import ./sources.nix
|
||||||
, nixpkgsSrc ? sources.nixpkgs
|
, nixpkgsName ? "nixos-19.09"
|
||||||
|
, nixpkgsSrc ? sources.${nixpkgsName}
|
||||||
, system ? builtins.currentSystem
|
, system ? builtins.currentSystem
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
|
|
|
@ -5,12 +5,34 @@ let
|
||||||
|
|
||||||
sources = import ./sources.nix;
|
sources = import ./sources.nix;
|
||||||
|
|
||||||
|
fakeRepo = src: super.runCommand "source" { inherit src; buildInputs = [super.git]; } ''
|
||||||
|
cp -r --no-preserve=mode $src $out
|
||||||
|
git init
|
||||||
|
cp -r .git $out
|
||||||
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
inherit (import ./.. { pkgs = self; }) arion;
|
inherit (import ./.. { pkgs = self; }) arion;
|
||||||
tests = super.callPackage ../tests {};
|
tests = super.callPackage ../tests {};
|
||||||
doc = super.callPackage ../doc {};
|
|
||||||
|
doc-options = import ../docs/options.nix {};
|
||||||
|
doc-options-check = self.runCommand "doc-options-check" {} ''
|
||||||
|
diff --color -u ${../docs/modules/ROOT/partials/NixOSOptions.adoc} ${self.doc-options}
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
doc = self.stdenv.mkDerivation {
|
||||||
|
name = "arion-documentation";
|
||||||
|
buildInputs = [super.antora];
|
||||||
|
src = fakeRepo ../.;
|
||||||
|
HOME = ".";
|
||||||
|
buildPhase = "antora antora-playbook";
|
||||||
|
installPhase = ''
|
||||||
|
mkdir $out
|
||||||
|
mv public/* $out/
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
arion-project = super.recurseIntoAttrs {
|
arion-project = super.recurseIntoAttrs {
|
||||||
haskellPkgs = super.haskellPackages.extend (import ./haskell-overlay.nix self super);
|
haskellPkgs = super.haskellPackages.extend (import ./haskell-overlay.nix self super);
|
||||||
|
|
|
@ -42,10 +42,10 @@
|
||||||
"homepage": "https://github.com/NixOS/nixpkgs",
|
"homepage": "https://github.com/NixOS/nixpkgs",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs-channels",
|
"repo": "nixpkgs-channels",
|
||||||
"rev": "6420e2649fa9e267481fb78e602022dab9d1dcd1",
|
"rev": "d15a31f88a261281cd7c79038ae860c5ed95507d",
|
||||||
"sha256": "1z3hx7gp8nxk3fspi8vik3j9zxpajj3s7nxvjvx3b5igndxwbp74",
|
"sha256": "038iqfwmppnxq6aa89qm6k98lhwg686bmc9qjifibddm8pcp2wd0",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://github.com/NixOS/nixpkgs-channels/archive/6420e2649fa9e267481fb78e602022dab9d1dcd1.tar.gz",
|
"url": "https://github.com/NixOS/nixpkgs-channels/archive/d15a31f88a261281cd7c79038ae860c5ed95507d.tar.gz",
|
||||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
},
|
},
|
||||||
"project.nix": {
|
"project.nix": {
|
||||||
|
|
|
@ -18,12 +18,7 @@ let
|
||||||
|
|
||||||
builtinModules = [
|
builtinModules = [
|
||||||
argsModule
|
argsModule
|
||||||
./modules/composition/docker-compose.nix
|
] ++ import ./modules.nix;
|
||||||
./modules/composition/host-environment.nix
|
|
||||||
./modules/composition/images.nix
|
|
||||||
./modules/composition/service-info.nix
|
|
||||||
./modules/composition/arion-base-image.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
argsModule = {
|
argsModule = {
|
||||||
_file = ./eval-composition.nix;
|
_file = ./eval-composition.nix;
|
||||||
|
|
7
src/nix/modules.nix
Normal file
7
src/nix/modules.nix
Normal file
|
@ -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
|
||||||
|
]
|
Loading…
Reference in a new issue