CommunityImagengithub.com

thanatornPik/nextjs-skill-app-workshop

Construye y ejecuta de forma segura una imagen Docker de producción para una aplicación Next.js localmente. Usa esta habilidad cuando el usuario quiera construir una imagen Docker, ejecutar un contenedor con un archivo env, verificar si una versión de imagen ya existe localmente o desplegar una aplicación Next.js localmente con Docker sin codificar el nombre del proyecto.

¿Qué es nextjs-skill-app-workshop?

Esta habilidad permite a un agente de IA construir y ejecutar una aplicación Next.js con Docker de manera segura y versionada, sin necesidad de codificar el nombre del proyecto. Es útil para desarrolladores que desean desplegar localmente una aplicación Next.js en producción usando Docker, manteniendo un control preciso de versiones (tags) y evitando conflictos de nombres. La habilidad soporta cualquier plataforma que ejecute Docker y Node.js, y funciona infiriendo el nombre de la imagen desde `package.json` o el nombre de la carpeta actual, normalizándolo según las reglas de Docker (minúsculas, guiones, sin caracteres inválidos). Realiza comprobaciones previas de seguridad: verifica que exista el `Dockerfile`, el archivo de entorno (por defecto `.env.production`), que Docker esté instalado y en ejecución, y que no exista ya la etiqueta de imagen o el nombre de contenedor solicitados. Luego, construye la imagen (si no existe) y ejecuta el contenedor con la configuración adecuada, validando el resultado con `curl`. Además, maneja casos de error comunes como etiquetas existentes, contenedores duplicados, puertos ocupados o archivos faltantes, solicitando siempre confirmación al usuario antes de acciones destructivas.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/thanatornPik/nextjs-skill-app-workshop/tree/HEAD/.agents/skills/deploy-docker-production

Installed? Explore more Imagen skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

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:

  1. Si el usuario proporciona un nombre de imagen, úsalo.

  2. De lo contrario, lee package.json y usa el campo name.

  3. Si package.json no tiene name, usa el nombre de la carpeta actual.

  4. 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
  5. Si el usuario proporciona una versión, úsala.

  6. De lo contrario, usa 1.0.0 por defecto.

  7. Si el usuario proporciona un nombre de contenedor, úsalo.

  8. De lo contrario, usa el nombre normalizado de la imagen como nombre del contenedor.

  9. Si el usuario proporciona un archivo env, úsalo.

  10. De lo contrario, usa .env.production por defecto.

  11. Si el usuario proporciona puertos, úsalos.

  12. De lo contrario, usa por defecto HOST_PORT=4000 y CONTAINER_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:

  1. Confirma que el directorio de trabajo actual es la raíz del proyecto.

  2. Confirma que existe Dockerfile.

  3. Confirma que existe el archivo env.

  4. Confirma que Docker está instalado y en ejecución.

  5. Verifica si la etiqueta de imagen solicitada ya existe localmente.

  6. Verifica si el nombre del contenedor solicitado ya existe.

  7. Nunca imprimas secretos del archivo env.

  8. No uses la etiqueta latest a menos que el usuario lo pida explícitamente.

  9. No ejecutes comandos de limpieza destructivos como:

    • docker system prune
    • docker image prune
    • docker volume prune
  10. No detengas, elimines ni reemplaces un contenedor existente sin confirmación explícita del usuario.

  11. 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:

  1. No ejecutes docker build.
  2. Informa que la versión ya existe localmente.
  3. Sugiere la siguiente versión de parche, por ejemplo 1.0.1.
  4. 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:

  1. No ejecutes otro contenedor con el mismo nombre.
  2. Informa del estado del contenedor existente.
  3. Pregunta al usuario si desea detenerlo/eliminarlo o usar un nombre de contenedor diferente.
  4. 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:

  1. El estado del contenedor debe ser Up.
  2. El mapeo de puertos debe incluir ${HOST_PORT}->${CONTAINER_PORT}.
  3. Los registros no deben mostrar errores fatales.
  4. curl -I debe devolver una respuesta HTTP como 200, 301, 302, 307 o 308.

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.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Skills relacionados