Merge branch 'feat/rewrite-image' into 'main'

feat: rewrite image

Closes #1

See merge request TECHNOFAB/coder-templates!1
This commit is contained in:
TECHNOFAB 2024-10-07 12:33:14 +00:00
commit 01c163c081
4 changed files with 151 additions and 46 deletions

View file

@ -1,2 +1,16 @@
# Coder Templates # Coder Templates
Templates for [Coder](https://coder.com), built with Nix (Terranix).
> [!NOTE]
> !1 changed how the docker image is built.
> If `nix store gc` results in `/nix/var/nix/profiles/default` being deleted
> you might have to clear the /nix persistent volume to fix it. See the
> merge request's comments for more information.
## Templates
- Nix Kubernetes
> provisions a Coder workspace on Kubernetes, running a Nix-built image,
> which also contains Nix and supports Dotfiles management using home-manager.
> Nix-ception ;P

6
flake.lock generated
View file

@ -642,11 +642,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1713805509, "lastModified": 1728249353,
"narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", "narHash": "sha256-7NBJm1jfMeAowE1J2oljYqWVvI9X7FyyxBY4O8uB/Os=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4", "rev": "c8a17040be4a20b29589cb4043a9e0c36af1930e",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -31,7 +31,12 @@
projectRootFile = "flake.nix"; projectRootFile = "flake.nix";
programs = { programs = {
alejandra.enable = true; alejandra.enable = true;
mdformat.enable = true; mdformat = {
enable = true;
package = pkgs.mdformat.withPlugins (p: [
p.mdformat-gfm-alerts
]);
};
}; };
}; };
@ -113,8 +118,6 @@
]; ];
script = [ script = [
"nix build .#nix-coder-image --system $SYSTEM" "nix build .#nix-coder-image --system $SYSTEM"
];
after_script = [
"install -D result dist/nix-coder-image_\${SYSTEM}.tar.gz" "install -D result dist/nix-coder-image_\${SYSTEM}.tar.gz"
]; ];
artifacts.paths = ["dist/"]; artifacts.paths = ["dist/"];

142
image.nix
View file

@ -2,56 +2,144 @@
lib, lib,
pkgs, pkgs,
... ...
}: }: let
pkgs.dockerTools.buildLayeredImage { baseSystem = let
name = "nix-coder"; packages = with pkgs; [
tag = "latest";
contents = pkgs.buildEnv {
name = "image-root";
paths = with pkgs; [
bash
bashInteractive
nix nix
bashInteractive
coreutils-full coreutils-full
procps
gnugrep gnugrep
openssh openssh
gitMinimal gitMinimal
curl curl
ncurses ncurses
dockerTools.usrBinEnv
cacert.out
(writeShellScriptBin "reload-dotfiles" '' (writeShellScriptBin "reload-dotfiles" ''
${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} --option tarball-ttl 0 ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} --option tarball-ttl 0
'') '')
(writeTextDir "etc/nix/nix.conf" ''
experimental-features = nix-command flakes
'')
(writeTextDir "etc/os-release" ''
ID=nixos
'')
(writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash")
(writeTextDir "etc/shadow" "coder:!:::::::")
(writeTextDir "etc/group" "coder:x:1000:")
(writeTextDir "etc/gshadow" "coder:x::")
]; ];
pathsToLink = ["/bin" "/etc" "/usr"]; rootEnv = pkgs.buildPackages.buildEnv {
name = "root-profile-env";
paths = packages;
}; };
maxLayers = 5;
nixConf = {
sandbox = "false";
experimental-features = "nix-command flakes";
min-free = toString (100 * 1024 * 1024);
max-free = toString (1024 * 1024 * 1024);
};
nixConfContents =
(lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: let
vStr =
if builtins.isList v
then lib.concatStringsSep " " v
else v;
in "${n} = ${vStr}")
nixConf))
+ "\n";
manifest = pkgs.buildPackages.runCommand "manifest.nix" {} ''
cat > $out <<EOF
[
${lib.concatStringsSep "\n" (builtins.map (drv: let
outputs = drv.outputsToInstall or ["out"];
in ''
{
${lib.concatStringsSep "\n" (builtins.map (output: ''
${output} = { outPath = "${lib.getOutput output drv}"; };
'')
outputs)}
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
name = "${drv.name}";
outPath = "${drv}";
system = "${drv.system}";
type = "derivation";
meta = { };
}
'')
packages)}
]
EOF
'';
profile = pkgs.buildPackages.runCommand "user-environment" {} ''
mkdir $out
cp -a ${rootEnv}/* $out/
ln -s ${manifest} $out/manifest.nix
'';
dirsToCreate = ["/etc/ssl/certs" "/etc/nix" "/usr" "/nix/var/nix/gcroots" "/bin" "/usr/bin" "/tmp" "/var/tmp" "/home/coder/.nix-defexpr" "/nix/var/nix/profiles/per-user/coder"];
in
pkgs.runCommand "base-system" {
allowSubstitutes = false;
preferLocalBuild = true;
} ''
env
set -x
mkdir -p ${lib.concatMapStringsSep " " (x: "$out${x}") dirsToCreate}
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
ln -s /nix/var/nix/profiles/share $out/usr/
echo "${nixConfContents}" > $out/etc/nix/nix.conf
echo "ID=nixos" > $out/etc/os-release
echo "coder:x:1000:1000::/home/coder:/bin/bash" > $out/etc/passwd
echo "coder:!:::::::" > $out/etc/shadow
echo "coder:x:1000:" > $out/etc/group
echo "coder:x::" > $out/etc/gshadow
echo "coder:100000:65536" > $out/etc/subuid
echo "coder:100000:65536" > $out/etc/subgid
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
# prevents the profiles from being cleaned up by the GC
ln -s /nix/var/nix/profiles $out/nix/var/nix/gcroots/profiles
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/bash
'';
in
pkgs.dockerTools.buildLayeredImageWithNixDb {
name = "nix-coder";
tag = "latest";
contents = [baseSystem];
maxLayers = 10;
uid = 1000; uid = 1000;
gid = 1000; gid = 1000;
fakeRootCommands = '' fakeRootCommands = ''
mkdir -p ./home/coder ./tmp ./nix/var/nix
chown -R 1000:1000 ./ chown -R 1000:1000 ./
chmod 1777 tmp
chmod 1777 var/tmp
''; '';
config = { config = {
Cmd = ["/bin/bash"]; Cmd = ["/bin/bash"];
User = "1000:1000"; User = "1000:1000";
Env = [ Env = [
"SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
"HOME=/home/coder"
"USER=coder" "USER=coder"
"HOME=/home/coder"
"TMPDIR=/tmp"
"XDG_RUNTIME_DIR=/tmp"
"PATH=${lib.concatStringsSep ":" [
"/home/coder/.nix-profile/bin"
# this makes all the packages defined at the top available
# in the workspace
"/nix/var/nix/profiles/default/bin"
"/nix/var/nix/profiles/default/sbin"
]}"
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_PATH=/nix/var/nix/profiles/per-user/coder/channels:/home/coder/.nix-defexpr/channels"
]; ];
}; };
} }