main
1{
2 lib,
3 pkgs,
4 nix2container,
5 name,
6 # Skopeo cannot assemble a multi-arch index, so a tag names one architecture.
7 tag ? "nixos-${lib.version}-${pkgs.stdenv.system}",
8}: let
9 fakeNss = pkgs.dockerTools.fakeNss.override {
10 extraPasswdLines = [
11 "podman:x:1000:1000:Podman user:/home/podman:/bin/bash"
12 "nixbld1:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
13 "nixbld2:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
14 "nixbld3:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
15 "nixbld4:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
16 "nixbld5:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
17 "nixbld6:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
18 "nixbld7:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
19 "nixbld8:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
20 "nixbld9:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
21 "nixbld10:!:999:999:Nix build user 1:/var/empty:/sbin/nologin"
22 ];
23 extraGroupLines = [
24 "podman:x:1000:podman"
25 "nixbld:x:999:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10"
26 ];
27 };
28
29 mkNixConf = pkgs.runCommand "nix-act-image-etc" {} ''
30 mkdir -p $out/etc/nix
31 echo "experimental-features = nix-command flakes" > $out/etc/nix/nix.conf
32 '';
33
34 mkTmp = pkgs.runCommand "nix-act-image-tmp" {} ''
35 mkdir -p $out/tmp
36 mkdir -p $out/var/tmp
37 '';
38
39 mkPodmanConfig = pkgs.runCommand "podman-config" {} ''
40 mkdir -p $out/etc/containers
41 mkdir -p $out/home/podman
42 mkdir -p $out/var/lib/containers
43 mkdir -p $out/var/lib/shared/overlay-images
44 mkdir -p $out/var/lib/shared/overlay-layers
45 mkdir -p $out/var/lib/shared/vfs-images
46 mkdir -p $out/var/lib/shared/vfs-layers
47 mkdir -p $out/run
48
49 touch $out/var/lib/shared/overlay-images/images.lock
50 touch $out/var/lib/shared/overlay-layers/layers.lock
51 touch $out/var/lib/shared/vfs-images/images.lock
52 touch $out/var/lib/shared/vfs-layers/layers.lock
53
54 cat > $out/etc/containers/containers.conf << 'EOF'
55 [containers]
56 netns="host"
57 userns="host"
58 ipcns="host"
59 utsns="host"
60 cgroupns="host"
61 cgroups="disabled"
62 log_driver = "k8s-file"
63 [engine]
64 cgroup_manager = "cgroupfs"
65 events_logger="file"
66 runtime="crun"
67 EOF
68
69 cat > $out/etc/containers/containers.conf.rootless << 'EOF'
70 [containers]
71 volumes = [
72 "/proc:/proc",
73 ]
74 default_sysctls = []
75 EOF
76
77 cat > $out/etc/containers/storage.conf << 'EOF'
78 [storage]
79 driver = "overlay"
80 runroot = "/run/containers/storage"
81 graphroot = "/var/lib/containers/storage"
82 [storage.options]
83 mount_program = "${pkgs.fuse-overlayfs}/bin/fuse-overlayfs"
84 mountopt = "nodev,fsync=0"
85 additionalimagestores = [
86 "/var/lib/shared",
87 ]
88 [storage.options.overlay]
89 ignore_chown_errors = "true"
90 EOF
91
92 cat > $out/etc/containers/mounts.conf << 'EOF'
93 /run/secrets/etc-pki-entitlement:/run/secrets/etc-pki-entitlement
94 /run/secrets/rhsm:/run/secrets/rhsm
95 EOF
96
97 cat > $out/etc/containers/policy.json << 'EOF'
98 {"default":[{"type":"insecureAcceptAnything"}]}
99 EOF
100 '';
101
102 mkSubugid = pkgs.runCommand "subugid" {} ''
103 mkdir -p $out/etc
104 cat > $out/etc/subuid << 'EOF'
105 root:1:999
106 root:1001:64535
107 podman:1:999
108 podman:1001:64535
109 EOF
110 cat > $out/etc/subgid << 'EOF'
111 root:1:999
112 root:1001:64535
113 podman:1:999
114 podman:1001:64535
115 EOF
116 '';
117
118 podmanDockerCompat =
119 pkgs.runCommand "${pkgs.podman.pname}-docker-compat-${pkgs.podman.version}"
120 {
121 nativeBuildInputs = [pkgs.installShellFiles];
122 outputs = [
123 "out"
124 "man"
125 ];
126 inherit (pkgs.podman) meta;
127 preferLocalBuild = true;
128 }
129 ''
130 mkdir -p $out/bin
131 ln -s ${pkgs.podman}/bin/podman $out/bin/docker
132
133 mkdir -p $man/share/man/man1
134 for f in ${pkgs.podman.man}/share/man/man1/*; do
135 basename=$(basename $f | sed s/podman/docker/g)
136 ln -s $f $man/share/man/man1/$basename
137 done
138
139 export HOME=$(mktemp -d) # work around `docker <cmd>`
140 installShellCompletion --cmd docker \
141 --bash <($out/bin/docker completion bash) \
142 --zsh <($out/bin/docker completion zsh) \
143 --fish <($out/bin/docker completion fish)
144 '';
145in
146 nix2container.buildImage {
147 inherit name tag;
148
149 initializeNixDatabase = true;
150 maxLayers = 100;
151
152 copyToRoot = [
153 (pkgs.buildEnv {
154 name = "root";
155 paths = with pkgs; [
156 bash
157 coreutils
158 dockerTools.caCertificates
159 dockerTools.usrBinEnv
160 fakeNss
161 mkTmp
162 nix
163 nodejs_24
164
165 aria2
166 cacert
167 curl
168 dnsutils
169 openssh
170 wget
171
172 gitMinimal
173 git-lfs
174
175 gnutar
176 gzip
177 p7zip
178 unzip
179 xz
180 zip
181 zstd
182
183 autoconf
184 automake
185 gcc
186 gnumake
187 m4
188 patchelf
189
190 binutils
191 file
192 findutils
193 gawk
194 gnugrep
195 gnupg
196 gnused
197 jq
198 parallel
199 python3
200 rsync
201 sqlite
202 sudo
203 tree
204 yq
205
206 fuse-overlayfs
207 mkPodmanConfig
208 podman
209 podmanDockerCompat
210 shadow
211 ];
212 })
213 mkNixConf
214 mkSubugid
215 ];
216 perms = [
217 {
218 path = mkTmp;
219 regex = ".*";
220 mode = "1777";
221 }
222 {
223 path = mkPodmanConfig;
224 regex = "home/podman";
225 mode = "0777";
226 }
227 {
228 path = pkgs.shadow;
229 regex = "bin/new[ug]idmap";
230 mode = "4555";
231 }
232 ];
233 config = {
234 Entrypoint = ["/bin/bash"];
235 Env = [
236 "USER=root"
237 "HOME=/"
238 "PATH=/nix/profile/bin:/nix/var/nix/profiles/default/bin:/bin"
239 "NIX_PAGER=cat"
240 "NIX_PATH=nixpkgs=${pkgs.path}"
241 "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
242 "DOCKER_HOST=unix:///run/user/1000/podman/podman.sock"
243 "CONTAINERS_STORAGE=/var/lib/containers/storage"
244 "_CONTAINERS_USERNS_CONFIGURED="
245 "BUILDAH_ISOLATION=chroot"
246 ];
247 Labels = {
248 "org.opencontainers.image.source" = "https://git.trin.one/GOI/nix-act-image";
249 "org.opencontainers.image.description" = "A Nix based container for Forgejo Actions";
250 "org.opencontainers.image.licenses" = lib.licenses.mit.spdxId;
251 };
252 };
253 }