made an issue https://github.com/NixOS/nix/issues/2663
How to reproduce
docker run --privileged --rm --name some-docker docker:stable-dind
cat > /tmp/test.nix << 'EOL'
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
stdenv.mkDerivation {
pname = "test";
version = "0.0.1";
DOCKER_HOST = builtins.getEnv "DOCKER_HOST";
buildInputs = [docker curl nettools];
phases = "installPhase";
installPhase = ''
(ls -al /etc || true)
(cat /etc/nsswitch.conf || true)
(cat /etc/hosts || true)
(cat /etc/resolv.conf || true)
# without --store returns
#
# Kernel IP routing table
# Destination Gateway Genmask Flags MSS Window irtt Iface
# 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
# 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
#
# with --store returns empty
#
# Kernel IP routing table
# Destination Gateway Genmask Flags MSS Window irtt Iface
netstat --numeric --route
# without --store - returns without error
# with --store - error "Could not resolve host: docker"
curl -v http://docker:2375/v1.39/version
# without --store - returns without error, prints server info
# with --store - error "error during connect: Get http://docker:2375/v1.39/version: dial tcp: lookup docker on [::1]:53: read udp [::1]:39506->[::1]:53: read: connection refused"
docker version
# create dummy package if everything above did work fine
mkdir -p $out
'';
}
EOL
--store
argumentdocker run -it --rm --link some-docker:docker -v /tmp/test.nix:/tmp/test.nix nixos/nix@sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357 sh -c 'export DOCKER_HOST=tcp://docker:2375/ && (echo "hosts: files dns" > /etc/nsswitch.conf) && nix-build /tmp/test.nix'
output - https://pastebin.com/DZmXrATR
--store
argumentdocker run -it --rm --link some-docker:docker --privileged -v /tmp/test.nix:/tmp/test.nix nixos/nix@sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357 sh -c 'export DOCKER_HOST=tcp://docker:2375/ && (echo "hosts: files dns" > /etc/nsswitch.conf) && nix-build --store /tmp/store /tmp/test.nix'
output https://pastebin.com/Z4DxtLQr
how to make it work?
Update:
seems like it's because /etc/nsswitch.conf is not mounted when using --store
Unfortunately, nix is not allowing me to create it myself (touch /etc/nsswitch.conf
throws permission denied)
Update:
I found that I can use extra-sandbox-paths
to mount files from container to nix-build sandbox
mounting /etc/nsswitch.conf solved curl: (6) Could not resolve host: docker
but I cant fix * Immediate connect fail for 172.17.0.2: Network is unreachable
error, I've tried mounting all network related files from /etc, but it's not working
docker run --privileged --rm --name some-docker docker:stable-dind
docker run -it --rm --link some-docker:docker --privileged -v /tmp/test.nix:/tmp/test.nix nixos/nix@sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357 sh
nix-env -i curl nettools
# works
curl -v http://172.17.0.2:2375/v1.39/version
# works
curl -v http://docker:2375/v1.39/version
# lo and eth
ifconfig -a
# not empty
netstat -rn
export DOCKER_HOST=tcp://docker:2375/ && (echo "hosts: files dns" > /etc/nsswitch.conf)
cat > /etc/nix/nix.conf << 'EOL'
sandbox = false
extra-sandbox-paths = /etc/nsswitch.conf=/etc/nsswitch.conf /etc/resolv.conf=/etc/resolv.conf /etc/hosts=/etc/hosts /etc/protocols=/etc/protocols /etc/udhcpd.conf=/etc/udhcpd.conf /etc/modules=/etc/modules
EOL
cat > /tmp/test.nix << 'EOL'
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
stdenv.mkDerivation {
pname = "test";
version = "0.0.1";
DOCKER_HOST = builtins.getEnv "DOCKER_HOST";
buildInputs = [docker curl nettools];
phases = "installPhase";
installPhase = ''
# only lo
ifconfig -a
# empty
netstat --numeric --route
# fails
curl -v http://172.17.0.2:2375/v1.39/version
curl -v http://docker:2375/v1.39/version
docker version
mkdir -p $out
'';
}
EOL
nix-build --store /tmp/store /tmp/test.nix
UPDATE
Current state of research
https://gitlab.com/gitlab-org/gitlab-ce/issues/31312#note_138576414
If your installPhase
runs curl
, you're doing it wrong. Derivations in Nix are supposed to be pure: To have their output depend only on their stated inputs, and nothing else. A derivation that connects to the network is impure by nature: Its results will depend on what is present behind the given network resource at the time when it's invoked. Thus, Nix's sandboxing intentionally (and in accordance with its documentation) disallows network access by its builders.
Consider the following, which is still impure, but uses builtins.fetchurl
instead, and so is not blocked from operation:
{ pkgs ? import <nixpkgs> {} }:
with pkgs; let
# WARNING: This is impure; usually, downloads should include an explicit hash
versionFile = builtins.fetchurl http://172.17.0.2:2375/v1.39/version
in stdenv.mkDerivation {
pname = "test";
version = "0.0.1";
DOCKER_HOST = builtins.getEnv "DOCKER_HOST";
buildInputs = [docker curl nettools];
phases = "installPhase";
installPhase = ''
cat ${escapeShellArg versionFile}
docker version
mkdir -p "$out"
'';
}
It's strongly recommended that you use pkgs.dockerTools to build Docker-compatible images using only pure Nix code, rather than trying to run Docker inside a Nix derivation.