tangled
alpha
login
or
join now
pyrox.dev
/
nixpkgs
0
fork
atom
lol
0
fork
atom
overview
issues
pulls
pipelines
nixos/coder: init module
Soner Sayakci
3 years ago
56ecab70
0566d27d
+298
-82
7 changed files
expand all
collapse all
unified
split
nixos
modules
module-list.nix
services
web-apps
coder.nix
tests
all-tests.nix
coder.nix
pkgs
applications
misc
coder
default.nix
development
tools
coder
default.nix
top-level
all-packages.nix
+1
nixos/modules/module-list.nix
···
1120
1120
./services/web-apps/baget.nix
1121
1121
./services/web-apps/bookstack.nix
1122
1122
./services/web-apps/calibre-web.nix
1123
1123
+
./services/web-apps/coder.nix
1123
1124
./services/web-apps/changedetection-io.nix
1124
1125
./services/web-apps/cloudlog.nix
1125
1126
./services/web-apps/code-server.nix
+217
nixos/modules/services/web-apps/coder.nix
···
1
1
+
{ config, lib, options, pkgs, ... }:
2
2
+
3
3
+
with lib;
4
4
+
5
5
+
let
6
6
+
cfg = config.services.coder;
7
7
+
name = "coder";
8
8
+
in {
9
9
+
options = {
10
10
+
services.coder = {
11
11
+
enable = mkEnableOption (lib.mdDoc "Coder service");
12
12
+
13
13
+
user = mkOption {
14
14
+
type = types.str;
15
15
+
default = "coder";
16
16
+
description = lib.mdDoc ''
17
17
+
User under which the coder service runs.
18
18
+
19
19
+
::: {.note}
20
20
+
If left as the default value this user will automatically be created
21
21
+
on system activation, otherwise it needs to be configured manually.
22
22
+
:::
23
23
+
'';
24
24
+
};
25
25
+
26
26
+
group = mkOption {
27
27
+
type = types.str;
28
28
+
default = "coder";
29
29
+
description = lib.mdDoc ''
30
30
+
Group under which the coder service runs.
31
31
+
32
32
+
::: {.note}
33
33
+
If left as the default value this group will automatically be created
34
34
+
on system activation, otherwise it needs to be configured manually.
35
35
+
:::
36
36
+
'';
37
37
+
};
38
38
+
39
39
+
package = mkOption {
40
40
+
type = types.package;
41
41
+
default = pkgs.coder;
42
42
+
description = lib.mdDoc ''
43
43
+
Package to use for the service.
44
44
+
'';
45
45
+
defaultText = literalExpression "pkgs.coder";
46
46
+
};
47
47
+
48
48
+
homeDir = mkOption {
49
49
+
type = types.str;
50
50
+
description = lib.mdDoc ''
51
51
+
Home directory for coder user.
52
52
+
'';
53
53
+
default = "/var/lib/coder";
54
54
+
};
55
55
+
56
56
+
listenAddress = mkOption {
57
57
+
type = types.str;
58
58
+
description = lib.mdDoc ''
59
59
+
Listen address.
60
60
+
'';
61
61
+
default = "127.0.0.1:3000";
62
62
+
};
63
63
+
64
64
+
accessUrl = mkOption {
65
65
+
type = types.nullOr types.str;
66
66
+
description = lib.mdDoc ''
67
67
+
Access URL should be a external IP address or domain with DNS records pointing to Coder.
68
68
+
'';
69
69
+
default = null;
70
70
+
example = "https://coder.example.com";
71
71
+
};
72
72
+
73
73
+
wildcardAccessUrl = mkOption {
74
74
+
type = types.nullOr types.str;
75
75
+
description = lib.mdDoc ''
76
76
+
If you are providing TLS certificates directly to the Coder server, you must use a single certificate for the root and wildcard domains.
77
77
+
'';
78
78
+
default = null;
79
79
+
example = "*.coder.example.com";
80
80
+
};
81
81
+
82
82
+
database = {
83
83
+
createLocally = mkOption {
84
84
+
type = types.bool;
85
85
+
default = true;
86
86
+
description = lib.mdDoc ''
87
87
+
Create the database and database user locally.
88
88
+
'';
89
89
+
};
90
90
+
91
91
+
host = mkOption {
92
92
+
type = types.str;
93
93
+
default = "/run/postgresql";
94
94
+
description = lib.mdDoc ''
95
95
+
Hostname hosting the database.
96
96
+
'';
97
97
+
};
98
98
+
99
99
+
database = mkOption {
100
100
+
type = types.str;
101
101
+
default = "coder";
102
102
+
description = lib.mdDoc ''
103
103
+
Name of database.
104
104
+
'';
105
105
+
};
106
106
+
107
107
+
username = mkOption {
108
108
+
type = types.str;
109
109
+
default = "coder";
110
110
+
description = lib.mdDoc ''
111
111
+
Username for accessing the database.
112
112
+
'';
113
113
+
};
114
114
+
115
115
+
password = mkOption {
116
116
+
type = types.nullOr types.str;
117
117
+
default = null;
118
118
+
description = lib.mdDoc ''
119
119
+
Password for accessing the database.
120
120
+
'';
121
121
+
};
122
122
+
123
123
+
sslmode = mkOption {
124
124
+
type = types.nullOr types.str;
125
125
+
default = "disable";
126
126
+
description = lib.mdDoc ''
127
127
+
Password for accessing the database.
128
128
+
'';
129
129
+
};
130
130
+
};
131
131
+
132
132
+
tlsCert = mkOption {
133
133
+
type = types.nullOr types.path;
134
134
+
description = lib.mdDoc ''
135
135
+
The path to the TLS certificate.
136
136
+
'';
137
137
+
default = null;
138
138
+
};
139
139
+
140
140
+
tlsKey = mkOption {
141
141
+
type = types.nullOr types.path;
142
142
+
description = lib.mdDoc ''
143
143
+
The path to the TLS key.
144
144
+
'';
145
145
+
default = null;
146
146
+
};
147
147
+
};
148
148
+
};
149
149
+
150
150
+
config = mkIf cfg.enable {
151
151
+
assertions = [
152
152
+
{ assertion = cfg.database.createLocally -> cfg.database.username == name;
153
153
+
message = "services.coder.database.username must be set to ${user} if services.coder.database.createLocally is set true";
154
154
+
}
155
155
+
];
156
156
+
157
157
+
systemd.services.coder = {
158
158
+
description = "Coder - Self-hosted developer workspaces on your infra";
159
159
+
after = [ "network.target" ];
160
160
+
wantedBy = [ "multi-user.target" ];
161
161
+
162
162
+
environment = {
163
163
+
CODER_ACCESS_URL = cfg.accessUrl;
164
164
+
CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl;
165
165
+
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}"}";
166
166
+
CODER_ADDRESS = cfg.listenAddress;
167
167
+
CODER_TLS_ENABLE = optionalString (cfg.tlsCert != null) "1";
168
168
+
CODER_TLS_CERT_FILE = cfg.tlsCert;
169
169
+
CODER_TLS_KEY_FILE = cfg.tlsKey;
170
170
+
};
171
171
+
172
172
+
serviceConfig = {
173
173
+
ProtectSystem = "full";
174
174
+
PrivateTmp = "yes";
175
175
+
PrivateDevices = "yes";
176
176
+
SecureBits = "keep-caps";
177
177
+
AmbientCapabilities = "CAP_IPC_LOCK CAP_NET_BIND_SERVICE";
178
178
+
CacheDirectory = "coder";
179
179
+
CapabilityBoundingSet = "CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE";
180
180
+
KillSignal = "SIGINT";
181
181
+
KillMode = "mixed";
182
182
+
NoNewPrivileges = "yes";
183
183
+
Restart = "on-failure";
184
184
+
ExecStart = "${cfg.package}/bin/coder server";
185
185
+
User = cfg.user;
186
186
+
Group = cfg.group;
187
187
+
};
188
188
+
};
189
189
+
190
190
+
services.postgresql = lib.mkIf cfg.database.createLocally {
191
191
+
enable = true;
192
192
+
ensureDatabases = [
193
193
+
cfg.database.database
194
194
+
];
195
195
+
ensureUsers = [{
196
196
+
name = cfg.database.username;
197
197
+
ensurePermissions = {
198
198
+
"DATABASE \"${cfg.database.database}\"" = "ALL PRIVILEGES";
199
199
+
};
200
200
+
}
201
201
+
];
202
202
+
};
203
203
+
204
204
+
users.groups = optionalAttrs (cfg.group == name) {
205
205
+
"${cfg.group}" = {};
206
206
+
};
207
207
+
users.users = optionalAttrs (cfg.user == name) {
208
208
+
${name} = {
209
209
+
description = "Coder service user";
210
210
+
group = cfg.group;
211
211
+
home = cfg.homeDir;
212
212
+
createHome = true;
213
213
+
isSystemUser = true;
214
214
+
};
215
215
+
};
216
216
+
};
217
217
+
}
+1
nixos/tests/all-tests.nix
···
135
135
cloudlog = handleTest ./cloudlog.nix {};
136
136
cntr = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cntr.nix {};
137
137
cockroachdb = handleTestOn ["x86_64-linux"] ./cockroachdb.nix {};
138
138
+
coder = handleTest ./coder.nix {};
138
139
collectd = handleTest ./collectd.nix {};
139
140
connman = handleTest ./connman.nix {};
140
141
consul = handleTest ./consul.nix {};
+24
nixos/tests/coder.nix
···
1
1
+
import ./make-test-python.nix ({ pkgs, ... }: {
2
2
+
name = "coder";
3
3
+
meta = with pkgs.lib.maintainers; {
4
4
+
maintainers = [ shyim ghuntley ];
5
5
+
};
6
6
+
7
7
+
nodes.machine =
8
8
+
{ pkgs, ... }:
9
9
+
{
10
10
+
services.coder = {
11
11
+
enable = true;
12
12
+
accessUrl = "http://localhost:3000";
13
13
+
};
14
14
+
};
15
15
+
16
16
+
testScript = ''
17
17
+
machine.start()
18
18
+
machine.wait_for_unit("postgresql.service")
19
19
+
machine.wait_for_unit("coder.service")
20
20
+
machine.wait_for_open_port(3000)
21
21
+
22
22
+
machine.succeed("curl --fail http://localhost:3000")
23
23
+
'';
24
24
+
})
-76
pkgs/applications/misc/coder/default.nix
···
1
1
-
{ lib, pkgs, fetchFromGitHub, installShellFiles, buildGoModule, fetchYarnDeps }:
2
2
-
3
3
-
let
4
4
-
pname = "coder";
5
5
-
version = "0.10.2";
6
6
-
7
7
-
src = fetchFromGitHub {
8
8
-
owner = "coder";
9
9
-
repo = "coder";
10
10
-
rev = "v${version}";
11
11
-
sha256 = "sha256-h5bN75agNocRAjShbufRCJr45huYJOzCBd4OcGpF4C4=";
12
12
-
};
13
13
-
14
14
-
offlineCache = fetchYarnDeps {
15
15
-
yarnLock = src + "/site/yarn.lock";
16
16
-
sha256 = "sha256-uDNPRQTpsgxyC5ks+2Qq/wiKjkbjWwSO+cJc5X6qmAA=";
17
17
-
};
18
18
-
19
19
-
yarn16 = pkgs.yarn.override { nodejs = pkgs.nodejs-16_x; };
20
20
-
nodePackages16 = pkgs.nodePackages.override { nodejs = pkgs.nodejs-16_x; };
21
21
-
in
22
22
-
buildGoModule rec {
23
23
-
inherit pname version src;
24
24
-
25
25
-
subPackages = [ "cmd/coder" ];
26
26
-
27
27
-
vendorSha256 = "sha256-+3Zy0zArCXkvD4ogfKdu9W9gJXveAhwFXKG1VRDvOkI=";
28
28
-
29
29
-
# Flags as provided by the build automation of the project:
30
30
-
# https://github.com/coder/coder/blob/075e891f287b27cdb481a48e129f20a1e6a7de12/scripts/build_go.sh#L89
31
31
-
ldflags = [
32
32
-
"-s"
33
33
-
"-w"
34
34
-
"-X github.com/coder/coder/buildinfo.tag=${version}"
35
35
-
];
36
36
-
37
37
-
preBuild = ''
38
38
-
export HOME=$(mktemp -d)
39
39
-
mkdir -p $HOME
40
40
-
41
41
-
cd site
42
42
-
yarn config --offline set yarn-offline-mirror ${offlineCache}
43
43
-
fixup_yarn_lock yarn.lock
44
44
-
45
45
-
# node-gyp tries to download always the headers and fails: https://github.com/NixOS/nixpkgs/issues/195404
46
46
-
yarn remove --offline jest-canvas-mock canvas
47
47
-
48
48
-
NODE_ENV=production node node_modules/.bin/vite build
49
49
-
cd ..
50
50
-
'';
51
51
-
52
52
-
tags = [ "embed" ];
53
53
-
54
54
-
nativeBuildInputs = with pkgs; [
55
55
-
fixup_yarn_lock
56
56
-
nodejs-16_x
57
57
-
yarn16
58
58
-
nodePackages16.node-pre-gyp
59
59
-
python3
60
60
-
pkg-config
61
61
-
installShellFiles
62
62
-
];
63
63
-
64
64
-
postInstall = ''
65
65
-
installShellCompletion --cmd coder \
66
66
-
--bash <($out/bin/coder completion bash) \
67
67
-
--zsh <($out/bin/coder completion zsh)
68
68
-
'';
69
69
-
70
70
-
meta = with lib; {
71
71
-
description = "Software development on any infrastructure";
72
72
-
license = licenses.agpl3Only;
73
73
-
homepage = "https://coder.com/";
74
74
-
maintainers = with maintainers; [ shyim ];
75
75
-
};
76
76
-
}
+55
-4
pkgs/development/tools/coder/default.nix
···
1
1
-
{ buildGoModule
1
1
+
{ lib
2
2
, fetchFromGitHub
3
3
, installShellFiles
4
4
-
, lib
4
4
+
, makeWrapper
5
5
+
, buildGoModule
6
6
+
, fetchYarnDeps
7
7
+
, fixup_yarn_lock
8
8
+
, pkg-config
9
9
+
, nodejs
10
10
+
, yarn
11
11
+
, nodePackages
12
12
+
, python3
13
13
+
, terraform
5
14
}:
15
15
+
6
16
buildGoModule rec {
7
17
pname = "coder";
8
18
version = "0.16.0";
···
14
24
hash = "sha256-3rGpyJzGkZYUEvKKDzj2I5sqrUImmmX7cXWM9UClPLY=";
15
25
};
16
26
27
27
+
offlineCache = fetchYarnDeps {
28
28
+
yarnLock = src + "/site/yarn.lock";
29
29
+
hash = "sha256-4GbM7GNZ3wHIZJIJuHw1v/SwjUNc1vi8IHRGaGwPGZQ=";
30
30
+
};
31
31
+
32
32
+
subPackages = [ "cmd/..." ];
33
33
+
34
34
+
vendorHash = "sha256-bb9jBno7elO6qKGjacpX3rxgrpJpGpTxMQtdBYjBzMk=";
35
35
+
17
36
# integration tests require network access
18
37
doCheck = false;
19
38
20
20
-
vendorHash = "sha256-bb9jBno7elO6qKGjacpX3rxgrpJpGpTxMQtdBYjBzMk=";
39
39
+
ldflags = [
40
40
+
"-s"
41
41
+
"-w"
42
42
+
"-X github.com/coder/coder/buildinfo.tag=${version}"
43
43
+
];
44
44
+
45
45
+
preBuild = ''
46
46
+
export HOME=$TEMPDIR
47
47
+
48
48
+
pushd site
49
49
+
yarn config --offline set yarn-offline-mirror ${offlineCache}
50
50
+
fixup_yarn_lock yarn.lock
51
51
+
52
52
+
# node-gyp tries to download always the headers and fails: https://github.com/NixOS/nixpkgs/issues/195404
53
53
+
yarn remove --offline jest-canvas-mock canvas
54
54
+
55
55
+
NODE_ENV=production node node_modules/.bin/vite build
56
56
+
57
57
+
popd
58
58
+
'';
59
59
+
60
60
+
tags = [ "embed" ];
21
61
22
22
-
nativeBuildInputs = [ installShellFiles ];
62
62
+
nativeBuildInputs = [
63
63
+
fixup_yarn_lock
64
64
+
installShellFiles
65
65
+
makeWrapper
66
66
+
nodePackages.node-pre-gyp
67
67
+
nodejs
68
68
+
pkg-config
69
69
+
python3
70
70
+
yarn
71
71
+
];
23
72
24
73
postInstall = ''
25
74
installShellCompletion --cmd coder \
26
75
--bash <($out/bin/coder completion bash) \
27
76
--fish <($out/bin/coder completion fish) \
28
77
--zsh <($out/bin/coder completion zsh)
78
78
+
79
79
+
wrapProgram $out/bin/coder --prefix PATH : ${lib.makeBinPath [ terraform ]}
29
80
'';
30
81
31
82
meta = with lib; {
-2
pkgs/top-level/all-packages.nix
···
4174
4174
electron = electron_11;
4175
4175
};
4176
4176
4177
4177
-
coder = callPackage ../applications/misc/coder {};
4178
4178
-
4179
4177
contrast = callPackage ../applications/accessibility/contrast { };
4180
4178
4181
4179
cplex = callPackage ../applications/science/math/cplex (config.cplex or {});