NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.91k stars 1.53k forks source link

nix-daemon and per-user proxy settings #1472

Open ivan-m opened 7 years ago

ivan-m commented 7 years ago

I've just installed nix to use on macOS. I have a proxy set up with appropriate *_proxy environment variables in my user environment, but of course nix-daemon isn't run as my user.

I could try and add the proxy variables to the generated org.nixos.nix-daemon.plist, but would prefer not to because if I take my laptop home and thus don't need to use the corporate proxy then I have to stop the daemon, edit the .plist file to remove those settings then re-start the daemon.

As such, is there any way to have the daemon use my user's proxy settings (or lack thereof)?

mickours commented 7 years ago

Seems to be related to this issue: https://github.com/NixOS/nixpkgs/issues/27535#issuecomment-317719143

I don't know if it is the same on macOS, but it seems that you have to set the environment variable in the daemon startup environment, like with Docker: https://docs.docker.com/engine/admin/systemd/#httphttps-proxy

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

nixos-discourse commented 3 years ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/how-to-use-nix-behind-corporate-proxy-on-mac/12990/2

Eason0210 commented 3 years ago

With latest Nix 2.4 , is there any way to set proxy via nix-darwin instead of editing org.nixos.nix-daemon.plist?

I am using multi-user installation Nix on Mac 12.0

contrun commented 2 years ago

I think for now the easiest way to change proxy is roaming laptop: network proxy configuration · Issue #27535 · NixOS/nixpkgs.

zhengpd commented 1 year ago

The nix docs doesn't have straightforward instructions about how to setup daemon proxy on macos. I'm sharing my solution here in case it could help someone else.

  1. create a template file: cp /Library/LaunchDaemons/org.nixos.nix-daemon.plist ~/.config/nix/org.nixos.nix-daemon.plist.template
  2. add proxy envs to the template plist EnvironmentVariables like:
    <key>EnvironmentVariables</key>
    <dict>
      ...
      <key>HTTP_PROXY</key>
      <string>PROXY_HOLDER</string>
      <key>HTTPS_PROXY</key>
      <string>PROXY_HOLDER</string>
    </dict>
  1. create a nix-daemon-reload script
#!/usr/bin/env zsh

tpl="$HOME/.config/nix/org.nixos.nix-daemon.plist.template"
plist="/Library/LaunchDaemons/org.nixos.nix-daemon.plist"

cat $tpl | sed -e "s#PROXY_HOLDER#$all_proxy#" | sudo tee $plist > /dev/null

sudo launchctl unload $plist
sudo launchctl load $plist
  1. chmod +x nix-daemon-reload and put it into directory in PATH. Run it to set the daemon proxy to $all_proxy shell env var.
ryan4yin commented 1 year ago

@zhengpd I made a python script based on your solution to avoid copy & edit plist file manually:

"""
  Set proxy for nix-daemon to speed up downloads
  You can safely ignore this file if you don't need a proxy.

  https://github.com/NixOS/nix/issues/1472#issuecomment-1532955973
"""
import os
import plistlib
import shlex
import subprocess
from pathlib import Path

NIX_DAEMON_PLIST = Path("/Library/LaunchDaemons/org.nixos.nix-daemon.plist")
NIX_DAEMON_NAME = "org.nixos.nix-daemon"
# http proxy provided by clash or other proxy tools
HTTP_PROXY = "http://127.0.0.1:7890"       

pl = plistlib.loads(NIX_DAEMON_PLIST.read_bytes())

# set http/https proxy
# NOTE: curl only accept the lowercase of `http_proxy`!
# NOTE: https://curl.se/libcurl/c/libcurl-env.html
pl["EnvironmentVariables"]["http_proxy"] = HTTP_PROXY
pl["EnvironmentVariables"]["https_proxy"] = HTTP_PROXY

# remove http proxy
# pl["EnvironmentVariables"].pop("http_proxy", None)
# pl["EnvironmentVariables"].pop("https_proxy", None)

os.chmod(NIX_DAEMON_PLIST, 0o644)
NIX_DAEMON_PLIST.write_bytes(plistlib.dumps(pl))
os.chmod(NIX_DAEMON_PLIST, 0o444)

# reload the plist
for cmd in (
    f"launchctl unload {NIX_DAEMON_PLIST}",
    f"launchctl load {NIX_DAEMON_PLIST}",
):
    print(cmd)
    subprocess.run(shlex.split(cmd), capture_output=False)

Save the script at scripts/darwin_set_proxy.py, and a Makefile to run this script before nix build:

darwin-set-proxy:
    sudo python3 scripts/darwin_set_proxy.py

darwin: darwin-set-proxy
    nix build .#darwinConfigurations.harmonica.system
    ./result/sw/bin/darwin-rebuild switch --flake .

darwin-debug: darwin-set-proxy
    nix build .#darwinConfigurations.harmonica.system --show-trace --verbose
    ./result/sw/bin/darwin-rebuild switch --flake . --show-trace --verbose

Then deploy the nix-darwin config by command:

make darwin

Or deploy with details:

make darwin-debug
AzurIce commented 11 months ago

@ryan4yin Thanks! It works for me very well.

However, I found the curl process of fetchurl is not using the proxy. And finally I solved it by changing the environment variables name to lowercase, like the following:

pl["EnvironmentVariables"]["http_proxy"] = HTTP_PROXY
pl["EnvironmentVariables"]["https_proxy"] = HTTP_PROXY
ryan4yin commented 11 months ago

@AzurIce Thanks for the feedback, updated the script above!