Habilidad de Despliegue Local con Docker para Next.js
Propósito
Usa esta habilidad para construir y ejecutar una aplicación Next.js con Docker usando una etiqueta de imagen versionada.
Esta habilidad no debe codificar el nombre del proyecto. Deduce el nombre de la imagen del repositorio actual, a menos que el usuario proporcione un nombre específico.
Resolución del Nombre del Proyecto
Antes de construir, determina estos valores:
PROJECT_NAME=<nombre del proyecto resuelto>
IMAGE_NAME=<nombre de la imagen resuelto>
IMAGE_VERSION=<versión resuelta>
IMAGE_TAG=${IMAGE_NAME}:${IMAGE_VERSION}
CONTAINER_NAME=<nombre del contenedor resuelto>
ENV_FILE=<archivo env resuelto>
HOST_PORT=<puerto del host resuelto>
CONTAINER_PORT=<puerto del contenedor resuelto>
Reglas de resolución:
-
Si el usuario proporciona un nombre de imagen, úsalo.
-
De lo contrario, lee
package.jsony usa el camponame. -
Si
package.jsonno tienename, usa el nombre de la carpeta actual. -
Normaliza el nombre de la imagen:
- minúsculas
- reemplaza espacios y guiones bajos con guiones
- elimina caracteres no válidos para nombres de imágenes Docker
-
Si el usuario proporciona una versión, úsala.
-
De lo contrario, usa
1.0.0por defecto. -
Si el usuario proporciona un nombre de contenedor, úsalo.
-
De lo contrario, usa el nombre normalizado de la imagen como nombre del contenedor.
-
Si el usuario proporciona un archivo env, úsalo.
-
De lo contrario, usa
.env.productionpor defecto. -
Si el usuario proporciona puertos, úsalos.
-
De lo contrario, usa por defecto
HOST_PORT=4000yCONTAINER_PORT=3000.
Ejemplo:
package.json name: nextjs-skill-app-workshop
PROJECT_NAME=nextjs-skill-app-workshop
IMAGE_NAME=nextjs-skill-app-workshop
IMAGE_VERSION=1.0.0
IMAGE_TAG=nextjs-skill-app-workshop:1.0.0
CONTAINER_NAME=nextjs-skill-app-workshop
ENV_FILE=.env.production
HOST_PORT=4000
CONTAINER_PORT=3000
Reglas de Seguridad
Antes de ejecutar cualquier comando de construcción o ejecución:
-
Confirma que el directorio de trabajo actual es la raíz del proyecto.
-
Confirma que existe
Dockerfile. -
Confirma que existe el archivo env.
-
Confirma que Docker está instalado y en ejecución.
-
Verifica si la etiqueta de imagen solicitada ya existe localmente.
-
Verifica si el nombre del contenedor solicitado ya existe.
-
Nunca imprimas secretos del archivo env.
-
No uses la etiqueta
latesta menos que el usuario lo pida explícitamente. -
No ejecutes comandos de limpieza destructivos como:
docker system prunedocker image prunedocker volume prune
-
No detengas, elimines ni reemplaces un contenedor existente sin confirmación explícita del usuario.
-
No reconstruyas una etiqueta de versión existente a menos que el usuario lo confirme claramente.
Comprobaciones Previas
Ejecuta estas comprobaciones primero:
pwd
ls -la
test -f package.json && echo "OK: package.json encontrado" || echo "WARN: package.json no encontrado"
test -f Dockerfile && echo "OK: Dockerfile encontrado" || echo "ERROR: Dockerfile no encontrado"
test -f "$ENV_FILE" && echo "OK: archivo env encontrado: $ENV_FILE" || echo "ERROR: archivo env no encontrado: $ENV_FILE"
docker --version
docker info >/dev/null && echo "OK: El demonio Docker está en ejecución" || echo "ERROR: El demonio Docker no está en ejecución"
Si falta Dockerfile, detente e informa del problema.
Si falta el archivo env, detente e informa del problema. No crees un archivo env provisional a menos que el usuario lo pida.
Si el demonio Docker no está en ejecución, detén e indica al usuario que inicie Docker Desktop o Docker Engine.
Comandos Auxiliares Sugeridos
Para inferir el nombre de la imagen desde package.json:
node -p "require('./package.json').name"
Si package.json no existe o no tiene name, usa el nombre del directorio actual:
basename "$PWD"
Para normalizar el nombre del proyecto manualmente, usa minúsculas y kebab-case.
Ejemplo:
My Next App -> my-next-app
nextjs_skill_app -> nextjs-skill-app
Verificación de Etiqueta de Versión
Antes de construir, verifica si la etiqueta de imagen solicitada ya existe:
docker image inspect "$IMAGE_TAG" >/dev/null 2>&1 \
&& echo "EXISTE: $IMAGE_TAG" \
|| echo "DISPONIBLE: $IMAGE_TAG"
También lista las versiones locales existentes para esta imagen:
docker images "$IMAGE_NAME" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}"
Si la etiqueta de imagen solicitada ya existe:
- No ejecutes
docker build. - Informa que la versión ya existe localmente.
- Sugiere la siguiente versión de parche, por ejemplo
1.0.1. - Pregunta al usuario si desea usar una nueva versión o reconstruir explícitamente la misma etiqueta.
Solo reconstruye una etiqueta existente si el usuario lo confirma claramente.
Verificación del Nombre del Contenedor
Antes de ejecutar el contenedor, verifica si el nombre del contenedor ya existe:
docker ps -a --filter "name=^/${CONTAINER_NAME}$" \
--format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
Si ya existe un contenedor con el mismo nombre:
- No ejecutes otro contenedor con el mismo nombre.
- Informa del estado del contenedor existente.
- Pregunta al usuario si desea detenerlo/eliminarlo o usar un nombre de contenedor diferente.
- No lo elimines automáticamente.
Comando de Construcción
Si la etiqueta de imagen no existe, ejecuta:
docker build -t "$IMAGE_TAG" .
Después de la construcción, verifica que la imagen exista:
docker image inspect "$IMAGE_TAG" >/dev/null \
&& echo "OK: imagen construida exitosamente: $IMAGE_TAG" \
|| echo "ERROR: imagen no encontrada después de la construcción: $IMAGE_TAG"
Comando de Ejecución
Si la imagen existe y el nombre del contenedor está disponible, ejecuta:
docker run --restart=always -d \
--name "$CONTAINER_NAME" \
--env-file "$ENV_FILE" \
-p "${HOST_PORT}:${CONTAINER_PORT}" \
"$IMAGE_TAG"
Validación Posterior a la Ejecución
Después de ejecutar el contenedor, valida con:
docker ps --filter "name=^/${CONTAINER_NAME}$" \
--format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
docker logs --tail=80 "$CONTAINER_NAME"
curl -I "http://localhost:${HOST_PORT}"
Resultado esperado:
- El estado del contenedor debe ser
Up. - El mapeo de puertos debe incluir
${HOST_PORT}->${CONTAINER_PORT}. - Los registros no deben mostrar errores fatales.
curl -Idebe devolver una respuesta HTTP como200,301,302,307o308.
Si curl falla, inspecciona los registros e informa la causa probable.
Manejo de Fallos Comunes
La etiqueta de imagen ya existe
Informa:
La etiqueta de imagen ya existe localmente:
<IMAGE_TAG>
Acción recomendada:
- Usa una nueva versión de parche, por ejemplo 1.0.1
- O confirma explícitamente la reconstrucción de la misma etiqueta
El nombre del contenedor ya existe
Informa:
El contenedor ya existe:
<CONTAINER_NAME>
Por favor, confirma si deseas detenerlo/eliminarlo o proporciona un nombre de contenedor diferente.
Puerto ya en uso
Verifica:
lsof -i :"$HOST_PORT"
Informa el proceso que usa el puerto y pregunta si el usuario desea cambiar HOST_PORT.
Archivo env faltante
Informa:
No se encontró el archivo env:
<ENV_FILE>
No puedo ejecutar el contenedor con --env-file hasta que este archivo exista.
No imprimas ni infieras secretos.
Demonio Docker no en ejecución
Informa:
Docker está instalado pero el demonio no está en ejecución.
Inicia Docker Desktop o Docker Engine, luego ejecuta las comprobaciones previas nuevamente.
Formato de Respuesta Final
Al finalizar, informa:
Resultado:
- Proyecto: <PROJECT_NAME>
- Imagen: <IMAGE_TAG>
- Contenedor: <CONTAINER_NAME>
- Archivo env: <ENV_FILE>
- Puerto: http://localhost:<HOST_PORT>
- Política de reinicio: always
- Validación: exitosa/fallida
Comandos usados:
<lista de comandos importantes>
Notas:
<cualquier advertencia, conflictos de imagen/contenedor existentes o acción de seguimiento>
Si el flujo de trabajo se detiene debido a una etiqueta de versión existente, archivo env faltante, contenedor existente, error de Docker o conflicto de puerto, indica claramente el problema bloqueante y el comando más seguro a continuación.