Static Reflection
Static Reflection
发布于 2025-11-17 / 10 阅读
0

在 NixOS 上的 docker-compose.yml

在使用 NixOS 作为操作系统的服务器上,手动 docker-compose up 是一件不太优雅的事

而手写 oci-container 又是一件麻烦事

这时,我们就可以使用 compose2nix 将 docker-compose.yml 转化成 Nix 格式的配置文件,并由 NixOS 来管理

安装 / 直接运行

  1. configuration.nix

    environment.systemPackages = with pkgs; [
        compose2nix
    ];
  2. nix-shell

    nix-shell -p compose2nix
  3. nix run

    nix run github:aksiksi/compose2nix -- -h

使用

在终端中,输入 compose2nix --help 可以查看帮助菜单

原帮助菜单
─❯ compose2nix --help
Usage of compose2nix:
  -auto_format
        if true, Nix output will be formatted using "nixfmt" (must be present in $PATH).
  -auto_start
        auto-start setting for generated service(s). this applies to all services, not just containers. (default true)
  -build
        if set, generated container build systemd services will be enabled.
  -check_bind_mounts
        if set, check that bind mount paths exist. this is useful if running the generated Nix code on the same machine.
  -check_systemd_mounts
        if set, volume paths will be checked against systemd mount paths on the current machine and marked as container dependencies.
  -create_root_target
        if set, a root systemd target will be created, which when stopped tears down all resources. (default true)
  -default_stop_timeout duration
        default stop timeout for generated container services. (default 1m30s)
  -enable_option
        generate a NixOS module option. this allows you to enable or disable the generated module from within your NixOS config. by default, the option will be named "options.[project_name]", but you can add a prefix using the "option_prefix" flag.
  -env_files string
        one or more comma-separated paths to .env file(s).
  -env_files_only
        only use env file(s) in the NixOS container definitions.
  -generate_unused_resources
        if set, unused resources (e.g., networks) will be generated even if no containers use them.
  -ignore_missing_env_files
        if set, missing env files will be ignored.
  -include_env_files
        include env files in the NixOS container definition.
  -inputs string
        one or more comma-separated path(s) to Compose file(s). (default "docker-compose.yml")
  -option_prefix string
        Prefix for the option. If empty, the project name will be used as the option name. (e.g. custom.containers)
  -output string
        path to output Nix file. (default "docker-compose.nix")
  -project string
        project name used as a prefix for generated resources. this overrides any top-level "name" set in the Compose file(s).
  -remove_volumes
        if set, volumes will be removed on systemd service stop.
  -root_path string
        absolute path to use as the root for any relative paths in the Compose file (e.g., volumes, env files). defaults to the current working directory.
  -runtime string
        one of: ["podman", "docker"]. (default "podman")
  -service_include string
        regex pattern for services to include.
  -sops_file string
        path to encrypted secrets YAML file (e.g., secrets.yaml). when set, secrets defined in compose services using "compose2nix.sops.secret=secret1,secret2" labels will be added as environmentFiles.
  -use_compose_log_driver
        if set, always use the Docker Compose log driver.
  -use_upheld_by
        if set, upheldBy will be used for service dependencies (NixOS 24.05+).
  -version
        display version and exit
  -warnings_as_errors
        if set, treat generator warnings as hard errors.
  -write_nix_setup
        if true, Nix setup code is written to output (runtime, DNS, autoprune, etc.) (default true)

翻译后的帮助菜单 (AI翻译)
─❯ compose2nix -h
compose2nix的使用方法:
  -auto_format
        如果为 true,Nix 输出将使用 "nixfmt" 进行格式化(必须在 $PATH 中)
  -auto_start
        生成服务的自动启动设置。这适用于所有服务,不仅仅是容器(默认 true)
  -build
        如果设置,将启用生成的容器构建 systemd 服务
  -check_bind_mounts
        如果设置,检查绑定挂载路径是否存在。如果在同一台机器上运行生成的 Nix 代码,这会很有用
  -check_systemd_mounts
        如果设置,卷路径将根据当前机器上的 systemd 挂载路径进行检查,并标记为容器依赖项
  -create_root_target
        如果设置,将创建一个根 systemd target,停止该 target 将关闭所有资源(默认 true)
  -default_stop_timeout duration
        生成的容器服务的默认停止超时时间(默认 1m30s)
  -enable_option
        生成一个 NixOS 模块选项。这允许您从 NixOS 配置内部启用或禁用生成的模块。默认情况下,该选项将被命名为 "options.[project_name]",但您可以使用 "option_prefix" 标志添加前缀
  -env_files string
        一个或多个以逗号分隔的 .env 文件路径
  -env_files_only
        仅在 NixOS 容器定义中使用环境文件
  -generate_unused_resources
        如果设置,即使没有容器使用,未使用的资源(例如,网络)也会被生成
  -ignore_missing_env_files
        如果设置,将忽略缺失的环境文件
  -include_env_files
        在 NixOS 容器定义中包含环境文件
  -inputs string
        一个或多个以逗号分隔的 Compose 文件路径(默认 "docker-compose.yml")
  -option_prefix string
        选项的前缀。如果为空,项目名称将用作选项名称(例如 custom.containers)
  -output string
        输出 Nix 文件的路径(默认 "docker-compose.nix")
  -project string
        用作生成资源前缀的项目名称。这将覆盖 Compose 文件中设置的任何顶级 "name"
  -remove_volumes
        如果设置,将在 systemd 服务停止时移除卷
  -root_path string
        用作 Compose 文件中任何相对路径(例如,卷、环境文件)根目录的绝对路径。默认为当前工作目录
  -runtime string
        运行环境,可选: ["podman", "docker"](默认 "podman")
  -service_include string
        用于包含服务的正则表达式模式。
  -sops_file string
        加密的 secrets YAML 文件路径(例如 secrets.yaml)。设置后,使用 "compose2nix.sops.secret=secret1,secret2" 标签在 compose 服务中定义的 secrets 将作为 environmentFiles 添加
  -use_compose_log_driver
        如果设置,始终使用 Docker Compose 日志驱动
  -use_upheld_by
        如果设置,将使用 upheldBy 来处理服务依赖关系(NixOS 24.05+)
  -version
        显示版本信息并退出
  -warnings_as_errors
        如果设置,将生成器警告视为硬错误
  -write_nix_setup
        如果为 true,Nix 设置代码将被写入输出(运行时、DNS、自动清理等)(默认 true)

基本用法

以下是一份 redis 的 docker-compose.yml

docker-compose.yml
services:
  redis:
    image: redis:latest
    container_name: redis
    restart: always
    ports:
      - '6379:6379'
    volumes:
      - redis_data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - redis_logs:/logs
    command: redis-server /usr/local/etc/redis/redis.conf

volumes:
  redis_data:
    name: redis_data
  redis_logs:
    name: redis_logs

我们可以使用 compose2nix -project=redis -output default.nix -runtime docker 来转换成 Nix 格式的配置文件(redis为project name,可填任意)

转化出的文件如下:

default.nix
# Auto-generated by compose2nix.

{ pkgs, lib, config, ... }:

{
  # Runtime
  virtualisation.podman = {
    enable = true;
    autoPrune.enable = true;
    dockerCompat = true;
  };

  # Enable container name DNS for all Podman networks.
  networking.firewall.interfaces = let
    matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
  in {
    "${matchAll}".allowedUDPPorts = [ 53 ];
  };

  virtualisation.oci-containers.backend = "podman";

  # Containers
  virtualisation.oci-containers.containers."redis" = {
    image = "redis:latest";
    volumes = [
      "/home/reflexia/Workdir/redis.conf:/usr/local/etc/redis/redis.conf:rw"
      "redis_data:/data:rw"
      "redis_logs:/logs:rw"
    ];
    ports = [
      "6379:6379/tcp"
    ];
    cmd = [ "redis-server" "/usr/local/etc/redis/redis.conf" ];
    log-driver = "journald";
    extraOptions = [
      "--network-alias=redis"
      "--network=bridge"
    ];
  };
  systemd.services."podman-redis" = {
    serviceConfig = {
      Restart = lib.mkOverride 90 "always";
    };
    after = [
      "podman-volume-redis_data.service"
      "podman-volume-redis_logs.service"
    ];
    requires = [
      "podman-volume-redis_data.service"
      "podman-volume-redis_logs.service"
    ];
    partOf = [
      "podman-compose-redis-root.target"
    ];
    wantedBy = [
      "podman-compose-redis-root.target"
    ];
  };

  # Volumes
  systemd.services."podman-volume-redis_data" = {
    path = [ pkgs.podman ];
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
    };
    script = ''
      podman volume inspect redis_data || podman volume create redis_data
    '';
    partOf = [ "podman-compose-redis-root.target" ];
    wantedBy = [ "podman-compose-redis-root.target" ];
  };
  systemd.services."podman-volume-redis_logs" = {
    path = [ pkgs.podman ];
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
    };
    script = ''
      podman volume inspect redis_logs || podman volume create redis_logs
    '';
    partOf = [ "podman-compose-redis-root.target" ];
    wantedBy = [ "podman-compose-redis-root.target" ];
  };

  # Root service
  # When started, this will automatically create all resources and start
  # the containers. When stopped, this will teardown all resources.
  systemd.targets."podman-compose-redis-root" = {
    unitConfig = {
      Description = "Root target generated by compose2nix.";
    };
    wantedBy = [ "multi-user.target" ];
  };
}

再到 configuration.nix 去 import 它后,使用 sudo nixos-rebuild switch 它就会自动完成 docker-compose up 干的事了

管理服务

开启服务(docker-compose up)

sudo systemctl start docker-compose-redis-root.target

重启服务

sudo systemctl restart docker-redis-myservice.service

停止服务(docker-compose down)

sudo systemctl stop docker-compose-redis-root.target

默认情况下,此操作只会删除网络。

相关链接 / 引用