Ejecutando Python en un contenedor Docker

En muchas ocasiones queremos que nuestras aplicaciones en Python estén dentro de un contenedor Docker para que sea más sencillo su despliegue.

Partamos de la base que tenemos un programa en Python muy sencillo, donde solo tenemos la dependencia de algunos módulos, no tenemos necesidad de utilizar una base de datos y solo requerimos de un archivo jpg (descarguen el archivo en la carpeta del proyecto); el cual utilizaremos como input de nuestro programa.

El programa que utilizaremos de ejemplo sera el siguiente:

Requiere de los modulos de Pillow, termcolor y colorama para trabajar; para poder utilizarlos dentro de Docker, crearemos un archivo llamado requirements.txt en la misma carpeta del programa, con el listado de modulos requeridos.

Luego debemos crear en la misma carpeta un archivo llamado dockerfile:

Una vez que tengamos todo; debemos construir el contenedor, ejecutando desde la terminal:

docker image build --tag testpy .

Esto demora unos instantes, debe descargar la imagen de docker con Python, luego copia los archivos de Python y descarga los módulos indicados en el archivo requierements.txt

Cuando termina, podemos validar que se construyo la imagen, ejecutando en la consola:

docker image ls

Obtendremos una vista como la siguiente:

Por ultimo, ejecutamos nuestro contenedor que tiene nuestro programa en Python, de la siguiente manera:

docker run --rm testpy

Convirtiendo un programa de Python en un servicio

Hace no mucho necesite que un programa en escrito en python se ejecutara en una Raspberry Pi al inicio, es decir, ni bien booteara el sistema operativo iniciara el programa.

La forma mas adecuada fue hacerlo por medio de systemctl definiendo algunos parámetros.

Por supuesto que el programa debe tener algún tipo de bucle que mantenga el hilo activo; de lo contrario se va a ejecutar una sola vez y concluirá.

Para los fines del ejemplo, voy a utilizar ServerHotKeys.py que escucha el puerto serie y si llega ciertos caracteres reproduce un archivo mp3.

Este programa lo pueden encontrar en el siguiente repositorio: https://github.com/gsampallo/hotkeys_server

El ejemplo lo realizo sobre una raspberry pi 3 con rasbian. El primer paso será clonar el repositorio:

git clone https://github.com/gsampallo/hotkeys_server

Nos quedara el proyecto en la ruta /home/pi/hotkeys_server.

El siguiente paso será crear un archivo bash, al cual llamaremos start.sh que ejecute el programa:

#!/bin/bash
cd /home/pi/hotkeys_server
python3 ServerHotKeys.py

Debemos dar permiso de ejecución sobre el archivo, lo hacemos con:

chmod +x start.sh

Luego debemos crear un archivo al que llamaremos ServerHotKeys.service, que contendrá las características del servicio, su contenido sera el siguiente:

[Unit]
Description=ServerHotKeys Service
After=multi-user.target
 
[Service]
Type=idle
ExecStart=bash /home/pi/hotkeys_server/start.sh
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=ServiceHotKeys

[Install]
WantedBy=multi-user.target

Luego debemos crear un nuevo archivo con la configuración, al cual llamaremos ServerHotKeys.conf que contendra lo siguiente:

if $programname=='ServiceHotKeys' then /home/pi/hotkeys_server/log/ServiceHotKeys.log & stop

De modo de ir almacenando en la carpeta log dentro de hotkeys_server los archivos de log del servicio; no olvidar de verificar que exista este directorio, en caso que no este crearlo.

Copiamos ambos archivos a la ruta correspondiente:

sudo cp ServiceHotKeys.service /lib/systemd/system/
sudo cp ServiceHotKeys.conf /etc/rsyslog.d/

Cambiamos los permisos sobre el service:

sudo chmod 644 /lib/systemd/system/ServiceHotKeys.service

Luego debemos recargar el demonio para que tome el nuevo servicio, habilitarlo y por ultimo iniciarlo para que quede corriendo.

sudo systemctl daemon-reload

sudo systemctl enable ServiceHotKeys.service
sudo systemctl restart rsyslog

sudo systemctl start ServiceHotKeys.service

De esta forma queda habilitado el servicio para que siempre se ejecute al iniciarse la Raspberry Pi.

Tener en cuenta que el programa que tome de ejemplo, utiliza el puerto serie de la pc y tiene algunas dependencias, por lo que puede que no funcione; pero es posible tomarlo como ejemplo y construir su propio servicio en base a este.