Skip to content

Latest commit

 

History

History
156 lines (125 loc) · 7.53 KB

isolated_development_environment_using_nix.md

File metadata and controls

156 lines (125 loc) · 7.53 KB

Изолированные окружения для разработки с помощью Nix

Источник: Isolated Development Environment using Nix

12 июня 2016

В более ранней записи в блоге я упоминал использование Nix в качестве пакетного менеджера на OS X. В этом продолжении вы увидите мощь Nix в создании изолированных окружений для разработки.

Предположим, я только что установил Nix, и у меня ещё не установлено никаких других пакетов:

$ nix-env -qs
IP-  nix-1.11.2
IPS  nss-cacert-3.21

Мне нужно поработать над проектом с названием Finch. Это стабильный проект, он работает в продакшене и опирается на набор солидных и проверенных окружений: Go 1.4, PUC-Lua 5.3 и Python 2.7.

С другой стороны, у меня есть ещё один не связанный проект — Grove. С этим проектом я всё ещё экспериментирую, и поэтому хочу использовать самые свежие передовые технологии. Его стек основан на новейших Python 3.5 и Go 1.6. По другим причинам мне также понадобился более быстрый Lua, и потому я выбираю LuaJIT. В качестве системы контроля версий вместо Git выбран Fossil.

Для первого проекта имеется файл ~/projects/finch/default.nix со следующим содержимым:

with import <nixpkgs> {};
stdenv.mkDerivation rec {
  name = "env";
  env = buildEnv { name = name; paths = buildInputs; };
  buildInputs = [
    python
    python27Packages.virtualenv
    python27Packages.pip
    go_1_4
    lua5_3
  ];
}

Не углубляясь в выражения Nix (подробности смотрите в руководстве), скажем: приведённый выше файл говорит Nix собрать новое окружение с заданным списком пакетов, указанных через путь атрибута пакета и перечисленных как buildInputs. Как мне узнать путь атрибута для, скажем, Go 1.4? Один способ — вывести список всех доступных пакетов:

$ nix-env -qaP | grep 'go-1.4'
nixpkgs.go_1_4             go-1.4.3

В примере выше go_1_4 (или полный путь nixpkgs.go_1_4) — это путь атрибута для нашего любимого пакета go-1.4.3.

Когда этот Nix-файл готов, каждый раз, когда я хочу поработать над Finch, всё, что мне нужно сделать, это:

$ cd ~/projects/finch/
$ nix-shell
[nix-shell:~/projects/finch]$

Это запустит новую оболочку со всеми пакетами, указанными в default.nix. То есть я получу именно указанные версии Python, Go и Lua. Если это делается впервые, Nix должен установить или собрать эти пакеты, но последующие вызовы nix-shell будут очень быстрыми, поскольку используется то, что есть в кэше.

Чтобы убедиться, что всё работает:

[nix-shell:~/projects/finch]$ python --version
Python 2.7.11
[nix-shell:~/projects/finch]$ pip --version
pip 8.1.2 from /nix/store/3cag9i2pa52qjxq5yvjap6m7jvp6idqm-python2.7-pip-8.1.2/lib/python2.7/site-packages (python 2.7)
[nix-shell:~/projects/finch]$ go version
go version go1.4.3 darwin/amd64
[nix-shell:~/projects/finch]$ lua -v
Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio

Это полностью герметичное окружение для разработки для работы над проектом Finch. Я могу использовать Python, включая virtualenv и pip, как и ожидалось:

[nix-shell:~/projects/finch]$ virtualenv env
New python executable in env/bin/python2.7
Also creating executable in env/bin/python
Installing setuptools, pip, wheel...done.
[nix-shell:~/projects/finch]$ source env/bin/activate
(env)
[nix-shell:~/projects/finch]$ pip install simplejson
Collecting simplejson
Installing collected packages: simplejson
Successfully installed simplejson-3.8.2
(env)
[nix-shell:~/projects/finch]$ pip list
pip (8.1.2)
setuptools (19.4)
simplejson (3.8.2)
virtualenv (13.1.2)
wheel (0.24.0)
(env)

Если я выйду из оболочки, я вернусь в окружение по умолчанию, в котором может не быть вообще никаких из указанных пакетов.

[nix-shell:~/projects/finch]$ exit
ariya:~/projects/finch $ go version
-bash: go: command not found
ariya:~/projects/finch $ pip --version
-bash: pip: command not found

Теперь я переключаюсь обратно на Grove. Его default.nix выглядит немного иначе:

with import <nixpkgs> {};
stdenv.mkDerivation rec {
  name = "env";
  env = buildEnv { name = name; paths = buildInputs; };
  buildInputs = [
    python35
    python35Packages.virtualenv
    python35Packages.pip
    luajit
    fossil
  ];
}

Мой первый шаг перед работой над Grove:

$ cd ~/projects/grove/
$ nix-shell
[nix-shell:~/projects/grove]$

И легко увидеть, что я получаю в этом окружении:

nix-shell:~/projects/grove]$ fossil version
This is fossil version 1.33 [9c65b5432e] 2015-05-23 11:11:31 UTC
[nix-shell:~/projects/grove]$ lua -v
LuaJIT 2.1.0-beta1 -- Copyright (C) 2005-2015 Mike Pall. http://luajit.org/
[nix-shell:~/projects/grove]$ virtualenv env
New python executable in env/bin/python3.5m
Also creating executable in env/bin/python
Installing setuptools, pip, wheel...done.
[nix-shell:~/projects/grove]$ source env/bin/activate
(env)
[nix-shell:~/projects/grove]$ pip list
pip (7.1.2)
setuptools (19.4)
virtualenv (13.1.2)
wheel (0.24.0)
(env)

Как видите, я поддерживаю своё глобальное окружение настолько чистым, насколько это возможно, и в то же время у меня есть гибкое рабочее окружение для двух (или более) разных проектов. Необходимые зависимые пакеты одного проекта не будут вмешиваться в другие проекты или загрязнять их, даже если это один и тот же пакет с разными версиями (Python 2.7 против Python 3.5, Go 1.4 против Go 1.6, PUC-Lua 5.3 против Lua-JIT 2.1).

Приятной работы!


nix linux