Nos artigos anteriores, escrevi uma breve introdução ao Nix
, apresentei algumas vantagens e exemplos,
e a especificação da sintaxe da linaguagem além de apresentar alguns contras e limitações dessa ferramenta!
Neste artigo irei mostrar um exemplo de configuração para um ambiente de desenvolvimento de projetos na linguagem
Elixir com o mix
e também suporte ao framework Phoenix
Requisitos
Os únicos requisitos para seguir este tutorial é ter um conhecimento brévio sobre o ecossistema Elixir
e
possuir o gerenciador de pacotes Nix
instalado no seu sistema.
Caso esteja usando a distribuição NixOS
, o gerenciador de pacotes já estará disponível.
Projeto base criado com o mix
O mix
é a ferramenta de contrução utilizada no ecossistema Elixir
para compilar seu projeto,
realizar tarefas mix
, rodar os testes de sua apliação dentre outras funcionalidades.
Para torná-lo acessível num ambiente isolado, crie um arquivo shell.nix
, com esse conteúdo:
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
let
elixirDrv = elixir.override {
version = "1.11.4";
rev = "308255bda81e7f76f9bec838cef033e8e869981b";
sha256 = "1y8fbhli29agf84ja0fwz6gf22a46738b50nwy26yvcl2n2zl9d8";
minimumOTPVersion = "23";
};
in mkShell {
name = "exemplo_dev";
buildInputs = [ readline elixirDrv ]
shellHook = ''
mkdir -p .nix-mix
mkdir -p .nix-hex
export MIX_HOME=$PWD/.nix-mix
export HEX_HOME=$PWD/.nix-hex
export PATH=$MIX_HOME/bin:$PATH
export PATH=$HEX_HOME/bin:$PATH
export LANG=en_US.UTF-8
export ERL_AFLAGS="-kernel shell_history enabled"
export ERL_LIBS=$HEX_HOME/lib/erlang/lib
'';
}
Com isso, execute nix-shell
ou nix-shell <caminho/para/shell.nix>
e você poderá
utilizar o mix
!
Vamos desconstruir esse arquivo:
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
No começo do arquivo importamos os pacotes a aprtir do repositório nixpkgs
e trazemos todas as opções desse
módulo para o escopo léxico atual.
Já dentro do bloco let...in
, sobrescrevo a versão do pacote da linguagem Elixir
, que atualmente está na versão 1.10.4
no canal estável:
elixirDrv = elixir.override {
version = "1.11.4";
rev = "308255bda81e7f76f9bec838cef033e8e869981b";
sha256 = "1y8fbhli29agf84ja0fwz6gf22a46738b50nwy26yvcl2n2zl9d8";
minimumOTPVersion = "23";
};
Essa expressão pode ser usada para utilizar qualquer versão da linguagem. Existem versões anteriores já envelopadas
no reposiório nixpkgs
como os pacotes elixir_1_9
e elixir_1_7
.
Dentro da derivção especial mkShell
, definimos um nome para esse ambiente e depois definimos a opção buildInputs
,
que presenta quais são as dependências desse ambiente a ser criado:
buildInputs = [ readline elixirDrv ]
E por último declaramos um pequeno script que será executado antes do ambiente ser criado:
shellHook = ''
mkdir -p .nix-mix
mkdir -p .nix-hex
export MIX_HOME=$PWD/.nix-mix
export HEX_HOME=$PWD/.nix-hex
export PATH=$MIX_HOME/bin:$PATH
export PATH=$HEX_HOME/bin:$PATH
export LANG=en_US.UTF-8
export ERL_AFLAGS="-kernel shell_history enabled"
export ERL_LIBS=$HEX_HOME/lib/erlang/lib
'';
Neste exemplo, criamos dois diretórios para abrigar as instalações locais
do mix
e hex
, tornamos disponmíveis os seus executáveis, e definimos duas
variáveis ambiente referentes à BEAM
:
-
ERL_AFLAGS
: o conteúdo dessa variáveis é adicionado no começo do comandoerl
-
ERL_LIBS
: necessária caso você já possua uma instalação local deelixir
, suprimindo os avisos que a biblioteca padrão está sendo redefinida durante a compilação
Projetos Phoenix
Já para projetos Phoenix
, devemos realizar algumas mudanças no arquivo shell.nix
.
Phoenix + PostgreSQL
A primeira mudança é na opção buildInputs
, onde adicionamos algumas dependência para compilação de
algumas dependências do projeto dentre outros utilitários:
buildInputs = [
gnumake
gcc
readline
openssl
zlib
libxml2
curl
libiconv
# minha versão do pacote `elixir`
elixirDrv
glibcLocales
nodejs-12_x
yarn
postgresql
gtk-engine-murrine
] ++ lib.optional stdenv.isLinux [
inotify-tools
# dependência do GTK para usar o observer
gtk-engine-murrine
]
++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
CoreFoundation
CoreServices
]);
A segunda alteração é no script inicial do ambiente, onde definimos algumas váriaveis ambiente
para configuração do servidor do PostgreSQL
e criamos um usuário padrão.
Para isso, adicione os seguintes comandos na opção shellHook
:
export PGHOST=$PWD/.postgres
export PGDATA=$PGHOST/data
export PGLOG=$PGHOST/postgres.log
export PGPASSWORD=postgres
if [ ! -d $PGDATA ]; then
echo 'Initializing postgresql database...'
initdb --auth=trust --no-locale --encoding=UTF8 >/dev/null
fi
# inicializando o servidor
pg_ctl start -l $PGLOG -o "--unix_socket_directories='$PGHOST'"
# verifica se existe um usuário padrão, caso contrário ele é criado
psql -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 \
|| createuser -s postgres
# assim que você sair do ambiente criado pelo `nix-shell`
# o servidor do postgres será desligado
finish() {
pg_ctl -D $PGDATA stop
}
trap finish EXIT
O código completo desta expressão Nix está disponível neste gist.
Phoenix + MariaDB/MySQL
Caso você esteja usando o MariaDB
ou MySQL
como SGBD, apenas altere a útilma parte do shellHook
, removendo
as opções relacionadas ao PostgreSQL
e adicionando essas linhas:
export MYSQL_BASEDIR=${pkgs.mariadb}
export MYSQL_HOME=$PWD/mysql
export MYSQL_DATADIR=$MYSQL_HOME/data
export MYSQL_UNIX_PORT=$MYSQL_HOME/mysql.sock
export MYSQL_PID_FILE=$MYSQL_HOME/mysql.pid
mysql_install_db --datadir=$MYSQL_DATADIR --basedir=$MYSQL_BASEDIR --pid-file=$MYSQL_PID_FILE
mysqld --datadir=$MYSQL_DATADIR --pid-file=$MYSQL_PID_FILE --socket=$MYSQL_UNIX_PORT &
export MYSQL_PID=$!
finish() {
mysqladmin --socket=$MYSQL_UNIX_PORT shutdown
kill $MYSQL_PID
wait $MYSQL_PID
}
trap finish EXIT
Conclusão
Utilizando essas derivações, é possível configurar um ambiente de densenvolvimento totalmente reproduzível
e estável em poucos minutos!
Vale lembrar que esta derivação é plenamente editável e pode ser adaptada para outros tipo de ambientes,
por exemplo aplicações Rails
, Django
ou mesmo Express
ou AdonisJS
.
Este post foi publicado com minha ferramenta de linha de comando devit
!
Você pode encontrar instruções para instalação neste link.
Top comments (0)