Use antora for documentation

This commit is contained in:
Domen Kožar 2019-10-24 19:36:58 +02:00
parent 4444cf1856
commit 5140cf0a09
No known key found for this signature in database
GPG Key ID: C2FFBCAFD2C24246
24 changed files with 1288 additions and 858 deletions

View File

@ -1,274 +1 @@
== 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, youll 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 Arions 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, its 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)
# [Documentation](https://docs.hercules-ci.com/arion/)

11
antora-playbook.yml Normal file
View File

@ -0,0 +1,11 @@
content:
sources:
- url: .
start_path: docs
branches: HEAD
ui:
bundle:
url: ./docs/ui-bundle.zip
output:
dir: ./public

View File

@ -1,8 +0,0 @@
{ pkgs ? import ../nix {} }:
let
inherit (pkgs) recurseIntoAttrs callPackage;
in
recurseIntoAttrs {
manual = callPackage ./manual {};
}

View File

@ -1,2 +0,0 @@
manual.html
options-composition.xml

View File

@ -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)

View File

@ -1,2 +0,0 @@
#!/usr/bin/env bash
nix-shell -A manual --run 'patchPhase && make'

View File

@ -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

View File

@ -1,3 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -A manual
#!nix-shell --run live-build

View File

@ -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>

View File

@ -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, '*', '_'), '&lt;', '_'), '>', '_'), '?', '_'))" />
<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, '&#010;')]">
<programlisting>
<xsl:text>''
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "&apos;&apos;${")' /><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, '&quot;') or contains(@value, '\')) and not(contains(@value, '&#010;'))">
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "&apos;&apos;${")' /><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, '\', '\\'), '&quot;', '\&quot;'), '&#010;', '\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 its 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 != ''">
&lt;<xsl:value-of select="$nixPathKey"/>/<xsl:value-of select="@value"/>&gt;
</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>

View File

@ -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
View File

@ -0,0 +1,6 @@
name: arion
title: Arion Documentation
version: 'master'
nav:
- modules/ROOT/nav.adoc
- modules/reference/nav.adoc

View File

@ -0,0 +1,2 @@
* xref:index.adoc[Getting Started]
* xref:options.adoc[Arion Options]

View 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, youll 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 Arions 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, its 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)

View File

@ -0,0 +1 @@
include::partial$NixOSOptions.adoc[]

View 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.&lt;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 &lt;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>&lt;name></code> in the composition-level <code>services.&lt;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}

16
docs/options.nix Normal file
View File

@ -0,0 +1,16 @@
{ pkgs ? import ../nix {} }:
let
eval = import (pkgs.path + "/nixos/lib/eval-config.nix") {
baseModules = import ../src/nix/module-composition.nix;
modules = [];
};
options = pkgs.nixosOptionsDoc {
options = eval.options;
};
in pkgs.writeText "agent-options" ''
= Arion options
${options.optionsAsciiDoc}
''

BIN
docs/ui-bundle.zip Normal file

Binary file not shown.

View File

@ -8,20 +8,15 @@ dimension "Nixpkgs version" {
"nixos-19_03" = {
nixpkgsSource = "nixpkgs";
isReferenceNixpkgs = true;
enableDoc = false;
};
"nixos-19_09" = {
nixpkgsSource = "nixos-19.09";
# Broken since 19.09, wontfix because doc tooling will be changed.
# TODO: reenable
enableDoc = false;
enableDoc = true;
};
"nixos-unstable" = {
nixpkgsSource = "nixos-unstable";
# Broken since 19.09, wontfix because doc tooling will be changed.
# TODO: reenable
enableDoc = false;
enableDoc = true;
};
} (
_name: { nixpkgsSource, isReferenceNixpkgs ? false, enableDoc ? true }:
@ -39,7 +34,7 @@ dimension "Nixpkgs version" {
{
inherit (pkgs) arion tests;
} // lib.optionalAttrs enableDoc {
doc = pkgs.recurseIntoAttrs (import ../doc { inherit pkgs; });
inherit (pkgs) doc doc-options doc-options-check;
} // lib.optionalAttrs isReferenceTarget {
inherit (pkgs.arion-project.haskellPkgs) arion-compose-checked;
}

View File

@ -1,5 +1,6 @@
{ sources ? import ./sources.nix
, nixpkgsSrc ? sources.nixpkgs
, nixpkgsName ? "nixos-19.09"
, nixpkgsSrc ? sources.${nixpkgsName}
, system ? builtins.currentSystem
, ...
}:

View File

@ -10,7 +10,23 @@ in
inherit (import ./.. { pkgs = self; }) arion;
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 = ../.;
HOME = ".";
buildPhase = "antora antora-playbook";
installPhase = ''
mkdir $out
mv public/* $out/
'';
};
arion-project = super.recurseIntoAttrs {
haskellPkgs = super.haskellPackages.extend (import ./haskell-overlay.nix self super);

View File

@ -42,10 +42,10 @@
"homepage": "https://github.com/NixOS/nixpkgs",
"owner": "NixOS",
"repo": "nixpkgs-channels",
"rev": "6420e2649fa9e267481fb78e602022dab9d1dcd1",
"sha256": "1z3hx7gp8nxk3fspi8vik3j9zxpajj3s7nxvjvx3b5igndxwbp74",
"rev": "d15a31f88a261281cd7c79038ae860c5ed95507d",
"sha256": "038iqfwmppnxq6aa89qm6k98lhwg686bmc9qjifibddm8pcp2wd0",
"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"
},
"project.nix": {

View File

@ -18,12 +18,7 @@ let
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 ./module-composition.nix;
argsModule = {
_file = ./eval-composition.nix;

View 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
]