I am trying to run a GitLab CI pipeline with a custom runner and nix flake.
Here is the simplified .gitlab-ci.yml
of my project that reproduces my problem:
stages:
- test
default:
image: alpine:latest
before_script: &nix_setup
- export TZ=Etc/UTC
- eval $(ssh-agent -s)
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "${SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- mkdir -p ~/.config/nix
- echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.conf
- echo $PATH
- nix develop .#ci -c echo $PATH
- nix develop .#ci -c init-pg --help
- nix develop .#ci
- echo $PATH
- init-pg --help
test:
stage: test
before_script:
- *nix_setup
script:
- echo "Hello World!"
nix develop
is supposed to provide me with a custom init-pg
program to initialize a PostgreSQL database. However, as opposed to my local development environment, running nix develop
in the GitLab CI pipeline does not seem to do much because I get the error init-pg: not found
:
Running with gitlab-runner 15.5.1 (v15.5.1)
on nix_mymachine_************ ********
Preparing the "docker" executor 00:03
Using Docker executor with image alpine:latest ...
Pulling docker image alpine:latest ...
Using docker image sha256:49176f190c7e9cdb51ac85ab6c6d5e4512352218190cd69b08e6fd803ffbf3da for alpine:latest with digest alpine@sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4 ...
Preparing environment 00:04
Running on runner-********-project-********-concurrent-0 via mymachine...
Getting source from Git repository 00:05
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/acme/postgresql-cluster/.git/
Created fresh repository.
Checking out ******** as mybranch...
Skipping Git submodules setup
Executing "step_script" stage of the job script
Using docker image sha256:49176f190c7e9cdb51ac85ab6c6d5e4512352218190cd69b08e6fd803ffbf3da for alpine:latest with digest alpine@sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4 ...
$ /nix/store/k7xz7ksajcr4z80ywbhsd0h4738kn7c5-setup-container
installing 'nix-2.11.0'
installing 'nss-cacert-3.83'
installing 'git-2.38.1'
installing 'openssh-9.1p1'
unpacking channels...
$ export TZ=Etc/UTC
$ eval $(ssh-agent -s)
Agent pid 42
$ echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
Identity added: (stdin) (gitlab.com CI for ACME)
$ mkdir -p ~/.ssh
$ chmod 700 ~/.ssh
$ echo "${SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
$ chmod 644 ~/.ssh/known_hosts
$ mkdir -p ~/.config/nix
$ echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.conf
$ echo $PATH
/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin
$ nix develop .#ci -c echo $PATH
/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin
$ nix develop .#ci -c init-pg --help
Initialize a PostgreSQL cluster for a given environment.
Usage:
/nix/store/bbcflvw77idq1v060gqp77rw616v1ybw-init-pg-unstable-2020-03-16/bin/init-pg --help Display this help message.
/nix/store/bbcflvw77idq1v060gqp77rw616v1ybw-init-pg-unstable-2020-03-16/bin/init-pg <options> Options.
Options:
--env ENV Environment. Required.
--port PORT Port. Required.
$ nix develop .#ci
$ echo $PATH
/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin
$ init-pg --help
/bin/sh: eval: line 162: init-pg: not found
Cleaning up project directory and file based variables
ERROR: Job failed: exit code 127
I do not understand what happens. As we can see in the logs, it seems that after nix develop .#ci
ran, the next command does not run in the interactive shell. But it can successfully run if I use nix develop .#ci -c init-pg --help
.
I have many commands to run so I would like to avoid to prefix all of them with nix develop .#ci -c <COMMAND>
.
Any idea of what is happening here?
For information, the custom GitLab runner I use is very close to the one documented. It is deployed on a NixOS
machine with nixops
. Here is the module:
{ lib, pkgs, ... }:
let
secretsDir = "/var/keys";
registrationConfigBasename = "gitlab-runner-registration-config";
registrationConfigFile = "${secretsDir}/${registrationConfigBasename}";
in
{
deployment.keys = {
"${registrationConfigBasename}" = {
text = let
serverUrl = "https://gitlab.com";
registrationToken = builtins.readFile ../secrets/gitlab-registration-token;
in ''
CI_SERVER_URL=${serverUrl}
REGISTRATION_TOKEN=${registrationToken}'';
destDir = "${secretsDir}";
user = "root";
group = "root";
permissions = "0640";
};
};
boot.kernel.sysctl."net.ipv4.ip_forward" = true;
virtualisation.docker.enable = true;
services.gitlab-runner = {
enable = true;
services = {
nix = {
inherit registrationConfigFile;
dockerImage = "alpine";
dockerVolumes = [
"/nix/store:/nix/store:ro"
"/nix/var/nix/db:/nix/var/nix/db:ro"
"/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro"
];
dockerDisableCache = true;
preBuildScript = pkgs.writeScript "setup-container" ''
mkdir -p -m 0755 /nix/var/log/nix/drvs
mkdir -p -m 0755 /nix/var/nix/gcroots
mkdir -p -m 0755 /nix/var/nix/profiles
mkdir -p -m 0755 /nix/var/nix/temproots
mkdir -p -m 0755 /nix/var/nix/userpool
mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
mkdir -p -m 1777 /nix/var/nix/profiles/per-user
mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
mkdir -p -m 0700 "$HOME/.nix-defexpr"
. ${pkgs.nix}/etc/profile.d/nix.sh
${pkgs.nix}/bin/nix-env -i ${lib.concatStringsSep " " (with pkgs; [ nix cacert git openssh ])}
${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
${pkgs.nix}/bin/nix-channel --update nixpkgs
'';
environmentVariables = {
ENV = "/etc/profile";
USER = "root";
NIX_REMOTE = "daemon";
PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin";
NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
};
};
};
};
}