Parte 5: Hello Containers¶
Tradução assistida por IA - saiba mais e sugira melhorias
Nas Partes 1-4 deste curso de treinamento, você aprendeu como usar os blocos de construção básicos do Nextflow para montar um fluxo de trabalho simples capaz de processar algum texto, paralelizar a execução se houvesse múltiplas entradas e coletar os resultados para processamento adicional.
No entanto, você estava limitado às ferramentas básicas do UNIX disponíveis no seu ambiente. Tarefas do mundo real frequentemente requerem várias ferramentas e pacotes não incluídos por padrão. Tipicamente, você precisaria instalar essas ferramentas, gerenciar suas dependências e resolver quaisquer conflitos.
Tudo isso é muito tedioso e irritante, então vamos mostrar como usar contêineres para resolver este problema de forma muito mais conveniente.
Um contêiner é uma unidade leve, autônoma e executável de software criada a partir de uma imagem de contêiner que inclui tudo o que é necessário para executar uma aplicação, incluindo código, bibliotecas do sistema e configurações. Como você pode imaginar, isso será muito útil para tornar seus pipelines mais reproduzíveis.
Note que ensinaremos isso usando Docker, mas tenha em mente que o Nextflow suporta várias outras tecnologias de contêiner também.
Como começar a partir desta seção
Esta seção do curso assume que você completou as Partes 1-4 do curso Hello Nextflow e tem um pipeline completo funcionando.
Se você está começando o curso a partir deste ponto, você precisará copiar o diretório modules das soluções:
0. Aquecimento: Execute hello-containers.nf¶
Vamos usar o script de fluxo de trabalho hello-containers.nf como ponto de partida.
Ele é equivalente ao script produzido ao trabalhar na Parte 4 deste curso de treinamento, exceto que mudamos os destinos de saída:
| hello-containers.nf | |
|---|---|
Apenas para garantir que tudo está funcionando, execute o script uma vez antes de fazer qualquer alteração:
Saída do comando
Como anteriormente, você encontrará os arquivos de saída no diretório especificado no bloco output (results/hello_containers/).
Conteúdo do diretório
Se funcionou para você, você está pronto para aprender como usar contêineres.
1. Use um contêiner 'manualmente'¶
O que queremos fazer é adicionar uma etapa ao nosso fluxo de trabalho que usará um contêiner para execução.
No entanto, primeiro vamos revisar alguns conceitos básicos e operações para solidificar sua compreensão do que são contêineres antes de começarmos a usá-los no Nextflow.
1.1. Baixe a imagem do contêiner¶
Para usar um contêiner, você normalmente baixa ou puxa uma imagem de contêiner de um registro de contêineres e então executa a imagem de contêiner para criar uma instância de contêiner.
A sintaxe geral é a seguinte:
A parte docker pull é a instrução ao sistema de contêiner para puxar uma imagem de contêiner de um repositório.
A parte '<container>' é o endereço URI da imagem de contêiner.
Como exemplo, vamos puxar uma imagem de contêiner que contém cowpy, uma implementação em Python de uma ferramenta chamada cowsay que gera arte ASCII para exibir entradas de texto arbitrárias de forma divertida.
________________________
< Are we having fun yet? >
------------------------
\ ___-------___
\ _-~~ ~~-_
\ _-~ /~-_
/^\__/^\ /~ \ / \
/| O|| O| / \_______________/ \
| |___||__| / / \ \
| \ / / \ \
| (_______) /______/ \_________ \
| / / \ / \
\ \^\\ \ / \ /
\ || \______________/ _-_ //\__//
\ ||------_-~~-_ ------------- \ --/~ ~\ || __/
~-----||====/~ |==================| |/~~~~~
(_(__/ ./ / \_\ \.
(_(___/ \_____)_)
Existem vários repositórios onde você pode encontrar contêineres publicados.
Usamos o serviço Seqera Containers para gerar esta imagem de contêiner Docker a partir do pacote Conda cowpy: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'.
Execute o comando pull completo:
Saída do comando
1.1.5--3db457ae1977a273: Pulling from library/cowpy
dafa2b0c44d2: Pull complete
dec6b097362e: Pull complete
f88da01cff0b: Pull complete
4f4fb700ef54: Pull complete
92dc97a3ef36: Pull complete
403f74b0f85e: Pull complete
10b8c00c10a5: Pull complete
17dc7ea432cc: Pull complete
bb36d6c3110d: Pull complete
0ea1a16bbe82: Pull complete
030a47592a0a: Pull complete
c23bdb422167: Pull complete
e1686ff32a11: Pull complete
Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160
Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273
community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273
Se você nunca baixou a imagem antes, isso pode levar um minuto para completar. Uma vez concluído, você tem uma cópia local da imagem de contêiner.
1.2. Use o contêiner para executar cowpy como um comando único¶
Uma maneira muito comum de as pessoas usarem contêineres é executá-los diretamente, ou seja, de forma não interativa. Isso é ótimo para executar comandos únicos.
A sintaxe geral é a seguinte:
A parte docker run --rm '<container>' é a instrução ao sistema de contêiner para iniciar uma instância de contêiner a partir de uma imagem de contêiner e executar um comando nela.
A flag --rm diz ao sistema para desligar a instância de contêiner após o comando ter sido completado.
A sintaxe [tool command] depende da ferramenta que você está usando e de como o contêiner está configurado.
Vamos começar apenas com cowpy.
Totalmente montado, o comando de execução do contêiner fica assim; vá em frente e execute-o.
Saída do comando
O sistema iniciou o contêiner, executou o comando cowpy com seus parâmetros, enviou a saída para o console e finalmente desligou a instância de contêiner.
1.3. Use o contêiner para executar cowpy interativamente¶
Você também pode executar um contêiner interativamente, o que lhe dá um prompt de shell dentro do contêiner e permite que você brinque com o comando.
1.3.1. Inicie o contêiner¶
Para executar interativamente, apenas adicionamos -it ao comando docker run.
Opcionalmente, podemos especificar o shell que queremos usar dentro do contêiner anexando por exemplo /bin/bash ao comando.
Note que seu prompt muda para algo como (base) root@b645838b3314:/tmp#, o que indica que você está agora dentro do contêiner.
Você pode verificar isso executando ls / para listar o conteúdo do diretório a partir da raiz do sistema de arquivos:
Saída do comando
Usamos ls aqui em vez de tree porque o utilitário tree não está disponível neste contêiner.
Você pode ver que o sistema de arquivos dentro do contêiner é diferente do sistema de arquivos no seu sistema hospedeiro.
Uma limitação do que acabamos de fazer é que o contêiner está completamente isolado do sistema hospedeiro por padrão. Isso significa que o contêiner não pode acessar nenhum arquivo no sistema hospedeiro a menos que você permita explicitamente que ele o faça.
Vamos mostrar como fazer isso em um minuto.
1.3.2. Execute o(s) comando(s) da ferramenta desejada¶
Agora que você está dentro do contêiner, você pode executar o comando cowpy diretamente e dar alguns parâmetros a ele.
Por exemplo, a documentação da ferramenta diz que podemos mudar o personagem ('cowacter') com -c.
Saída do comando
Agora a saída mostra o pinguim do Linux, Tux, em vez da vaca padrão, porque especificamos o parâmetro -c tux.
Como você está dentro do contêiner, você pode executar o comando cowpy quantas vezes quiser, variando os parâmetros de entrada, sem ter que se preocupar com comandos Docker.
Dica
Use a flag '-c' para escolher um personagem diferente, incluindo:
beavis, cheese, daemon, dragonandcow, ghostbusters, kitty, moose, milk, stegosaurus, turkey, turtle, tux
Isso é legal. O que seria ainda mais legal é se pudéssemos alimentar nosso greetings.csv como entrada nisso.
Mas como não temos acesso ao sistema de arquivos, não podemos.
Vamos consertar isso.
1.3.3. Saia do contêiner¶
Para sair do contêiner, você pode digitar exit no prompt ou usar o atalho de teclado Ctrl+D.
Seu prompt agora deve estar de volta ao que era antes de você iniciar o contêiner.
1.3.4. Monte dados no contêiner¶
Como notado anteriormente, o contêiner está isolado do sistema hospedeiro por padrão.
Para permitir que o contêiner acesse o sistema de arquivos do hospedeiro, você pode montar um volume do sistema hospedeiro no contêiner usando a seguinte sintaxe:
No nosso caso <outside_path> será o diretório de trabalho atual, então podemos apenas usar um ponto (.), e <inside_path> é apenas um alias que inventamos; vamos chamá-lo de /my_project (o caminho interno deve ser absoluto).
Para montar um volume, substituímos os caminhos e adicionamos o argumento de montagem de volume ao comando docker run da seguinte forma:
docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash
Isso monta o diretório de trabalho atual como um volume que estará acessível em /my_project dentro do contêiner.
Você pode verificar que funciona listando o conteúdo de /my_project:
Saída do comando
Agora você pode ver o conteúdo do diretório de trabalho de dentro do contêiner, incluindo o arquivo greetings.csv em data/.
Isso efetivamente estabeleceu um túnel através da parede do contêiner que você pode usar para acessar aquela parte do seu sistema de arquivos.
1.3.5. Use os dados montados¶
Agora que montamos o diretório de trabalho no contêiner, podemos usar o comando cowpy para exibir o conteúdo do arquivo greetings.csv.
Para fazer isso, usaremos cat /my_project/data/greetings.csv | para canalizar o conteúdo do arquivo CSV para o comando cowpy.
Saída do comando
____________________
/ Hello,English,123 \
| Bonjour,French,456 |
\ Holà,Spanish,789 /
--------------------
\ ,+*^^*+___+++_
\ ,*^^^^ )
\ _+* ^**+_
\ +^ _ _++*+_+++_, )
_+^^*+_ ( ,+*^ ^ \+_ )
{ ) ( ,( ,_+--+--, ^) ^\
{ (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ )
{:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) /
( / ( ( ,___ ^*+_+* ) < < \
U _/ ) *--< ) ^\-----++__) ) ) )
( ) _(^)^^)) ) )\^^^^^))^*+/ / /
( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^
( ,/ (^))^)) ) ) ))^^^^^^^))^^) _)
*+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^
\ \_)^)_)) ))^^^^^^^^^^))^^^^)
(_ ^\__^^^^^^^^^^^^))^^^^^^^)
^\___ ^\__^^^^^^))^^^^^^^^)\\
^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\
___) >____) >___ ^\_\_\_\_\_\_\)
^^^//\\_^^//\\_^ ^(\_\_\_\)
^^^ ^^ ^^^ ^
Isso produz a arte ASCII desejada de um peru recitando nossas saudações de exemplo! Exceto que aqui o peru está repetindo as linhas completas em vez de apenas as saudações. Já sabemos que nosso fluxo de trabalho Nextflow fará um trabalho melhor!
Sinta-se à vontade para brincar com este comando. Quando terminar, saia do contêiner como anteriormente:
Você se encontrará de volta ao seu shell normal.
Conclusão¶
Você sabe como puxar um contêiner e executá-lo como um comando único ou interativamente. Você também sabe como tornar seus dados acessíveis de dentro do seu contêiner, o que permite que você experimente qualquer ferramenta na qual esteja interessado com dados reais sem ter que instalar nenhum software no seu sistema.
O que vem a seguir?¶
Aprenda como usar contêineres para a execução de processos Nextflow.
2. Use contêineres no Nextflow¶
O Nextflow tem suporte integrado para executar processos dentro de contêineres para permitir que você execute ferramentas que você não tem instaladas no seu ambiente de computação. Isso significa que você pode usar qualquer imagem de contêiner que desejar para executar seus processos, e o Nextflow cuidará de puxar a imagem, montar os dados e executar o processo dentro dela.
Para demonstrar isso, vamos adicionar uma etapa cowpy ao pipeline que estamos desenvolvendo, após a etapa collectGreetings.
Muu se você está pronto para mergulhar!
2.1. Escreva um módulo cowpy¶
Primeiro, vamos criar o módulo do processo cowpy.
2.1.1. Crie um arquivo stub para o novo módulo¶
Crie um arquivo vazio para o módulo chamado cowpy.nf.
Isso nos dá um lugar para colocar o código do processo.
2.1.2. Copie o código do processo cowpy no arquivo do módulo¶
Podemos modelar nosso processo cowpy nos outros processos que escrevemos anteriormente.
| modules/cowpy.nf | |
|---|---|
O processo espera um input_file contendo as saudações, bem como um valor character.
A saída será um novo arquivo de texto contendo a arte ASCII gerada pela ferramenta cowpy.
2.2. Adicione cowpy ao fluxo de trabalho¶
Agora precisamos importar o módulo e chamar o processo.
2.2.1. Importe o processo cowpy para hello-containers.nf¶
Insira a declaração de importação acima do bloco de fluxo de trabalho e preencha-a adequadamente.
Agora o módulo cowpy está disponível para uso no fluxo de trabalho.
2.2.2. Adicione uma chamada ao processo cowpy no fluxo de trabalho¶
Vamos conectar o processo cowpy() à saída do processo collectGreetings(), que como você deve se lembrar produz duas saídas:
collectGreetings.out.outfilecontém o arquivo de saída <--o que queremoscollectGreetings.out.reportcontém o arquivo de relatório com a contagem de saudações por lote
No bloco de fluxo de trabalho, faça a seguinte mudança de código:
Note que declaramos um novo parâmetro CLI, params.character, para especificar qual personagem queremos que diga as saudações.
2.2.3. Adicione o parâmetro character ao bloco params¶
Isso é tecnicamente opcional, mas é a prática recomendada e é uma oportunidade de definir um valor padrão para o personagem enquanto estamos nisso.
Agora podemos ser preguiçosos e pular a digitação do parâmetro de personagem em nossas linhas de comando.
2.2.4. Atualize as saídas do fluxo de trabalho¶
Precisamos atualizar as saídas do fluxo de trabalho para publicar a saída do processo cowpy.
2.2.4.1. Atualize a seção publish:¶
No bloco de workflow, faça a seguinte mudança de código:
O processo cowpy produz apenas uma saída, então podemos referenciá-la da maneira usual anexando .out.
Mas por enquanto, vamos terminar de atualizar as saídas no nível do fluxo de trabalho.
2.2.4.2. Atualize o bloco output¶
Precisamos adicionar a saída final cowpy_art ao bloco output. Enquanto estamos nisso, vamos também editar os destinos de publicação, já que agora nosso pipeline está completo e sabemos quais saídas realmente nos interessam.
No bloco output, faça as seguintes mudanças de código:
Agora as saídas publicadas estarão um pouco mais organizadas.
2.2.5. Execute o fluxo de trabalho¶
Apenas para recapitular, isso é o que estamos buscando:
Você acha que vai funcionar?
Vamos deletar as saídas publicadas anteriores para ter um slate limpo, e executar o fluxo de trabalho com a flag -resume.
Saída do comando (editada para clareza)
N E X T F L O W ~ version 25.10.2
Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f
executor > local (1)
[c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔
[ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔
[7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔
[9b/02e776] cowpy [ 0%] 0 of 1 ✘
ERROR ~ Error executing process > 'cowpy'
Caused by:
Process `cowpy` terminated with an error exit status (127)
Command executed:
cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt
Command exit status:
127
Command output:
(empty)
Command error:
.command.sh: line 2: cowpy: command not found
Work dir:
/workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6
Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line
-- Check '.nextflow.log' file for details
ERROR ~ Cannot access first() element from an empty List
-- Check '.nextflow.log' file for details
Oh não, há um erro!
O código de erro dado por error exit status (127) significa que o executável que pedimos não foi encontrado.
Isso faz sentido, já que estamos chamando a ferramenta cowpy mas não especificamos um contêiner ainda (ops).
2.3. Use um contêiner para executar o processo cowpy¶
Precisamos especificar um contêiner e dizer ao Nextflow para usá-lo no processo cowpy().
2.3.1. Especifique um contêiner para cowpy¶
Podemos usar a mesma imagem que estávamos usando diretamente na primeira seção deste tutorial.
Edite o módulo cowpy.nf para adicionar a diretiva container à definição do processo da seguinte forma:
| modules/cowpy.nf | |
|---|---|
Isso diz ao Nextflow que se o uso de Docker estiver habilitado, ele deve usar a imagem de contêiner especificada aqui para executar o processo.
2.3.2. Habilite o uso de Docker através do arquivo nextflow.config¶
Note que dissemos 'se o uso de Docker estiver habilitado'. Por padrão, não está, então precisamos dizer ao Nextflow que ele tem permissão para usar Docker. Para esse fim, vamos antecipar um pouco o tópico da próxima e última parte deste curso (Parte 6), que cobre configuração.
Uma das principais maneiras que o Nextflow oferece para configurar a execução do fluxo de trabalho é usar um arquivo nextflow.config.
Quando tal arquivo está presente no diretório atual, o Nextflow irá carregá-lo automaticamente e aplicar qualquer configuração que ele contém.
Fornecemos um arquivo nextflow.config com uma única linha de código que desabilita explicitamente o Docker: docker.enabled = false.
Agora, vamos mudar isso para true para habilitar o Docker:
Dica
É possível habilitar a execução Docker a partir da linha de comando, por execução, usando o parâmetro -with-docker <container>.
No entanto, isso só nos permite especificar um contêiner para todo o fluxo de trabalho, enquanto a abordagem que acabamos de mostrar permite especificar um contêiner diferente por processo.
Isso é melhor para modularidade, manutenção de código e reprodutibilidade.
2.3.3. Execute o fluxo de trabalho com Docker habilitado¶
Execute o fluxo de trabalho com a flag -resume:
Saída do comando
N E X T F L O W ~ version 25.10.2
Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f
executor > local (1)
[c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔
[ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔
[7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔
[98/656c6c] cowpy [100%] 1 of 1 ✔
Desta vez realmente funciona! Como de costume, você pode encontrar as saídas do fluxo de trabalho no diretório de resultados correspondente, embora desta vez elas estejam um pouco mais organizadas, com apenas o relatório e a saída final no nível superior, e todos os arquivos intermediários empurrados para fora do caminho em um subdiretório.
Conteúdo do diretório
A saída final de arte ASCII está no diretório results/hello_containers/, com o nome cowpy-COLLECTED-batch-output.txt.
Conteúdo do arquivo
_________
/ HOLà \
| HELLO |
\ BONJOUR /
---------
\ ,+*^^*+___+++_
\ ,*^^^^ )
\ _+* ^**+_
\ +^ _ _++*+_+++_, )
_+^^*+_ ( ,+*^ ^ \+_ )
{ ) ( ,( ,_+--+--, ^) ^\
{ (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ )
{:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) /
( / ( ( ,___ ^*+_+* ) < < \
U _/ ) *--< ) ^\-----++__) ) ) )
( ) _(^)^^)) ) )\^^^^^))^*+/ / /
( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^
( ,/ (^))^)) ) ) ))^^^^^^^))^^) _)
*+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^
\ \_)^)_)) ))^^^^^^^^^^))^^^^)
(_ ^\__^^^^^^^^^^^^))^^^^^^^)
^\___ ^\__^^^^^^))^^^^^^^^)\\
^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\
___) >____) >___ ^\_\_\_\_\_\_\)
^^^//\\_^^//\\_^ ^(\_\_\_\)
^^^ ^^ ^^^ ^
E aí está, nosso lindo peru dizendo as saudações conforme desejado.
2.3.4. Inspecione como o Nextflow lançou a tarefa em contêiner¶
Como um coda final para esta seção, vamos dar uma olhada no subdiretório de trabalho de uma das chamadas do processo cowpy para obter um pouco mais de insight sobre como o Nextflow trabalha com contêineres nos bastidores.
Verifique a saída do seu comando nextflow run para encontrar o caminho para o subdiretório de trabalho do processo cowpy.
Olhando para o que obtivemos para a execução mostrada acima, a linha de log do console para o processo cowpy começa com [98/656c6c].
Isso corresponde ao seguinte caminho de diretório truncado: work/98/656c6c.
Nesse diretório, você encontrará o arquivo .command.run que contém todos os comandos que o Nextflow executou em seu nome no curso da execução do pipeline.
Conteúdo do arquivo
#!/bin/bash
### ---
### name: 'cowpy'
### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'
### outputs:
### - 'cowpy-COLLECTED-batch-output.txt'
### ...
set -e
set -u
NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x
NXF_ENTRY=${1:-nxf_main}
nxf_sleep() {
sleep $1 2>/dev/null || sleep 1;
}
nxf_date() {
local ts=$(date +%s%3N);
if [[ ${#ts} == 10 ]]; then echo ${ts}000
elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000}
elif [[ $ts == *3N ]]; then echo ${ts/3N/000}
elif [[ ${#ts} == 13 ]]; then echo $ts
else echo "Unexpected timestamp value: $ts"; exit 1
fi
}
nxf_env() {
echo '============= task environment ============='
env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/"
echo '============= task output =================='
}
nxf_kill() {
declare -a children
while read P PP;do
children[$PP]+=" $P"
done < <(ps -e -o pid= -o ppid=)
kill_all() {
[[ $1 != $$ ]] && kill $1 2>/dev/null || true
for i in ${children[$1]:=}; do kill_all $i; done
}
kill_all $1
}
nxf_mktemp() {
local base=${1:-/tmp}
mkdir -p "$base"
if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX
else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX
fi
}
nxf_fs_copy() {
local source=$1
local target=$2
local basedir=$(dirname $1)
mkdir -p $target/$basedir
cp -fRL $source $target/$basedir
}
nxf_fs_move() {
local source=$1
local target=$2
local basedir=$(dirname $1)
mkdir -p $target/$basedir
mv -f $source $target/$basedir
}
nxf_fs_rsync() {
rsync -rRl $1 $2
}
nxf_fs_rclone() {
rclone copyto $1 $2/$1
}
nxf_fs_fcp() {
fcp $1 $2/$1
}
on_exit() {
local last_err=$?
local exit_status=${nxf_main_ret:=0}
[[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0}
[[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err}
printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode
set +u
docker rm $NXF_BOXID &>/dev/null || true
exit $exit_status
}
on_term() {
set +e
docker stop $NXF_BOXID
}
nxf_launch() {
docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh
}
nxf_stage() {
true
# stage input files
rm -f COLLECTED-batch-output.txt
ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt
}
nxf_unstage_outputs() {
true
}
nxf_unstage_controls() {
true
}
nxf_unstage() {
if [[ ${nxf_main_ret:=0} == 0 ]]; then
(set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err)
nxf_unstage_ret=$?
fi
nxf_unstage_controls
}
nxf_main() {
trap on_exit EXIT
trap on_term TERM INT USR2
trap '' USR1
[[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR"
export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')"
NXF_SCRATCH=''
[[ $NXF_DEBUG > 0 ]] && nxf_env
touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin
set +u
set -u
[[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH
export NXF_TASK_WORKDIR="$PWD"
nxf_stage
set +e
(set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) &
pid=$!
wait $pid || nxf_main_ret=$?
nxf_unstage
}
$NXF_ENTRY
Se você procurar por nxf_launch neste arquivo, você deve ver algo assim:
nxf_launch() {
docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh
}
Como você pode ver, o Nextflow está usando o comando docker run para lançar a chamada do processo.
Ele também monta o subdiretório de trabalho correspondente no contêiner, define o diretório de trabalho dentro do contêiner adequadamente e executa nosso script bash modelado no arquivo .command.sh.
Todo o trabalho duro que tivemos que fazer manualmente na primeira seção? O Nextflow faz por nós nos bastidores!
_______________________
< Viva os robôs...! >
-----------------------
,-----.
| |
,--| |-.
__,----| | | |
,;:: | `_____' |
`._______| i^i |
`----| |---'| .
,-------._| |== ||//
| |_|P`. /'/
`-------' 'Y Y/'/'
.==\ /_\
^__^ / /'| `i
(oo)\_______ /' / | |
(__)\ )\/\ /' / | `i
||----w | ___,;`----'.___L_,-'`\__
|| || i_____;----\.____i""\____\
Conclusão¶
Você sabe como usar contêineres no Nextflow para executar processos.
O que vem a seguir?¶
Faça uma pausa!
Quando estiver pronto, siga para Parte 6: Olá Configuração para aprender como configurar a execução do seu pipeline para se adequar à sua infraestrutura, bem como gerenciar configuração de entradas e parâmetros.
É a última parte, e então você terá terminado este curso!
Quiz¶
O que é um contêiner?
Qual é a diferença entre uma imagem de contêiner e uma instância de contêiner?
O que a flag -v faz em um comando docker run?
Por que você precisa montar volumes ao usar contêineres?
Como você especifica um contêiner para um processo Nextflow?
Qual configuração do nextflow.config habilita Docker para seu fluxo de trabalho?
O que o Nextflow lida automaticamente ao executar um processo em um contêiner? (Selecione todas as opções que se aplicam)