Parte 5: Hello Containers¶
Traducción asistida por IA - más información y sugerencias
Vea la lista de reproducción completa en el canal de YouTube de Nextflow.
La transcripción del video está disponible aquí.
En las Partes 1-4 de este curso de capacitación, aprendió a usar los bloques de construcción básicos de Nextflow para ensamblar un workflow simple capaz de procesar texto, paralelizar la ejecución si había múltiples entradas y recopilar los resultados para su posterior procesamiento.
Sin embargo, estaba limitado a las herramientas básicas de UNIX disponibles en su entorno. Las tareas del mundo real a menudo requieren varias herramientas y paquetes que no están incluidos de forma predeterminada. Típicamente, necesitaría instalar estas herramientas, gestionar sus dependencias y resolver cualquier conflicto.
Todo eso es muy tedioso y molesto, así que vamos a mostrarle cómo usar contenedores para resolver este problema de manera mucho más conveniente.
Un contenedor es una unidad de software ligera, independiente y ejecutable creada a partir de una imagen de contenedor que incluye todo lo necesario para ejecutar una aplicación, incluyendo código, bibliotecas del sistema y configuraciones. Como puede imaginar, eso va a ser muy útil para hacer que sus pipelines sean más reproducibles.
Tenga en cuenta que enseñaremos esto usando Docker, pero recuerde que Nextflow también admite varias otras tecnologías de contenedores.
Cómo comenzar desde esta sección
Esta sección del curso asume que ha completado las Partes 1-4 del curso Hello Nextflow y tiene un pipeline completo y funcional.
Si está comenzando el curso desde este punto, necesitará copiar el directorio modules desde las soluciones:
0. Calentamiento: Ejecutar hello-containers.nf¶
Vamos a usar el script de workflow hello-containers.nf como punto de partida.
Es equivalente al script producido al trabajar en la Parte 4 de este curso de capacitación, excepto que hemos cambiado los destinos de salida:
| hello-containers.nf | |
|---|---|
Solo para asegurarnos de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio:
Salida del comando
Como anteriormente, encontrará los archivos de salida en el directorio especificado en el bloque output (results/hello_containers/).
Contenido del directorio
Si eso funcionó para usted, está listo para aprender cómo usar contenedores.
1. Usar un contenedor 'manualmente'¶
Lo que queremos hacer es agregar un paso a nuestro workflow que usará un contenedor para la ejecución.
Sin embargo, primero vamos a repasar algunos conceptos y operaciones básicas para solidificar su comprensión de qué son los contenedores antes de comenzar a usarlos en Nextflow.
1.1. Descargar la imagen del contenedor¶
Para usar un contenedor, generalmente descarga o extrae una imagen de contenedor de un registro de contenedores, y luego ejecuta la imagen del contenedor para crear una instancia de contenedor.
La sintaxis general es la siguiente:
La parte docker pull es la instrucción al sistema de contenedores para extraer una imagen de contenedor de un repositorio.
La parte '<container>' es la dirección URI de la imagen del contenedor.
Como ejemplo, extraigamos una imagen de contenedor que contiene cowpy, una implementación en Python de una herramienta llamada cowsay que genera arte ASCII para mostrar entradas de texto arbitrarias de una manera divertida.
________________________
< Are we having fun yet? >
------------------------
\ ___-------___
\ _-~~ ~~-_
\ _-~ /~-_
/^\__/^\ /~ \ / \
/| O|| O| / \_______________/ \
| |___||__| / / \ \
| \ / / \ \
| (_______) /______/ \_________ \
| / / \ / \
\ \^\\ \ / \ /
\ || \______________/ _-_ //\__//
\ ||------_-~~-_ ------------- \ --/~ ~\ || __/
~-----||====/~ |==================| |/~~~~~
(_(__/ ./ / \_\ \.
(_(___/ \_____)_)
Hay varios repositorios donde puede encontrar contenedores publicados.
Usamos el servicio Seqera Containers para generar esta imagen de contenedor Docker a partir del paquete Conda cowpy: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'.
Ejecute el comando pull completo:
Salida del 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
Si nunca ha descargado la imagen antes, esto puede tardar un minuto en completarse. Una vez que esté listo, tiene una copia local de la imagen del contenedor.
1.2. Usar el contenedor para ejecutar cowpy como un comando único¶
Una forma muy común en que las personas usan contenedores es ejecutarlos directamente, es decir, de forma no interactiva. Esto es excelente para ejecutar comandos únicos.
La sintaxis general es la siguiente:
La parte docker run --rm '<container>' es la instrucción al sistema de contenedores para iniciar una instancia de contenedor a partir de una imagen de contenedor y ejecutar un comando en ella.
La bandera --rm le dice al sistema que apague la instancia del contenedor después de que el comando se haya completado.
La sintaxis [comando de herramienta] depende de la herramienta que esté usando y de cómo esté configurado el contenedor.
Comencemos simplemente con cowpy.
Completamente ensamblado, el comando de ejecución del contenedor se ve así; adelante, ejecútelo.
Salida del comando
El sistema inició el contenedor, ejecutó el comando cowpy con sus parámetros, envió la salida a la consola y finalmente, apagó la instancia del contenedor.
1.3. Usar el contenedor para ejecutar cowpy interactivamente¶
También puede ejecutar un contenedor de forma interactiva, lo que le da un prompt de shell dentro del contenedor y le permite jugar con el comando.
1.3.1. Iniciar el contenedor¶
Para ejecutar de forma interactiva, simplemente agregamos -it al comando docker run.
Opcionalmente, podemos especificar el shell que queremos usar dentro del contenedor agregando p. ej. /bin/bash al comando.
Note que su prompt cambia a algo como (base) root@b645838b3314:/tmp#, lo que indica que ahora está dentro del contenedor.
Puede verificar esto ejecutando ls / para listar el contenido del directorio desde la raíz del sistema de archivos:
Salida del comando
Usamos ls aquí en lugar de tree porque la utilidad tree no está disponible en este contenedor.
Puede ver que el sistema de archivos dentro del contenedor es diferente del sistema de archivos en su sistema host.
Una limitación de lo que acabamos de hacer es que el contenedor está completamente aislado del sistema host de forma predeterminada. Esto significa que el contenedor no puede acceder a ningún archivo en el sistema host a menos que usted lo permita explícitamente.
Le mostraremos cómo hacer eso en un minuto.
1.3.2. Ejecutar el(los) comando(s) de herramienta deseado(s)¶
Ahora que está dentro del contenedor, puede ejecutar el comando cowpy directamente y darle algunos parámetros.
Por ejemplo, la documentación de la herramienta dice que podemos cambiar el personaje ('cowacter') con -c.
Salida del comando
Ahora la salida muestra al pingüino de Linux, Tux, en lugar de la vaca predeterminada, porque especificamos el parámetro -c tux.
Debido a que está dentro del contenedor, puede ejecutar el comando cowpy tantas veces como desee, variando los parámetros de entrada, sin tener que preocuparse por los comandos de Docker.
Consejo
Use la bandera '-c' para elegir un personaje diferente, incluyendo:
beavis, cheese, daemon, dragonandcow, ghostbusters, kitty, moose, milk, stegosaurus, turkey, turtle, tux
Esto es genial. Lo que sería aún más genial es si pudiéramos alimentar nuestro greetings.csv como entrada en esto.
Pero como no tenemos acceso al sistema de archivos, no podemos.
Arreglemos eso.
1.3.3. Salir del contenedor¶
Para salir del contenedor, puede escribir exit en el prompt o usar el atajo de teclado Ctrl+D.
Su prompt ahora debería volver a lo que era antes de iniciar el contenedor.
1.3.4. Montar datos en el contenedor¶
Como se señaló anteriormente, el contenedor está aislado del sistema host de forma predeterminada.
Para permitir que el contenedor acceda al sistema de archivos del host, puede montar un volumen desde el sistema host en el contenedor usando la siguiente sintaxis:
En nuestro caso, <ruta_externa> será el directorio de trabajo actual, por lo que podemos usar simplemente un punto (.), y <ruta_interna> es solo un alias que inventamos; llamémoslo /my_project (la ruta interna debe ser absoluta).
Para montar un volumen, reemplazamos las rutas y agregamos el argumento de montaje de volumen al comando docker run de la siguiente manera:
docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash
Esto monta el directorio de trabajo actual como un volumen que será accesible bajo /my_project dentro del contenedor.
Puede verificar que funciona listando el contenido de /my_project:
Salida del comando
Ahora puede ver el contenido del directorio de trabajo desde dentro del contenedor, incluyendo el archivo greetings.csv bajo data/.
Esto efectivamente estableció un túnel a través de la pared del contenedor que puede usar para acceder a esa parte de su sistema de archivos.
1.3.5. Usar los datos montados¶
Ahora que hemos montado el directorio de trabajo en el contenedor, podemos usar el comando cowpy para mostrar el contenido del archivo greetings.csv.
Para hacer esto, usaremos cat /my_project/data/greetings.csv | para canalizar el contenido del archivo CSV al comando cowpy.
Salida del comando
____________________
/ Hello,English,123 \
| Bonjour,French,456 |
\ Holà,Spanish,789 /
--------------------
\ ,+*^^*+___+++_
\ ,*^^^^ )
\ _+* ^**+_
\ +^ _ _++*+_+++_, )
_+^^*+_ ( ,+*^ ^ \+_ )
{ ) ( ,( ,_+--+--, ^) ^\
{ (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ )
{:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) /
( / ( ( ,___ ^*+_+* ) < < \
U _/ ) *--< ) ^\-----++__) ) ) )
( ) _(^)^^)) ) )\^^^^^))^*+/ / /
( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^
( ,/ (^))^)) ) ) ))^^^^^^^))^^) _)
*+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^
\ \_)^)_)) ))^^^^^^^^^^))^^^^)
(_ ^\__^^^^^^^^^^^^))^^^^^^^)
^\___ ^\__^^^^^^))^^^^^^^^)\\
^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\
___) >____) >___ ^\_\_\_\_\_\_\)
^^^//\\_^^//\\_^ ^(\_\_\_\)
^^^ ^^ ^^^ ^
¡Esto produce el arte ASCII deseado de un pavo recitando nuestros saludos de ejemplo! Excepto que aquí el pavo está repitiendo las filas completas en lugar de solo los saludos. ¡Ya sabemos que nuestro workflow de Nextflow hará un mejor trabajo!
Siéntase libre de jugar con este comando. Cuando haya terminado, salga del contenedor como anteriormente:
Se encontrará de vuelta en su shell normal.
Conclusión¶
Sabe cómo extraer un contenedor y ejecutarlo ya sea como un comando único o de forma interactiva. También sabe cómo hacer que sus datos sean accesibles desde dentro de su contenedor, lo que le permite probar cualquier herramienta que le interese con datos reales sin tener que instalar ningún software en su sistema.
¿Qué sigue?¶
Aprenda cómo usar contenedores para la ejecución de procesos de Nextflow.
2. Usar contenedores en Nextflow¶
Nextflow tiene soporte integrado para ejecutar procesos dentro de contenedores para permitirle ejecutar herramientas que no tiene instaladas en su entorno de cómputo. Esto significa que puede usar cualquier imagen de contenedor que desee para ejecutar sus procesos, y Nextflow se encargará de extraer la imagen, montar los datos y ejecutar el proceso dentro de ella.
Para demostrar esto, vamos a agregar un paso de cowpy al pipeline que hemos estado desarrollando, después del paso collectGreetings.
2.1. Escribir un módulo cowpy¶
Primero, creemos el módulo del proceso cowpy.
2.1.1. Crear un archivo stub para el nuevo módulo¶
Cree un archivo vacío para el módulo llamado cowpy.nf.
Esto nos da un lugar para poner el código del proceso.
2.1.2. Copiar el código del proceso cowpy en el archivo del módulo¶
Podemos modelar nuestro proceso cowpy en los otros procesos que hemos escrito anteriormente.
| modules/cowpy.nf | |
|---|---|
El proceso espera un input_file que contiene los saludos así como un valor character.
La salida será un nuevo archivo de texto que contiene el arte ASCII generado por la herramienta cowpy.
2.2. Agregar cowpy al workflow¶
Ahora necesitamos importar el módulo y llamar al proceso.
2.2.1. Importar el proceso cowpy en hello-containers.nf¶
Inserte la declaración de importación arriba del bloque workflow y complétela apropiadamente.
Ahora el módulo cowpy está disponible para usar en el workflow.
2.2.2. Agregar una llamada al proceso cowpy en el workflow¶
Conectemos el proceso cowpy() a la salida del proceso collectGreetings(), que como recordará produce dos salidas:
collectGreetings.out.outfilecontiene el archivo de salida <--lo que queremoscollectGreetings.out.reportcontiene el archivo de reporte con el conteo de saludos por lote
En el bloque workflow, haga el siguiente cambio de código:
Note que declaramos un nuevo parámetro CLI, params.character, para especificar qué personaje queremos que diga los saludos.
2.2.3. Agregar el parámetro character al bloque params¶
Esto es técnicamente opcional pero es la práctica recomendada y es una oportunidad para establecer un valor predeterminado para el personaje mientras lo hacemos.
Ahora podemos ser perezosos y omitir escribir el parámetro de personaje en nuestras líneas de comando.
2.2.4. Actualizar las salidas del workflow¶
Necesitamos actualizar las salidas del workflow para publicar la salida del proceso cowpy.
2.2.4.1. Actualizar la sección publish:¶
En el bloque workflow, haga el siguiente cambio de código:
El proceso cowpy solo produce una salida, por lo que podemos referirnos a ella de la manera habitual agregando .out.
Pero por ahora, terminemos de actualizar las salidas a nivel de workflow.
2.2.4.2. Actualizar el bloque output¶
Necesitamos agregar la salida final cowpy_art al bloque output. Mientras lo hacemos, también editemos los destinos de publicación ya que ahora nuestro pipeline está completo y sabemos qué salidas realmente nos importan.
En el bloque output, haga los siguientes cambios de código:
Ahora las salidas publicadas estarán un poco más organizadas.
2.2.5. Ejecutar el workflow¶
Solo para recapitular, esto es lo que estamos buscando:
¿Cree que va a funcionar?
Eliminemos las salidas publicadas anteriores para tener un estado limpio, y ejecutemos el workflow con la bandera -resume.
Salida del comando (editada para claridad)
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 no, hay un error!
El código de error dado por error exit status (127) significa que el ejecutable que solicitamos no se encontró.
Eso tiene sentido, ya que estamos llamando a la herramienta cowpy pero aún no hemos especificado un contenedor (ups).
2.3. Usar un contenedor para ejecutar el proceso cowpy¶
Necesitamos especificar un contenedor y decirle a Nextflow que lo use para el proceso cowpy().
2.3.1. Especificar un contenedor para cowpy¶
Podemos usar la misma imagen que estábamos usando directamente en la primera sección de este tutorial.
Edite el módulo cowpy.nf para agregar la directiva container a la definición del proceso de la siguiente manera:
| modules/cowpy.nf | |
|---|---|
Esto le dice a Nextflow que si el uso de Docker está habilitado, debe usar la imagen de contenedor especificada aquí para ejecutar el proceso.
2.3.2. Habilitar el uso de Docker a través del archivo nextflow.config¶
Note que dijimos 'si el uso de Docker está habilitado'. De forma predeterminada, no lo está, por lo que necesitamos decirle a Nextflow que está permitido usar Docker. Para ese fin, vamos a anticipar ligeramente el tema de la siguiente y última parte de este curso (Parte 6), que cubre la configuración.
Una de las principales formas que Nextflow ofrece para configurar la ejecución del workflow es usar un archivo nextflow.config.
Cuando tal archivo está presente en el directorio actual, Nextflow lo cargará automáticamente y aplicará cualquier configuración que contenga.
Proporcionamos un archivo nextflow.config con una sola línea de código que deshabilita explícitamente Docker: docker.enabled = false.
Ahora, cambiemos eso a true para habilitar Docker:
Consejo
Es posible habilitar la ejecución de Docker desde la línea de comandos, por ejecución, usando el parámetro -with-docker <container>.
Sin embargo, eso solo nos permite especificar un contenedor para todo el workflow, mientras que el enfoque que acabamos de mostrarle nos permite especificar un contenedor diferente por proceso.
Esto es mejor para la modularidad, el mantenimiento del código y la reproducibilidad.
2.3.3. Ejecutar el workflow con Docker habilitado¶
Ejecute el workflow con la bandera -resume:
Salida del 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 ✔
¡Esta vez sí funciona! Como de costumbre, puede encontrar las salidas del workflow en el directorio de resultados correspondiente, aunque esta vez están un poco más ordenadas, con solo el reporte y la salida final en el nivel superior, y todos los archivos intermedios guardados en un subdirectorio.
Contenido del directorio
La salida final de arte ASCII está en el directorio results/hello_containers/, bajo el nombre cowpy-COLLECTED-batch-output.txt.
Contenido del archivo
_________
/ HOLà \
| HELLO |
\ BONJOUR /
---------
\ ,+*^^*+___+++_
\ ,*^^^^ )
\ _+* ^**+_
\ +^ _ _++*+_+++_, )
_+^^*+_ ( ,+*^ ^ \+_ )
{ ) ( ,( ,_+--+--, ^) ^\
{ (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ )
{:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) /
( / ( ( ,___ ^*+_+* ) < < \
U _/ ) *--< ) ^\-----++__) ) ) )
( ) _(^)^^)) ) )\^^^^^))^*+/ / /
( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^
( ,/ (^))^)) ) ) ))^^^^^^^))^^) _)
*+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^
\ \_)^)_)) ))^^^^^^^^^^))^^^^)
(_ ^\__^^^^^^^^^^^^))^^^^^^^)
^\___ ^\__^^^^^^))^^^^^^^^)\\
^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\
___) >____) >___ ^\_\_\_\_\_\_\)
^^^//\\_^^//\\_^ ^(\_\_\_\)
^^^ ^^ ^^^ ^
Y ahí está, nuestro hermoso pavo diciendo los saludos como se deseaba.
2.3.4. Inspeccionar cómo Nextflow lanzó la tarea en contenedor¶
Como coda final de esta sección, echemos un vistazo al subdirectorio de trabajo para una de las llamadas al proceso cowpy para obtener un poco más de información sobre cómo funciona Nextflow con contenedores bajo el capó.
Verifique la salida de su comando nextflow run para encontrar la ruta al subdirectorio de trabajo para el proceso cowpy.
Mirando lo que obtuvimos para la ejecución mostrada arriba, la línea de registro de consola para el proceso cowpy comienza con [98/656c6c].
Eso corresponde a la siguiente ruta de directorio truncada: work/98/656c6c.
En ese directorio, encontrará el archivo .command.run que contiene todos los comandos que Nextflow ejecutó en su nombre en el curso de ejecutar el pipeline.
Contenido del archivo
#!/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
Si busca nxf_launch en este archivo, debería ver algo como esto:
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 puede ver, Nextflow está usando el comando docker run para lanzar la llamada al proceso.
También monta el subdirectorio de trabajo correspondiente en el contenedor, establece el directorio de trabajo dentro del contenedor en consecuencia y ejecuta nuestro script bash con plantilla en el archivo .command.sh.
¿Todo el trabajo duro que tuvimos que hacer manualmente en la primera sección? ¡Nextflow lo hace por nosotros detrás de escena!
_______________________
< Hurray for robots...! >
-----------------------
,-----.
| |
,--| |-.
__,----| | | |
,;:: | `_____' |
`._______| i^i |
`----| |---'| .
,-------._| |== ||//
| |_|P`. /'/
`-------' 'Y Y/'/'
.==\ /_\
^__^ / /'| `i
(oo)\_______ /' / | |
(__)\ )\/\ /' / | `i
||----w | ___,;`----'.___L_,-'`\__
|| || i_____;----\.____i""\____\
Conclusión¶
Sabe cómo usar contenedores en Nextflow para ejecutar procesos.
¿Qué sigue?¶
¡Tome un descanso!
Cuando esté listo, continúe con Parte 6: Hello Config para aprender cómo configurar la ejecución de su pipeline para que se ajuste a su infraestructura, así como gestionar la configuración de entradas y parámetros.
¡Es la última parte, y luego habrá terminado con este curso!
Cuestionario¶
¿Qué es un contenedor?
¿Cuál es la diferencia entre una imagen de contenedor y una instancia de contenedor?
¿Qué hace la bandera -v en un comando docker run?
¿Por qué necesita montar volúmenes al usar contenedores?
¿Cómo se especifica un contenedor para un proceso de Nextflow?
¿Qué configuración de nextflow.config habilita Docker para su workflow?
¿Qué maneja automáticamente Nextflow al ejecutar un proceso en un contenedor? (Seleccione todas las que apliquen)