Introducción
Un servicio de informes necesita leer configuración y escribir documentos, pero su montaje de configuración también permite escrituras. Como responsable de mantenimiento, reducirás ese acceso innecesario sin romper la generación de informes.
Primero generarás un informe normal, protegerás su montaje de entrada y recrearás únicamente el contenedor de informes. Basta con conocimientos básicos de terminal; Docker, la sintaxis de montaje y la edición se explican antes de utilizarlos.
Generar un informe normal
En este paso ejecutarás la tarea empresarial normal antes de cambiar permisos. Harbor Books utiliza un pequeño servicio para sumar pedidos y producir un documento. Todos los clientes y números son datos sintéticos de formación.
Utiliza la terminal Maintenance, un rol de mantenimiento del host Linux con acceso de administración de Docker. Docker inicia procesos en contenedores: cada uno ve su propio sistema de archivos y lista de procesos, pero comparte el núcleo del host. Un contenedor no es otra VM. Administra solo report-renderer y los archivos de /home/labex/project/report-desk.
La terminal comienza en ese directorio. pwd muestra el directorio actual:
pwd
Debe mostrar /home/labex/project/report-desk. Si cambiaste de directorio, vuelve con cd /home/labex/project/report-desk.
La aplicación escucha en el puerto 8090. Un puerto identifica un servicio; aquí localhost es el host de mantenimiento, cuyo puerto Docker reenvía al contenedor. curl envía una petición HTTP, -X POST selecciona una petición de acción y -fsS muestra errores con una salida de éxito concisa. Solicita el documento inicial:
curl -fsS -X POST http://localhost:8090/render/baseline
{"saved": "/output/baseline.json", "total": 37, "uid": 0}
El servicio leyó la entrada y guardó un archivo real. cat muestra un archivo; el host ve /output del contenedor como su directorio local output:
cat output/baseline.json
Busca Report for Harbor Books: 37 orders. Los demás campos registran la identidad de la entrada y la instancia del servicio. Abre Document Desk y actualiza: baseline.json aparece bajo Stored documents. La página enumera archivos reales; no certifica que los permisos sean seguros.
Proteger la declaración de entrada
En este paso relacionarás las rutas de entrada y salida, demostrarás una escritura innecesaria y editarás la declaración de inicio. Un montaje bind conecta un directorio del host con una ruta del contenedor. Es escribible salvo que se restrinja explícitamente.
cat launch.sh muestra el script Bash preparado:
cat launch.sh
La barra inversa continúa el comando en la siguiente línea. sudo administra Docker con permisos del administrador del host; no determina el usuario de la aplicación. docker run -d inicia un contenedor en segundo plano, --name lo identifica, --user 0:0 selecciona los identificadores de usuario/grupo y -p 8090:8090 reenvía el puerto del host al del contenedor. El último argumento es la imagen preparada c12-renderer:1.
Cada --mount tiene campos separados por comas: type=bind conecta una ruta del host, src es esa ruta y dst es la ruta del contenedor.
| Directorio del host | Directorio del contenedor | Acceso necesario |
|---|---|---|
report-desk/config |
/config |
Leer lote y plantilla |
report-desk/output |
/output |
Escribir documentos generados |
La configuración contiene probe.txt, una muestra desechable sin datos empresariales. docker exec ejecuta un comando dentro del contenedor en marcha indicado. touch actualiza la fecha de esa muestra: es un acceso innecesario deliberado.
sudo docker exec report-renderer touch /config/probe.txt
La ausencia de salida indica éxito. Demuestra que el montaje es escribible sin dañar lote ni plantilla. Proteger la declaración del host cambia lo que Docker creará después; editar un archivo dentro del contenedor actual no cambia su modo de montaje.
Utiliza el editor de terminal nano para modificarla:
nano launch.sh
Muévete con las flechas. En la línea con dst=/config, añade ,readonly justo después de /config, antes del espacio y la barra inversa. Conserva /output escribible. Guarda con Ctrl+O, Enter y sal con Ctrl+X. La línea debe quedar así:
--mount type=bind,src=/home/labex/project/report-desk/config,dst=/config,readonly \
Vuelve a mostrar cat launch.sh para detectar comas o barras inversas omitidas. Reabre nano launch.sh para corregir errores. El contenedor sigue usando el montaje antiguo; lo reemplazarás en el siguiente paso.
Aplicar y probar el límite del montaje
En este paso reemplazarás solo el contenedor de informes y demostrarás que rechazar escrituras de entrada es compatible con una salida funcional. Cambiar el script no actualiza un contenedor existente.
docker rm -f detiene y elimina el contenedor indicado. Los directorios del host montados mediante bind sobreviven. bash launch.sh ejecuta la declaración editada:
sudo docker rm -f report-renderer
bash launch.sh
El segundo comando imprime un ID nuevo. Espera un momento al inicio. Si informa de un error de sintaxis o montaje, corrige la línea con nano launch.sh, elimina cualquier report-renderer recién creado con el mismo comando y vuelve a ejecutar el script. No borres los directorios de datos del host.
docker inspect lee la configuración real. --format selecciona un campo; conserva las comillas simples para que el shell pase las llaves sin cambios:
sudo docker inspect report-renderer --format '{{json .Mounts}}'
Busca "Destination":"/config" con "RW":false, y /output con "RW":true. RW significa lectura/escritura. Comprueba el límite real con la misma muestra:
sudo docker exec report-renderer touch /config/probe.txt
touch: /config/probe.txt: Read-only file system
Esta salida distinta de cero es esperada. La terminal sigue disponible; continúa con el siguiente comando. Un error de conexión o un contenedor inexistente es diferente: debes corregir o reiniciar el script.
Solicita un documento nuevo al servicio recreado:
curl -fsS -X POST http://localhost:8090/render/final
{"saved": "/output/final.json", "total": 37, "uid": 0}
cat output/final.json
El documento sigue diciendo Report for Harbor Books: 37 orders. Actualiza Document Desk para ver final.json. El servicio lee sus entradas y escribe salidas, mientras el montaje de configuración rechaza escrituras. Sigue ejecutándose como root; el siguiente laboratorio independiente aborda ese permiso por separado.
Resumen
Generaste un informe real, relacionaste rutas del host y del contenedor, protegiste el montaje de entrada como solo lectura y recreaste el servicio. La inspección del montaje y una escritura rechazada confirmaron la protección; un informe nuevo confirmó que la salida seguía funcionando.



