Este es un ejemplo de *Dockerfile*`multi-stage`. En un *Dockerfile* de tipo `multi-stage` cada `FROM` (puede haber varios) usa la base que quieras para abrir una nueva etapa (*stage*) Se pueden copiar artefactos de una etapa anterior de forma selectiva.
FROM alpine:3.15 AS builder
- En la primera etapa, que llamaremos `builder` partimos de la imagen `alpine:3.20.1`
- Instalamos:
- `pcre`, una biblioteca de expresiones regulares
- `libxml2`
- `libxslt`
- `gcc`, el compilador gnu
- `make`, la herramienta
- `libc-dev`
- `pcre-dev`
- `zlib-dev`
- `libxml2-dev`
- `libxslt-dev`
- Descargamos el código de *nginx* en el directorio `/tmp` y lo descomprimimos
- Ejecutamos `autoconfigure` especificando que se instale en `/opt`
- Compilamos con `make` e instalamos con `make install`
- Desinstalamos la bibliotecas y borramos la caché (aunque no creo que esto valga para nada, hasta donde yo entiendo la etapa `builder` se descarta)
La segunda etapa empieza en la linea 24 definiendo un par de variables para establecer en `UID` y el `GID` del usuario `www-data` que usaremos dentro del contenedor `nginx` para ejecutar el servidor.
- Instalamos las bibliotecas:
- `pcre`
- `libxml2`
- `libxslt`
- `tini`, un micro `init` ideal para implementar contenedores ligeros
- `shadow`, el PAM de Alpine
- Limpiamos la caché de instalación de paquetes
- Cambiamos el `GID`para el grupo `www-data`
- Creamos el usuario `www-data` con el `UID` especificado
- Creamos el directorio `/html`
- Copiamos los ejecutables de *nginx* de la etapa anterior
- Copiamos el `nginx.conf` y el `entrypoint.sh` desde el directorio de trabajo del *Dockerfile*
- Declaramos el puerto de acceso y el volumen correspondiente a `/html`
- Ejecutamos como usuario `www-data` el *entrypoint* del contenedor.
##### Ficheros auxiliares
**entrypoint**
El fichero `entrypoint` que hemos usado es muy simple:
```bash
#!/bin/bash
mediaowner=$(ls -ld /html | awk '{print $3}')
echo "Current /html owner is $mediaowner"
/opt/nginx/sbin/nginx -g "daemon off;"
```
El fichero `nginx.conf` tampoco es muy complicado. Dejamos secciones comentadas para tener algunas referencias.
```nginx
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8080;
server_name localhost;
access_log /dev/stdout;
error_log /dev/stdout info;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /html;
index index.html index.htm;
include mime.types;
try_files $uri $uri/ =404;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
- [Debugging an Array](https://community.st.com/t5/stm32cubemonitor-mcus/how-to-watch-an-array-using-stm32cubemonitor/td-p/225086)
- [Trasmitting Structures via USB](https://medium.com/vicara-hardware-university/a-guide-to-transmitting-structures-using-stm32-uart-and-python-56b67f806566)