Teenix Containers

Wie bereits erwähnt benutzt Teenix sehr viele NixOS Container. Um uns die Arbeit etwas einfacher zu machen haben wir uns ein eigenes Modul geschrieben was die containers und teenix.persist Optionen “wrapped” um häufige Konfigurationen umzusetzen.

Überblick

Diese Defaults sind:

  • Den Container Autostarten
  • Das Dateisystem des Containers ephemeral (nicht-persistent) zu machen
  • Dem Container ein eigenes Netzwerk Interface zu geben und diesem IPs zuzuordnen
  • Das Journal (Logs) des Containers in /var/log/containers verfügbar zu machen

Auf Bedarf kann auch:

  • Dem Container DNS Zugriff gewährt werden (standardmässig ist das nämlich nicht der Fall)
  • Ein Subvolume in /persist/<container-name> für persistente Daten erstellt werden
  • Standard Ordner von Datenbanken (postgres, mysql) dorthin mounten
  • Die “data dir” des containers dorthin gemounted werden (/var/lib/<container-name>)
  • TCP/UDP Ports in der Firewall des Containers geöffnet werden
  • Sops Secrets/Templates an den Container weitergereicht werden (damit der Container die Schlüssel nicht kennt)

Options

teenix.containers

Type: attribute set of (submodule)

Default: { }

Example:

{
  config = {
    services = {
      postgresql = {
        enable = true;
      };
    };
    system = {
      stateVersion = "24.11";
    };
  };
  networking = {
    ports = {
      tcp = [
        8000
      ];
    };
  };
}

teenix.containers.<name>.backup

Automatically snapshot this containers persisted subvolume.

In addition to time-based snapshotting, a snapshot is also taken every time the container restarts

Type: boolean

Default: true

Example: false

teenix.containers.<name>.config

The containers NixOS configuration, specified as a file, attribute set or NixOS Module function.

The special arg “host-config” can be used to access the hosts configuration from within the container.

Type: module

Example:

{
  services = {
    postgresql = {
      enable = true;
    };
  };
  system = {
    stateVersion = "24.11";
  };
}

teenix.containers.<name>.extraConfig

Extra Options/Overrides to pass to the underlying container option

Type: attribute set

Default: { }

Example:

{
  timeoutStartSec = "15min";
}

teenix.containers.<name>.machineId

The containers machine-id, uniquely identifiying this container. You shouldn’t ever have to set this yourself.

Used for mounting the systemd journals back to the host.

Type: string matching the pattern ^[a-f0-9]{32} $

Default: lib.substring 0 32 (builtins.hashString "sha256" name) + "\n"

teenix.containers.<name>.mounts.data.enable

Mount (from the containers perspective) /var/lib/<containerName> into persisted storage (at /persist/container/data)

This is a really common pattern. A service named “example” will propably have a container called “example” and place its data within a folder under /var/lib.

Nonetheless, verify if this is actually the case. This option is just a really stupid shortcut.

Type: boolean

Default: false

Example: true

teenix.containers.<name>.mounts.data.name

Change the folder name under /var/lib

This makes this option at least a bit more versatile, and should be used to achieve consistency (data dir at /persist/container/data)

Type: non-empty string

Default: "container name"

Example: "myservice"

teenix.containers.<name>.mounts.data.ownerUid

Owner of the data dir. Since the desired user may not exist on the host, this option takes an id instead of a name.

Be ware, that if set this is enforced and set to this value on a regular basis.

If set to null, the folder will at first be owned by root and its left up to the service to set the correct owner.

The privateUsers option may interfere with this.

Type: null or signed integer

Default: null

Example: config.containers.myservice.config.users.users.myservice.uid

teenix.containers.<name>.mounts.extra

Additional Mounts for the container

Type: attribute set of (submodule)

Default: { }

teenix.containers.<name>.mounts.extra.<name>.hostPath

Path on the host to mount from

Type: null or non-empty string

Default: null

Example: "/mnt/netapp/Nextcloud"

teenix.containers.<name>.mounts.extra.<name>.isReadOnly

Make the mount read-only, prohibiting any modifications (from anything) from within the container

Type: boolean

Default: true

teenix.containers.<name>.mounts.extra.<name>.mode

Be ware, that if set this is enforced and set to this value on a regular basis.

If set to null, the folder will at first be owned by root and its left up to the service to set the correct owner.

The privateUsers option may interfere with this.

Type: non-empty string

Default: "0700"

Example: "0755"

teenix.containers.<name>.mounts.extra.<name>.mountPoint

Path inside the container to mount to

Type: non-empty string

Example: "/var/lib/nextcloud/data"

teenix.containers.<name>.mounts.extra.<name>.ownerUid

Be ware, that if set this is enforced and set to this value on a regular basis.

If set to null, the folder will at first be owned by root and its left up to the service to set the correct owner.

The privateUsers option may interfere with this.

Type: null or signed integer

Default: null

Example: config.users.users.nextcloud.uid

teenix.containers.<name>.mounts.mysql.enable

Mount the container’s mysql data dir into persisted storage (at /persist/container/mysql).

If a mysql database is used within the container, you’ll always want this enabled.

Type: boolean

Default: false

Example: true

teenix.containers.<name>.mounts.postgres.enable

Mount the container’s postgresql data dir into persisted storage (at /persist/container/postgres)

If a postgresql database is used within the container, you’ll always want this enabled.

Type: boolean

Default: false

Example: true

teenix.containers.<name>.mounts.sops.secrets

Names of sops-nix secrets to mount into the container.

Use host-config.sops.secrets.my-secret.path to access the path within the container

Type: list of non-empty string

Default: [ ]

Example: [ "my-secret" ]

teenix.containers.<name>.mounts.sops.templates

Names of sops-nix templates to mount into the container

Use host-config.sops.templates.my-template.path to access the path within the container

Type: list of non-empty string

Default: [ ]

Example: [ "my-template" ]

teenix.containers.<name>.networking.id

Network id this container should be placed in. If null, one is picked automatically

Type: null or non-empty string

Default: null

Example: "192.168.1"

teenix.containers.<name>.networking.ports.tcp

TCP Ports to open in the containers firewall

Type: list of 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: [ ]

Example:

[
  8080
]

teenix.containers.<name>.networking.ports.udp

UDP Ports to open in the containers firewall

Type: list of 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: [ ]

Example:

[
  25565
]

teenix.containers.<name>.networking.useResolvConf

Whether to enable Make a resolv.conf file available in the container.

This is required if the container wants to do DNS lookups. .

Type: boolean

Default: false

Example: true

teenix.containers.<name>.privateUsers

Whether to give the container its own private UIDs/GIDs space (user namespacing). This greatly enhances security.

In addition to the options provided by nixos containers, this option also takes a boolean. If true, privateUsers is set to “pick”, If set to false, privateUsers is set to “no”

Type: boolean or 32 bit unsigned integer; between 0 and 4294967295 (both inclusive) or one of “no”, “identity”, “pick”

Default: false

Example: true