Como construir um ambiente personalizado para o Jupyter no Docker
Se você tem desenvolvido software nos últimos anos, você provavelmente teve algum contato com o uso de containers não apenas para fazer o deploy, mas também durante o desenvolvimento para ter certeza de que o seu ambiente é totalmente reproduzível em sistemas diferentes.
Também é muito popular nos meios de ciência de dados, visualização de dados e outros relacionados usar Python e Jupyter Notebooks e Jupyter Lab para explorar e experimentar com os dados. Algumas pessoas criticam o Jupyter por frequentemente resultar em trabalhos não reproduzíveis, algo muito importante para o método científico, pois o ambiente de desenvolvimento pode ser diferente daquele que o vai reproduzir e as células podem ser executadas fora de ordem. Por exemplo, em um experimento feito pela equipe Datalore do Jetbrains Datalore no ano passado que baixou quase 10 milhões de cadernos do Github, eles descobriram que 36% desses cadernos eram inconsistentes, isto é, eram executados em uma ordem não linear.
Por outro lado, se o seu ambiente estiver definido em um container Docker e você tomar o cuidado de fazer a boa prática de executar as células na ordem apropriada, os cadernos podem ser completamente reproduzíveis.
Pode não ser tão óbvio como fazê-lo, todavia. Por isso, aqui está um guia passo a passo de como usar o Jupyter Lab e o Jupyter Notebook dentro do Docker com os pacotes Python de sua escolha.
Este guia foi escrito pensando em um sistema baseado em GNU-Linux e foi testado no Ubuntu 18.04 e 20.04. Ele deve funcionar em outros sistemas baseados em GNU-Linux. Todavia, se você estiver usando Windows ou MacOS, você terá que fazer algumas adaptações para funcionar, principalmente em relação às operações de linha de comando e variáveis de ambiente, mas isso não é abordado neste guia.
Preparações
Antes de começar, certifique-se de que o Docker e o Docker Compose estão instalados.
Escolhendo uma imagem base
O Jupyter Docker Stacks fornece algumas imagens prontas para rodar e algumas receitas para criar a sua própria imagem de Docker herdando a partir destas (o que eles chamam de imagem Docker filha).
Para isso, precisamos primeiro escolher uma imagem base da qual herdar.
Para este exercício vamos usar a jupyter/scipy-notebook
, que inclui
o Pandas, o NumPy
e mais algumas coisas. Entretanto, dê uma olhada na seção de
seleção de imagem
na documentação do Jupyter Docker Stacks para ver outras opções.
Então vamos criar um Dockerfile
para construir a imagem Docker
personalizada e a seguinte linha para definir a imagem base:
FROM jupyter/scipy-notebook
Se você não quiser criar um novo Dockerfile
do zero, você também pode
clonar
este repositório de exemplo
a partir do Github, que tem um Dockerfile
pronto para uso.
Configurando os locales
Se você algum dia for trabalhar com dados de outros locales que não sejam os EUA, você provavelmente deveria configurar um ou mais outros locales. Por exemplo, isso vai tornar mais fácil trabalhar com separadores de casas decimais diferentes ou com os nomes dos dias da semana e dos meses do ano em diferentes idiomas.
Para este exercício, vamos configurar os locales do sistema para usar
ambos os locales en_US.UTF-8 (inglês, EUA) e pt_BR.UTF-8 (português
brasileiro). A seguinte seção do Dockerfile
faz exatamente isso.
# instala os locales que você quiser usar
RUN set -ex \
&& sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \
&& sed -i 's/^# pt_BR.UTF-8 UTF-8$/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen \
&& locale-gen en_US.UTF-8 pt_BR.UTF-8 \
&& update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \
Escolhendo os seus pacotes Python
Em seguida, nós vamos escolher os pacotes Python que estarão disponíveis
para o Jupyter dentro do ambiente. Neste exemplo, escolhemos a ferramenta
de visualização de dados chamada Plotly e
o pacote de traçar mapas chamado
Folium. Esta é a
seção do Dockerfile
onde definimos isso.
# instala os pacotes Python que você usa frequentemente
RUN set -ex \
&& conda install --quiet --yes \
# escolhe os pacotes Python que você precisa
'plotly==4.9.0' \
'folium==0.11.0' \
&& conda clean --all -f -y \
# instala as extensões do Jupyter Lab que você precisa
&& jupyter labextension install jupyterlab-plotly@4.9.0 --no-build \
&& jupyter lab build -y \
&& jupyter lab clean -y \
&& rm -rf "/home/${NB_USER}/.cache/yarn" \
&& rm -rf "/home/${NB_USER}/.node-gyp" \
&& fix-permissions "${CONDA_DIR}" \
&& fix-permissions "/home/${NB_USER}"
Substitua-os ou adicione os pacotes Python e extensões do Jupyter Lab que você quiser.
Construindo o container
Este passo é muito fácil de se fazer, mas pode demorar bastante para terminar. Simplesmente execute o seguinte comando:
$ docker build --rm -t docker-jupyter-extensible .
e vá fazer um lanche ou fazer alguma outra coisa e volte depois de um tempo.
Corrigindo as permissões
Um problema comum ao montar uma pasta do host dentro do container é que os donos dos arquivos frequentemente não se correspondem. Então você fica ou sem acesso à pasta ou com somente leitura. Para corrigir isso, precisamos configurar o usuário e o grupo usados dentro do container para ter os mesmos números de id que o usuário e grupo que você estiver usando no host. Pode parecer complicado, mas com essas imagens é algo muito fácil de se fazer.
Apenas crie um arquivo chamado .env
, rodando o seguinte comando:
$ printf "UID=$(id -u)\nGID=$(id -g)\n" > .env
Isso vai permitir que você use a pasta notebooks
tanto dentro como
fora do container.
Executando o container
Está pronto! A cada vez que você quiser iniciar o Jupyter, apenas rode o container com o comando:
$ docker-compose up
Você deve ver as mensagens do container no terminal. Se tudo correr bem,
você deve ver um link começando com http://127.0.0.1:8888
que também
contém um token de acesso. Abra esse link em um navegador para usar o
Jupyter Notebook. Se, em vez disso, você quiser usar o Jupyter Lab, é
só trocar o início da URL para
http://127.0.0.1:8888/lab
, mas mantenha tudo depois disso, incluindo
o token de acesso.
Para verificar que os pacotes foram corretamente instalados e configurados, apenas abra um novo caderno e os importe. Veja, por exemplo, o Plotly Express:
Agora divirta-se com o seu novo Jupyter Lab ou Jupyter Notebook!
Se, mais tarde, você quiser acrescentar quaisquer novos pacotes, só vá para o passo “escolhendo os seus pacotes”, faça as alterações que deseja e siga a partir dali, construindo o container novamente.
Referências: este texto foi mencionado na newsletter da comunidade Data Hackers de fevereiro de 2020.