Loading nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,7 @@ ./services/web-apps/baget.nix ./services/web-apps/bookstack.nix ./services/web-apps/calibre-web.nix ./services/web-apps/coder.nix ./services/web-apps/changedetection-io.nix ./services/web-apps/cloudlog.nix ./services/web-apps/code-server.nix Loading nixos/modules/services/web-apps/coder.nix 0 → 100644 +217 −0 Original line number Diff line number Diff line { config, lib, options, pkgs, ... }: with lib; let cfg = config.services.coder; name = "coder"; in { options = { services.coder = { enable = mkEnableOption (lib.mdDoc "Coder service"); user = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' User under which the coder service runs. ::: {.note} If left as the default value this user will automatically be created on system activation, otherwise it needs to be configured manually. ::: ''; }; group = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Group under which the coder service runs. ::: {.note} If left as the default value this group will automatically be created on system activation, otherwise it needs to be configured manually. ::: ''; }; package = mkOption { type = types.package; default = pkgs.coder; description = lib.mdDoc '' Package to use for the service. ''; defaultText = literalExpression "pkgs.coder"; }; homeDir = mkOption { type = types.str; description = lib.mdDoc '' Home directory for coder user. ''; default = "/var/lib/coder"; }; listenAddress = mkOption { type = types.str; description = lib.mdDoc '' Listen address. ''; default = "127.0.0.1:3000"; }; accessUrl = mkOption { type = types.nullOr types.str; description = lib.mdDoc '' Access URL should be a external IP address or domain with DNS records pointing to Coder. ''; default = null; example = "https://coder.example.com"; }; wildcardAccessUrl = mkOption { type = types.nullOr types.str; description = lib.mdDoc '' If you are providing TLS certificates directly to the Coder server, you must use a single certificate for the root and wildcard domains. ''; default = null; example = "*.coder.example.com"; }; database = { createLocally = mkOption { type = types.bool; default = true; description = lib.mdDoc '' Create the database and database user locally. ''; }; host = mkOption { type = types.str; default = "/run/postgresql"; description = lib.mdDoc '' Hostname hosting the database. ''; }; database = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Name of database. ''; }; username = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Username for accessing the database. ''; }; password = mkOption { type = types.nullOr types.str; default = null; description = lib.mdDoc '' Password for accessing the database. ''; }; sslmode = mkOption { type = types.nullOr types.str; default = "disable"; description = lib.mdDoc '' Password for accessing the database. ''; }; }; tlsCert = mkOption { type = types.nullOr types.path; description = lib.mdDoc '' The path to the TLS certificate. ''; default = null; }; tlsKey = mkOption { type = types.nullOr types.path; description = lib.mdDoc '' The path to the TLS key. ''; default = null; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = cfg.database.createLocally -> cfg.database.username == name; message = "services.coder.database.username must be set to ${user} if services.coder.database.createLocally is set true"; } ]; systemd.services.coder = { description = "Coder - Self-hosted developer workspaces on your infra"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment = { CODER_ACCESS_URL = cfg.accessUrl; CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl; CODER_PG_CONNECTION_URL = "user=${cfg.database.username} ${optionalString (cfg.database.password != null) "password=${cfg.database.password}"} database=${cfg.database.database} host=${cfg.database.host} ${optionalString (cfg.database.sslmode != null) "sslmode=${cfg.database.sslmode}"}"; CODER_ADDRESS = cfg.listenAddress; CODER_TLS_ENABLE = optionalString (cfg.tlsCert != null) "1"; CODER_TLS_CERT_FILE = cfg.tlsCert; CODER_TLS_KEY_FILE = cfg.tlsKey; }; serviceConfig = { ProtectSystem = "full"; PrivateTmp = "yes"; PrivateDevices = "yes"; SecureBits = "keep-caps"; AmbientCapabilities = "CAP_IPC_LOCK CAP_NET_BIND_SERVICE"; CacheDirectory = "coder"; CapabilityBoundingSet = "CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE"; KillSignal = "SIGINT"; KillMode = "mixed"; NoNewPrivileges = "yes"; Restart = "on-failure"; ExecStart = "${cfg.package}/bin/coder server"; User = cfg.user; Group = cfg.group; }; }; services.postgresql = lib.mkIf cfg.database.createLocally { enable = true; ensureDatabases = [ cfg.database.database ]; ensureUsers = [{ name = cfg.database.username; ensurePermissions = { "DATABASE \"${cfg.database.database}\"" = "ALL PRIVILEGES"; }; } ]; }; users.groups = optionalAttrs (cfg.group == name) { "${cfg.group}" = {}; }; users.users = optionalAttrs (cfg.user == name) { ${name} = { description = "Coder service user"; group = cfg.group; home = cfg.homeDir; createHome = true; isSystemUser = true; }; }; }; } nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ in { cloudlog = handleTest ./cloudlog.nix {}; cntr = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cntr.nix {}; cockroachdb = handleTestOn ["x86_64-linux"] ./cockroachdb.nix {}; coder = handleTest ./coder.nix {}; collectd = handleTest ./collectd.nix {}; connman = handleTest ./connman.nix {}; consul = handleTest ./consul.nix {}; Loading nixos/tests/coder.nix 0 → 100644 +24 −0 Original line number Diff line number Diff line import ./make-test-python.nix ({ pkgs, ... }: { name = "coder"; meta = with pkgs.lib.maintainers; { maintainers = [ shyim ghuntley ]; }; nodes.machine = { pkgs, ... }: { services.coder = { enable = true; accessUrl = "http://localhost:3000"; }; }; testScript = '' machine.start() machine.wait_for_unit("postgresql.service") machine.wait_for_unit("coder.service") machine.wait_for_open_port(3000) machine.succeed("curl --fail http://localhost:3000") ''; }) pkgs/applications/misc/coder/default.nixdeleted 100644 → 0 +0 −76 Original line number Diff line number Diff line { lib, pkgs, fetchFromGitHub, installShellFiles, buildGoModule, fetchYarnDeps }: let pname = "coder"; version = "0.10.2"; src = fetchFromGitHub { owner = "coder"; repo = "coder"; rev = "v${version}"; sha256 = "sha256-h5bN75agNocRAjShbufRCJr45huYJOzCBd4OcGpF4C4="; }; offlineCache = fetchYarnDeps { yarnLock = src + "/site/yarn.lock"; sha256 = "sha256-uDNPRQTpsgxyC5ks+2Qq/wiKjkbjWwSO+cJc5X6qmAA="; }; yarn16 = pkgs.yarn.override { nodejs = pkgs.nodejs-16_x; }; nodePackages16 = pkgs.nodePackages.override { nodejs = pkgs.nodejs-16_x; }; in buildGoModule rec { inherit pname version src; subPackages = [ "cmd/coder" ]; vendorSha256 = "sha256-+3Zy0zArCXkvD4ogfKdu9W9gJXveAhwFXKG1VRDvOkI="; # Flags as provided by the build automation of the project: # https://github.com/coder/coder/blob/075e891f287b27cdb481a48e129f20a1e6a7de12/scripts/build_go.sh#L89 ldflags = [ "-s" "-w" "-X github.com/coder/coder/buildinfo.tag=${version}" ]; preBuild = '' export HOME=$(mktemp -d) mkdir -p $HOME cd site yarn config --offline set yarn-offline-mirror ${offlineCache} fixup_yarn_lock yarn.lock # node-gyp tries to download always the headers and fails: https://github.com/NixOS/nixpkgs/issues/195404 yarn remove --offline jest-canvas-mock canvas NODE_ENV=production node node_modules/.bin/vite build cd .. ''; tags = [ "embed" ]; nativeBuildInputs = with pkgs; [ fixup_yarn_lock nodejs-16_x yarn16 nodePackages16.node-pre-gyp python3 pkg-config installShellFiles ]; postInstall = '' installShellCompletion --cmd coder \ --bash <($out/bin/coder completion bash) \ --zsh <($out/bin/coder completion zsh) ''; meta = with lib; { description = "Software development on any infrastructure"; license = licenses.agpl3Only; homepage = "https://coder.com/"; maintainers = with maintainers; [ shyim ]; }; } Loading
nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,7 @@ ./services/web-apps/baget.nix ./services/web-apps/bookstack.nix ./services/web-apps/calibre-web.nix ./services/web-apps/coder.nix ./services/web-apps/changedetection-io.nix ./services/web-apps/cloudlog.nix ./services/web-apps/code-server.nix Loading
nixos/modules/services/web-apps/coder.nix 0 → 100644 +217 −0 Original line number Diff line number Diff line { config, lib, options, pkgs, ... }: with lib; let cfg = config.services.coder; name = "coder"; in { options = { services.coder = { enable = mkEnableOption (lib.mdDoc "Coder service"); user = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' User under which the coder service runs. ::: {.note} If left as the default value this user will automatically be created on system activation, otherwise it needs to be configured manually. ::: ''; }; group = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Group under which the coder service runs. ::: {.note} If left as the default value this group will automatically be created on system activation, otherwise it needs to be configured manually. ::: ''; }; package = mkOption { type = types.package; default = pkgs.coder; description = lib.mdDoc '' Package to use for the service. ''; defaultText = literalExpression "pkgs.coder"; }; homeDir = mkOption { type = types.str; description = lib.mdDoc '' Home directory for coder user. ''; default = "/var/lib/coder"; }; listenAddress = mkOption { type = types.str; description = lib.mdDoc '' Listen address. ''; default = "127.0.0.1:3000"; }; accessUrl = mkOption { type = types.nullOr types.str; description = lib.mdDoc '' Access URL should be a external IP address or domain with DNS records pointing to Coder. ''; default = null; example = "https://coder.example.com"; }; wildcardAccessUrl = mkOption { type = types.nullOr types.str; description = lib.mdDoc '' If you are providing TLS certificates directly to the Coder server, you must use a single certificate for the root and wildcard domains. ''; default = null; example = "*.coder.example.com"; }; database = { createLocally = mkOption { type = types.bool; default = true; description = lib.mdDoc '' Create the database and database user locally. ''; }; host = mkOption { type = types.str; default = "/run/postgresql"; description = lib.mdDoc '' Hostname hosting the database. ''; }; database = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Name of database. ''; }; username = mkOption { type = types.str; default = "coder"; description = lib.mdDoc '' Username for accessing the database. ''; }; password = mkOption { type = types.nullOr types.str; default = null; description = lib.mdDoc '' Password for accessing the database. ''; }; sslmode = mkOption { type = types.nullOr types.str; default = "disable"; description = lib.mdDoc '' Password for accessing the database. ''; }; }; tlsCert = mkOption { type = types.nullOr types.path; description = lib.mdDoc '' The path to the TLS certificate. ''; default = null; }; tlsKey = mkOption { type = types.nullOr types.path; description = lib.mdDoc '' The path to the TLS key. ''; default = null; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = cfg.database.createLocally -> cfg.database.username == name; message = "services.coder.database.username must be set to ${user} if services.coder.database.createLocally is set true"; } ]; systemd.services.coder = { description = "Coder - Self-hosted developer workspaces on your infra"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment = { CODER_ACCESS_URL = cfg.accessUrl; CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl; CODER_PG_CONNECTION_URL = "user=${cfg.database.username} ${optionalString (cfg.database.password != null) "password=${cfg.database.password}"} database=${cfg.database.database} host=${cfg.database.host} ${optionalString (cfg.database.sslmode != null) "sslmode=${cfg.database.sslmode}"}"; CODER_ADDRESS = cfg.listenAddress; CODER_TLS_ENABLE = optionalString (cfg.tlsCert != null) "1"; CODER_TLS_CERT_FILE = cfg.tlsCert; CODER_TLS_KEY_FILE = cfg.tlsKey; }; serviceConfig = { ProtectSystem = "full"; PrivateTmp = "yes"; PrivateDevices = "yes"; SecureBits = "keep-caps"; AmbientCapabilities = "CAP_IPC_LOCK CAP_NET_BIND_SERVICE"; CacheDirectory = "coder"; CapabilityBoundingSet = "CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE"; KillSignal = "SIGINT"; KillMode = "mixed"; NoNewPrivileges = "yes"; Restart = "on-failure"; ExecStart = "${cfg.package}/bin/coder server"; User = cfg.user; Group = cfg.group; }; }; services.postgresql = lib.mkIf cfg.database.createLocally { enable = true; ensureDatabases = [ cfg.database.database ]; ensureUsers = [{ name = cfg.database.username; ensurePermissions = { "DATABASE \"${cfg.database.database}\"" = "ALL PRIVILEGES"; }; } ]; }; users.groups = optionalAttrs (cfg.group == name) { "${cfg.group}" = {}; }; users.users = optionalAttrs (cfg.user == name) { ${name} = { description = "Coder service user"; group = cfg.group; home = cfg.homeDir; createHome = true; isSystemUser = true; }; }; }; }
nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ in { cloudlog = handleTest ./cloudlog.nix {}; cntr = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cntr.nix {}; cockroachdb = handleTestOn ["x86_64-linux"] ./cockroachdb.nix {}; coder = handleTest ./coder.nix {}; collectd = handleTest ./collectd.nix {}; connman = handleTest ./connman.nix {}; consul = handleTest ./consul.nix {}; Loading
nixos/tests/coder.nix 0 → 100644 +24 −0 Original line number Diff line number Diff line import ./make-test-python.nix ({ pkgs, ... }: { name = "coder"; meta = with pkgs.lib.maintainers; { maintainers = [ shyim ghuntley ]; }; nodes.machine = { pkgs, ... }: { services.coder = { enable = true; accessUrl = "http://localhost:3000"; }; }; testScript = '' machine.start() machine.wait_for_unit("postgresql.service") machine.wait_for_unit("coder.service") machine.wait_for_open_port(3000) machine.succeed("curl --fail http://localhost:3000") ''; })
pkgs/applications/misc/coder/default.nixdeleted 100644 → 0 +0 −76 Original line number Diff line number Diff line { lib, pkgs, fetchFromGitHub, installShellFiles, buildGoModule, fetchYarnDeps }: let pname = "coder"; version = "0.10.2"; src = fetchFromGitHub { owner = "coder"; repo = "coder"; rev = "v${version}"; sha256 = "sha256-h5bN75agNocRAjShbufRCJr45huYJOzCBd4OcGpF4C4="; }; offlineCache = fetchYarnDeps { yarnLock = src + "/site/yarn.lock"; sha256 = "sha256-uDNPRQTpsgxyC5ks+2Qq/wiKjkbjWwSO+cJc5X6qmAA="; }; yarn16 = pkgs.yarn.override { nodejs = pkgs.nodejs-16_x; }; nodePackages16 = pkgs.nodePackages.override { nodejs = pkgs.nodejs-16_x; }; in buildGoModule rec { inherit pname version src; subPackages = [ "cmd/coder" ]; vendorSha256 = "sha256-+3Zy0zArCXkvD4ogfKdu9W9gJXveAhwFXKG1VRDvOkI="; # Flags as provided by the build automation of the project: # https://github.com/coder/coder/blob/075e891f287b27cdb481a48e129f20a1e6a7de12/scripts/build_go.sh#L89 ldflags = [ "-s" "-w" "-X github.com/coder/coder/buildinfo.tag=${version}" ]; preBuild = '' export HOME=$(mktemp -d) mkdir -p $HOME cd site yarn config --offline set yarn-offline-mirror ${offlineCache} fixup_yarn_lock yarn.lock # node-gyp tries to download always the headers and fails: https://github.com/NixOS/nixpkgs/issues/195404 yarn remove --offline jest-canvas-mock canvas NODE_ENV=production node node_modules/.bin/vite build cd .. ''; tags = [ "embed" ]; nativeBuildInputs = with pkgs; [ fixup_yarn_lock nodejs-16_x yarn16 nodePackages16.node-pre-gyp python3 pkg-config installShellFiles ]; postInstall = '' installShellCompletion --cmd coder \ --bash <($out/bin/coder completion bash) \ --zsh <($out/bin/coder completion zsh) ''; meta = with lib; { description = "Software development on any infrastructure"; license = licenses.agpl3Only; homepage = "https://coder.com/"; maintainers = with maintainers; [ shyim ]; }; }