main
1{
2 lib,
3 pkgs,
4 nix2container,
5 name,
6 # NOTE: Skopeo didn't support multi arch image push
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 ''
131 mkdir -p $out/bin
132 ln -s ${pkgs.podman}/bin/podman $out/bin/docker
133
134 mkdir -p $man/share/man/man1
135 for f in ${pkgs.podman.man}/share/man/man1/*; do
136 basename=$(basename $f | sed s/podman/docker/g)
137 ln -s $f $man/share/man/man1/$basename
138 done
139 ''
140 + lib.optionalString (pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform) ''
141 export HOME=$(mktemp -d) # work around `docker <cmd>`
142 installShellCompletion --cmd docker \
143 --bash <($out/bin/docker completion bash) \
144 --zsh <($out/bin/docker completion zsh) \
145 --fish <($out/bin/docker completion fish)
146 ''
147 );
148in
149 nix2container.buildImage {
150 inherit name tag;
151
152 initializeNixDatabase = true;
153 maxLayers = 100;
154
155 copyToRoot = [
156 (pkgs.buildEnv {
157 name = "root";
158 paths = with pkgs; [
159 bash
160 coreutils
161 dockerTools.caCertificates
162 dockerTools.usrBinEnv
163 fakeNss
164 mkNixConf
165 mkTmp
166 nix
167 nodejs_24
168
169 aria2
170 cacert
171 curl
172 dnsutils
173 openssh
174 wget
175
176 gitMinimal
177 git-lfs
178
179 gnutar
180 gzip
181 p7zip
182 unzip
183 xz
184 zip
185 zstd
186
187 autoconf
188 automake
189 gcc
190 gnumake
191 m4
192 patchelf
193
194 binutils
195 file
196 findutils
197 gawk
198 gnugrep
199 gnupg
200 gnused
201 jq
202 parallel
203 python3
204 rsync
205 sqlite
206 sudo
207 tree
208 yq
209
210 fuse-overlayfs
211 mkPodmanConfig
212 podman
213 podmanDockerCompat
214 shadow
215 ];
216 })
217 mkSubugid
218 ];
219 perms = [
220 {
221 path = mkTmp;
222 regex = ".*";
223 mode = "1777";
224 }
225 {
226 path = mkPodmanConfig;
227 regex = "home/podman";
228 mode = "0777";
229 }
230 {
231 path = pkgs.shadow;
232 regex = "bin/new[ug]idmap";
233 mode = "4555";
234 }
235 ];
236 config = {
237 Entrypoint = ["/bin/bash"];
238 Env = [
239 "USER=root"
240 "HOME=/"
241 "PATH=/bin"
242 "NIX_PAGER=cat"
243 "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
244 "DOCKER_HOST=unix:///run/user/1000/podman/podman.sock"
245 "CONTAINERS_STORAGE=/var/lib/containers/storage"
246 "_CONTAINERS_USERNS_CONFIGURED="
247 "BUILDAH_ISOLATION=chroot"
248 ];
249 Labels = {
250 "org.opencontainers.image.source" = "https://codeberg.org/HPCesia/nix-act-image";
251 "org.opencontainers.image.description" = "A Nix based container for Forgejo Actions";
252 "org.opencontainers.image.licenses" = lib.licenses.mit.spdxId;
253 };
254 };
255 }