-
Notifications
You must be signed in to change notification settings - Fork 416
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
961 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## OS Support | ||
|
||
This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, RockyLinux, and Alpine Linux. | ||
|
||
## Location of Flakes | ||
|
||
Currently `flakeUri` works best with a remote URI (e.g., `github:nixos/nixpkgs/nixpkgs-unstable#hello`) as local files need to be in the image. | ||
|
||
> Proposed support for lifecycle hooks in Features ([#60](https://github.com/devcontainers/spec/issues/60)) would allow for expressions files or Flakes to exist in the source tree to be automatically installed on initial container startup, but today you will have to manually add the appropriate install command to `postCreateCommand` to your `devcontainer.json` instead. | ||
## Multi-user vs. single-user installs | ||
|
||
This Dev Container Feature supports two installation models for Nix: multi-user and single user. Multi-user is the default, but each has pros and cons. | ||
|
||
| Installation Model | Pros | Cons | | ||
| --- | --- | --- | | ||
| *Multi-User* | Nix can be used with any user including root.<br /><br />Also still works if the UID or GID of any user is updated. | Only works with Nix 2.11 and up due to a Nix installer limitation.<br /><br />Container must run either: run as root (but `remoteUser` in devcontainer.json can be non-root), or includes `sudo` with the `remoteUser` being configured to use it. <br /><br />Note that automated start of the `nix-daemon` requires passwordless `sudo` if the container itself (e.g., `containerUser`) is not running as root. Manual startup using `sudo` can require a password, however (more next). | | ||
| *Single-User* | Does not require the container to run as root or `sudo` to be included in the image. | Only works with the user specified in the `userName` property or an auto-detected user. If this user's UID/GID is updated, that user will no longer be able to work with Nix. This is primarily a consideration when running on Linux where the UID/GID is sync'd to the local user. | | ||
|
||
### Manually starting the Nix daemon | ||
|
||
If you have `sudo` in your base image, but have a password set so automatic startup is not possible, you can manually start the Nix daemon by running the following command in a terminal: | ||
|
||
```bash | ||
sudo /usr/local/share/nix-entrypoint.sh | ||
``` | ||
|
||
This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"id": "nix", | ||
"version": "1.0.0", | ||
"name": "Nix Package Manager", | ||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/nix", | ||
"description": "Installs the Nix package manager and optionally a set of packages.", | ||
"options": { | ||
"version": { | ||
"type": "string", | ||
"proposals": ["latest", "2.11"], | ||
"default": "latest", | ||
"description": "Version of Nix to install." | ||
}, | ||
"multiUser": { | ||
"type": "boolean", | ||
"default": true, | ||
"description": "Perform a multi-user install (instead of single user)" | ||
}, | ||
"packages": { | ||
"type": "string", | ||
"default": "", | ||
"description": "Optional comma separated list of Nix packages to install in profile." | ||
}, | ||
"flakeUri": { | ||
"type": "string", | ||
"default": "", | ||
"description": "Optional URI to a Nix Flake to install in profile." | ||
} | ||
}, | ||
"installsAfter": [ | ||
"ghcr.io/devcontainers/features/common-utils" | ||
], | ||
"containerEnv": { | ||
"PATH": "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:${PATH}" | ||
}, | ||
"entrypoint": "/usr/local/share/nix-entrypoint.sh" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#!/bin/bash | ||
# Move to the same directory as this script | ||
set -e | ||
FEATURE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | ||
cd "${FEATURE_DIR}" | ||
|
||
# Option defaults | ||
VERSION="${VERSION:-"latest"}" | ||
MULTIUSER="${MULTIUSER:-"true"}" | ||
PACKAGES="${PACKAGES//,/ }" | ||
FLAKEURI="${FLAKEURI:-""}" | ||
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" | ||
|
||
# Nix keys for securly verifying installer download signature per https://nixos.org/download.html#nix-verify-installation | ||
NIX_GPG_KEYS="B541D55301270E0BCF15CA5D8170B4726D7198DE" | ||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 | ||
keyserver hkps://keys.openpgp.org | ||
keyserver hkp://keyserver.pgp.com" | ||
|
||
if [ "$(id -u)" -ne 0 ]; then | ||
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' | ||
exit 1 | ||
fi | ||
|
||
# Import common utils | ||
. ./utils.sh | ||
|
||
detect_user USERNAME | ||
|
||
if [ -e "/nix" ]; then | ||
echo "(!) Nix is already installed! Skipping installation." | ||
else | ||
if [ "${USERNAME}" = "root" ] && [ "${MULTIUSER}" != "true" ]; then | ||
echo "(!) A single user install is not allowed for root. Add a non-root user to your image or set multiUser to true in your feature configuration." | ||
exit 1 | ||
fi | ||
|
||
# Verify dependencies | ||
apt_get_update_if_exists | ||
check_command curl "curl ca-certificates" "curl ca-certificates" "curl ca-certificates" | ||
check_command gpg2 gnupg2 gnupg gnupg2 | ||
check_command dirmngr dirmngr dirmngr dirmngr | ||
check_command xz xz-utils xz xz | ||
check_command git git git git | ||
check_command xargs findutils findutils findutils | ||
|
||
# Determine version | ||
find_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" | ||
|
||
# Download and verify install per https://nixos.org/download.html#nix-verify-installation | ||
tmpdir="$(mktemp -d)" | ||
echo "(*) Downloading Nix installer..." | ||
set +e | ||
curl -sSLf -o "${tmpdir}/install-nix" https://releases.nixos.org/nix/nix-${VERSION}/install | ||
exit_code=$? | ||
set -e | ||
if [ "$exit_code" != "0" ]; then | ||
# Handle situation where git tags are ahead of what was is available to actually download | ||
echo "(!) Nix version ${VERSION} failed to download. Attempting to fall back one version to retry..." | ||
find_prev_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" | ||
curl -sSLf -o "${tmpdir}/install-nix" https://releases.nixos.org/nix/nix-${VERSION}/install | ||
fi | ||
curl -sSLf -o "${tmpdir}/install-nix.asc" https://releases.nixos.org/nix/nix-${VERSION}/install.asc | ||
cd "${tmpdir}" | ||
receive_gpg_keys NIX_GPG_KEYS | ||
gpg2 --verify ./install-nix.asc | ||
cd "${FEATURE_DIR}" | ||
|
||
# Do a multi or single-user setup based on feature config | ||
if [ "${MULTIUSER}" = "true" ]; then | ||
echo "(*) Performing multi-user install..." | ||
sh "${tmpdir}/install-nix" --daemon | ||
else | ||
home_dir="$(eval echo ~${USERNAME})" | ||
if [ ! -e "${home_dir}" ]; then | ||
echo "(!) Home directory ${home_dir} does not exist for ${USERNAME}. Nix install will fail." | ||
exit 1 | ||
fi | ||
echo "(*) Performing single-user install..." | ||
echo -e "\n**NOTE: Nix will only work for user ${USERNAME} on Linux if the host machine user's UID is $(id -u ${USERNAME}). You will need to chown /nix otherwise.**\n" | ||
# Install per https://nixos.org/manual/nix/stable/installation/installing-binary.html#single-user-installation | ||
mkdir -p /nix | ||
chown ${USERNAME} /nix ${tmpdir} | ||
su ${USERNAME} -c "sh \"${tmpdir}/install-nix\" --no-daemon --no-modify-profile" | ||
# nix installer does not update ~/.bashrc, and USER may or may not be defined, so update rc/profile files directly to handle that | ||
snippet=' | ||
if [ "${PATH#*$HOME/.nix-profile/bin}" = "${PATH}" ]; then if [ -z "$USER" ]; then USER=$(whoami); fi; . $HOME/.nix-profile/etc/profile.d/nix.sh; fi | ||
' | ||
update_rc_file "$home_dir/.bashrc" "${snippet}" | ||
update_rc_file "$home_dir/.zshenv" "${snippet}" | ||
update_rc_file "$home_dir/.profile" "${snippet}" | ||
fi | ||
rm -rf "${tmpdir}" "/tmp/tmp-gnupg" | ||
fi | ||
|
||
# Set nix config | ||
mkdir -p /etc/nix | ||
create_or_update_file /etc/nix/nix.conf 'sandbox = false' | ||
if [ ! -z "${FLAKEURI}" ] && [ "${FLAKEURI}" != "none" ]; then | ||
create_or_update_file /etc/nix/nix.conf 'experimental-features = nix-command flakes' | ||
fi | ||
|
||
# Create entrypoint if needed | ||
if [ ! -e "/usr/local/share/nix-entrypoint.sh" ]; then | ||
if [ "${MULTIUSER}" = "true" ]; then | ||
echo "(*) Setting up entrypoint..." | ||
cp -f nix-entrypoint.sh /usr/local/share/ | ||
else | ||
echo -e '#!/bin/bash\nexec "$@"' > /usr/local/share/nix-entrypoint.sh | ||
fi | ||
chmod +x /usr/local/share/nix-entrypoint.sh | ||
fi | ||
|
||
# Install packages, flakes, etc if specified | ||
chmod +x,o+r ${FEATURE_DIR} ${FEATURE_DIR}/post-install-steps.sh | ||
if [ "${MULTIUSER}" = "true" ]; then | ||
/usr/local/share/nix-entrypoint.sh | ||
su ${USERNAME} -c " | ||
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh | ||
${FEATURE_DIR}/post-install-steps.sh | ||
" | ||
else | ||
su ${USERNAME} -c " | ||
. \$HOME/.nix-profile/etc/profile.d/nix.sh | ||
${FEATURE_DIR}/post-install-steps.sh | ||
" | ||
fi | ||
|
||
echo "Done!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
# Attempt to start daemon | ||
set +e | ||
if ! pidof nix-daemon > /dev/null 2>&1; then | ||
start_ok=false | ||
if [ "$(id -u)" = "0" ]; then | ||
( . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh; /nix/var/nix/profiles/default/bin/nix-daemon > /tmp/nix-daemon.log 2>&1 ) & | ||
if [ "$?" = "0" ]; then | ||
start_ok=true | ||
fi | ||
elif type sudo > /dev/null 2>&1; then | ||
sudo -n sh -c '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh; /nix/var/nix/profiles/default/bin/nix-daemon > /tmp/nix-daemon.log 2>&1' & | ||
if [ "$?" = "0" ]; then | ||
start_ok=true | ||
fi | ||
fi | ||
if [ "${start_ok}" = "false" ]; then | ||
echo -e 'Failed to start nix-daemon as root. Set multiUser to false in your feature configuraiton if you would\nprefer to run the container as a non-root. You may also start the daemon manually if you have sudo\ninstalled and configured for your user by running "sudo -c nix-daemon &"' | ||
fi | ||
fi | ||
exec "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
set -e | ||
echo "(*) Executing post-installation steps..." | ||
|
||
# Install list of packages in profile if specified. | ||
if [ ! -z "${PACKAGES}" ] && [ "${PACKAGES}" != "none" ]; then | ||
echo "Installing packages \"${PACKAGES}\" in profile..." | ||
nix-env --install ${PACKAGES} | ||
fi | ||
|
||
# Install Nix flake in profile if specified | ||
if [ ! -z "${FLAKEURI}" ] && [ "${FLAKEURI}" != "none" ]; then | ||
echo "Installing flake ${FLAKEURI} in profile..." | ||
nix profile install "${FLAKEURI}" | ||
fi | ||
|
||
nix-collect-garbage --delete-old | ||
nix-store --optimise |
Oops, something went wrong.