diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/web-apps/coder.nix')
-rw-r--r-- | nixpkgs/nixos/modules/services/web-apps/coder.nix | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/web-apps/coder.nix b/nixpkgs/nixos/modules/services/web-apps/coder.nix new file mode 100644 index 000000000000..469a29bc3aa8 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/coder.nix @@ -0,0 +1,217 @@ +{ 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; + }; + }; + }; +} |