Introducción
Pine & Path va a enviar su guía de visitantes de Alder Ridge a otro centro de visitantes. La imagen actual funciona, pero incluye el compilador de Go, los archivos fuente y los restos de compilación junto con la aplicación. Entrega una imagen de ejecución ligera que conserve los cuatro senderos, los filtros de dificultad, las páginas de detalles, las ilustraciones locales y las descargas completas de rutas GPX.
Ya debes saber crear y ejecutar una imagen sencilla de Docker y reconocer FROM, COPY y la publicación de puertos en un Dockerfile. No necesitas programar en Go: se proporcionan la aplicación completa y sus materiales. Este laboratorio explica la compilación, las etapas de construcción, la disposición de archivos de ejecución y la sintaxis del shell para escribir archivos antes de usarlas. El parque y los datos de las rutas son materiales didácticos ficticios.
Docker, la imagen de compilación y el servicio de referencia proporcionado están listos. Usa Workstation para los comandos, Reference Guide para el ejemplo funcional y Your Guide para tu entrega. Este laboratorio es independiente del desafío. Calcula unos 60 minutos, incluidos la lectura, las compilaciones y los errores habituales; es una estimación del autor.
Construye la imagen inicial funcional
En este paso, comprobarás qué hace una guía completa y construirás la imagen inicial proporcionada. Empieza en Reference Guide. Muestra cuatro senderos. Selecciona Easy, abre Cedar Loop, lee su distancia y desnivel y usa Download GPX. GPX es XML que contiene un recorrido con nombre y puntos geográficos; esta descarga es un archivo de ruta real. Selecciona Back to trails, después Moderate, y abre Ridge Path. Vuelve a todos los senderos. Observa la hoja de estilos y el mapa esquemático, además del texto: también son recursos de ejecución.

Cambia a Workstation, que comienza en /home/labex/project/trail-guide. pwd muestra el directorio actual y ls enumera las entradas. Si sales del proyecto, el siguiente cd vuelve a él:
cd /home/labex/project/trail-guide
ls
La estructura proporcionada es:
| Ruta fuente | Finalidad durante la ejecución |
|---|---|
app/main.go |
Programa Go que se compila; no se necesita su código fuente durante la ejecución |
content/trails.json |
Los cuatro senderos y sus relaciones |
content/routes/ |
Las cuatro descargas GPX |
public/ |
Hoja de estilos e ilustraciones esquemáticas originales |
author-notes/, build-cache/ |
Borradores y restos, no recursos de ejecución |
Conserva estos materiales y el servicio de referencia sin cambios. Editarás Dockerfile, añadirás .dockerignore y crearás imágenes y contenedores del curso. Dockerfile.incomplete es un ejemplo de fallo proporcionado para el paso siguiente.
cat muestra un archivo de texto. Lee el Dockerfile existente:
cat Dockerfile
Parte de dk02-go-builder:1, una imagen preparada del compilador de Go. WORKDIR /guide selecciona el directorio de trabajo dentro de la imagen. COPY . . copia el contexto de construcción actual en ese directorio, incluidos archivos que la aplicación final no necesita. El último ENTRYPOINT es un arreglo JSON que inicia directamente el programa compilado.
El comando de compilación establece CGO_ENABLED=0 solo para ese comando, de modo que este ejemplo de Go, que usa la biblioteca estándar, no requiera bibliotecas de C. go build compila el programa suministrado; -trimpath elimina del ejecutable los detalles del directorio fuente local y -o /guide/guide le asigna nombre. Esto permite que este programa concreto use una base de ejecución vacía. Otros programas pueden necesitar bibliotecas compartidas, certificados u otros datos; una base vacía no es una solución universal.
Primero consulta la versión del compilador. docker run --rm crea un contenedor temporal y lo elimina al terminar el comando. Las palabras después del nombre de la imagen seleccionan el comando que se ejecutará:
docker run --rm dk02-go-builder:1 go version
La salida identifica Go 1.26 en Linux. Esto ejecuta el compilador en un contenedor, no en Workstation.
Construye la imagen inicial. docker build lee el Dockerfile; -t asigna una etiqueta al resultado y el . final selecciona el directorio actual como contexto de construcción:
docker build -t trail-guide:sample .
Espera el resultado satisfactorio. La etiqueta identifica una imagen, no un contenedor en ejecución. Para consultar su tamaño en bytes, docker image inspect lee los metadatos y --format selecciona un campo. Las comillas simples pasan la plantilla literalmente:
docker image inspect trail-guide:sample --format '{{.Size}}'
El número varía según la imagen preparada del compilador. La imagen inicial funciona, pero aún incluye el compilador y el código fuente. Un tamaño pequeño por sí solo no demostrará que su sustituta esté completa.
Separa los archivos de compilación y de ejecución
En este paso, compilarás el programa en una etapa y entregarás solo su ejecutable y sus recursos de ejecución en otra. Empieza en Workstation, en el mismo directorio del proyecto. Una etapa comienza con una instrucción FROM. Nombrarla con AS build permite que un COPY --from=build posterior tome un resultado sin heredar el compilador ni las capas anteriores del sistema de archivos.
Primero examina una entrega incompleta real. El Dockerfile.incomplete proporcionado compila el programa y copia las ilustraciones públicas, pero omite los datos de los senderos:
cat Dockerfile.incomplete
La opción -f selecciona este Dockerfile alternativo:
docker build -f Dockerfile.incomplete -t trail-guide:incomplete .
La construcción termina correctamente porque la compilación no lee la colección de senderos. Se espera deliberadamente que la siguiente ejecución falle con estado de salida 1:
docker run --rm trail-guide:incomplete
Lee el error: open content/trails.json: no such file or directory. El ejecutable existe, pero faltan sus datos de ejecución. Una construcción correcta y una aplicación completa son resultados distintos. El contenedor temporal que falló ya se eliminó. Corrige el Dockerfile normal, en lugar de reparar ese contenedor o cambiar la aplicación.
Un here-document guarda un bloque de texto completo. Abajo, cat proporciona las líneas, > escribe Dockerfile y <<'DOCKERFILE' marca un bloque literal que termina en una línea que contiene únicamente DOCKERFILE. Las comillas del marcador inicial impiden que el shell expanda el contenido al guardarlo. Sustituye solo el Dockerfile editable:
cat > Dockerfile <<'DOCKERFILE'
FROM dk02-go-builder:1 AS build
WORKDIR /src
COPY app/main.go ./main.go
RUN CGO_ENABLED=0 go build -trimpath -o /out/guide main.go
FROM scratch
WORKDIR /guide
COPY --from=build /out/guide ./guide
COPY content/ ./content/
COPY public/ ./public/
ENTRYPOINT ["/guide/guide"]
DOCKERFILE
Sigue los archivos: la primera etapa compila el código fuente en /out/guide. El segundo FROM parte de scratch, la base de sistema de archivos vacía de Docker, sin heredar la primera etapa. El ejecutable pasa a ser /guide/guide; los datos de los senderos y archivos GPX conservan su estructura content; los estilos y las ilustraciones conservan su estructura public. El programa lee estas rutas relativas desde su directorio de trabajo. Por eso no bastaba con copiar solo el ejecutable.
La imagen final no tiene shell ni compilador. Aquí es lo esperado. Inspecciona su aplicación en lugar de intentar ejecutar un shell dentro de ella.
El contexto de construcción es una cuestión aparte. .dockerignore excluye las rutas coincidentes del contexto antes de enviarlas al constructor. Un punto inicial convierte este nombre en un archivo oculto. Estas reglas omiten borradores y caché obsoleta sin omitir la aplicación ni sus recursos de ejecución:
cat > .dockerignore <<'IGNORE'
author-notes/
build-cache/
IGNORE
El Dockerfile de dos etapas selecciona explícitamente los archivos de ejecución; el archivo de exclusión también evita enviar material innecesario. Excluir un archivo del contexto no puede eliminar bytes ya almacenados en capas heredadas. La etapa de ejecución separada es lo que deja atrás las capas de compilación.
Construye la imagen de entrega:
docker build -t trail-guide:lean .
docker image inspect trail-guide:lean --format '{{.Size}}'
Compara el tamaño con el de la muestra. El resultado útil es un entorno de ejecución más pequeño con una guía completa, no el menor número posible. Si falla un COPY, lee qué ruta fuente falta y compárala con la tabla de estructura y el directorio actual. Corrige el Dockerfile o la regla de exclusión y vuelve a construir. No crees datos sustitutos ni montes la carpeta fuente para ocultar una imagen incompleta.
Ejecuta y recrea la guía entregada
En este paso, ejecutarás la imagen con independencia de la carpeta fuente y usarás la guía completa. Empieza en Workstation. El programa escucha en el puerto 8080 del contenedor. Publicar 8090:8080 permite acceder a él en el puerto 8090 de Workstation, que muestra Your Guide. -d deja el servidor en segundo plano; --name asigna un nombre a este contenedor del curso. No añadas montajes: la imagen debe contener sus propios recursos.
docker run -d --name trail-guide -p 8090:8080 trail-guide:lean
La salida es un ID de contenedor. Este contenedor sigue en ejecución para servir la guía. docker logs lee la salida del programa; --tail 5 la limita a las cinco últimas líneas:
docker logs --tail 5 trail-guide
Espera Guide listening on :8080, el puerto del contenedor en vez del puerto publicado en el host. Si el nombre del contenedor ya está en uso por un intento anterior, usa el comando de eliminación limitado al curso que aparece abajo y repite el comando de inicio. Un error de recurso ausente exige corregir el Dockerfile y reconstruir primero.
Cambia a Your Guide y recarga. Deben aparecer los cuatro senderos. Selecciona Easy: solo aparecen Cedar Loop y River Walk. Abre Cedar Loop, inspecciona sus datos y mapa y descarga su GPX. Usa Back to trails, elige Moderate, abre Ridge Path y descarga también esa ruta. Vuelve a todos los senderos. Las ilustraciones y los estilos locales deben cargarse y los recorridos deben corresponder a los senderos seleccionados. Reference Guide sigue disponible de forma independiente.

Ahora demuestra que puedes sustituir el contenedor usando la misma imagen. Cambia a Workstation. docker rm -f detiene y elimina únicamente el contenedor del curso nombrado; no elimina la imagen. Mantén dk02-reference en ejecución:
docker rm -f trail-guide
Crea una instancia nueva sin montajes:
docker run -d --name trail-guide -p 8090:8080 trail-guide:lean
Cambia a Your Guide, recarga y repite las visitas y descargas de Easy/Cedar Loop y Moderate/Ridge Path. Este nuevo contenedor nunca recibió la carpeta fuente de la estación de trabajo. Su entorno de ejecución procede de la imagen.
Mantén el contenedor en ejecución. Tras futuros cambios del Dockerfile, reconstruir una etiqueta no actualiza un contenedor existente; elimina y recrea solo tu contenedor del curso para ejecutar la nueva imagen. Un servicio detenido o un fallo de conexión es diferente de la página Trail not found de la propia guía para una ruta desconocida.
Resumen
Separaste una etapa de compilación de una etapa de ejecución vacía, copiaste los recursos reales que necesita la aplicación y excluiste los borradores del contexto de construcción. Tu imagen ligera sirve la colección completa, los filtros, los detalles, las ilustraciones y las descargas GPX sin montajes de la estación de trabajo. Recrear su contenedor demostró que la imagen es una entrega reutilizable y no un proceso que toma prestada la carpeta fuente.



