CommunityImagegithub.com

thanatornPik/nextjs-skill-app-workshop

Construire et exécuter localement une image Docker de production pour une application Next.js en toute sécurité. Utilisez cette compétence lorsque l'utilisateur souhaite construire une image Docker, exécuter un conteneur avec un fichier d'environnement, vérifier si une version d'image existe déjà localement, ou déployer une application Next.js localement avec Docker sans coder en dur le nom du projet.

Qu'est-ce que nextjs-skill-app-workshop ?

Cette compétence automatise le déploiement local d'une application Next.js avec Docker de manière sécurisée et intelligente. Elle résout automatiquement le nom du projet à partir du dépôt Git, du fichier `package.json`, ou du nom du dossier courant, puis l'utilise pour construire et exécuter une image Docker versionnée. Avant chaque action, une série de vérifications préalables (préflight checks) est effectuée : existence du Dockerfile, disponibilité de Docker, présence du fichier d'environnement, conflits d'image ou de conteneur. L'agent ne reconstruit jamais une image existante ni ne supprime un conteneur sans confirmation explicite de l'utilisateur, ce qui évite les pertes de données et les actions destructrices. En cas d'échec (port déjà utilisé, image existante, conteneur en conflit), il fournit un diagnostic clair et propose des actions correctives sécurisées.

Compatible avec~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 Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Compétence de déploiement Docker local pour Next.js

Objectif

Utilisez cette compétence pour construire et exécuter une application Next.js avec Docker en utilisant une étiquette d'image versionnée.

Cette compétence ne doit pas coder en dur le nom du projet. Déduisez le nom de l'image du dépôt actuel sauf si l'utilisateur fournit un nom spécifique.

Résolution du nom du projet

Avant de construire, déterminez ces valeurs :

PROJECT_NAME=<nom du projet résolu>
IMAGE_NAME=<nom de l'image résolu>
IMAGE_VERSION=<version résolue>
IMAGE_TAG=${IMAGE_NAME}:${IMAGE_VERSION}
CONTAINER_NAME=<nom du conteneur résolu>
ENV_FILE=<fichier d'environnement résolu>
HOST_PORT=<port hôte résolu>
CONTAINER_PORT=<port conteneur résolu>

Règles de résolution :

  1. Si l'utilisateur fournit un nom d'image, utilisez-le.

  2. Sinon, lisez package.json et utilisez le champ name.

  3. Si package.json n'a pas de name, utilisez le nom du dossier courant.

  4. Normalisez le nom de l'image :

    • minuscule
    • remplacez les espaces et underscores par des tirets
    • supprimez les caractères invalides pour les noms d'images Docker
  5. Si l'utilisateur fournit une version, utilisez-la.

  6. Sinon, prenez par défaut 1.0.0.

  7. Si l'utilisateur fournit un nom de conteneur, utilisez-le.

  8. Sinon, utilisez le nom d'image normalisé comme nom de conteneur.

  9. Si l'utilisateur fournit un fichier d'environnement, utilisez-le.

  10. Sinon, prenez par défaut .env.production.

  11. Si l'utilisateur fournit des ports, utilisez-les.

  12. Sinon, prenez par défaut HOST_PORT=4000 et CONTAINER_PORT=3000.

Exemple :

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

Règles de sécurité

Avant d'exécuter une commande de construction ou d'exécution :

  1. Vérifiez que le répertoire de travail actuel est la racine du projet.

  2. Vérifiez que Dockerfile existe.

  3. Vérifiez que le fichier d'environnement existe.

  4. Vérifiez que Docker est installé et en cours d'exécution.

  5. Vérifiez si l'étiquette d'image demandée existe déjà localement.

  6. Vérifiez si le nom de conteneur demandé existe déjà.

  7. Ne jamais afficher les secrets du fichier d'environnement.

  8. N'utilisez pas l'étiquette latest sauf demande explicite de l'utilisateur.

  9. N'exécutez pas de commandes de nettoyage destructrices telles que :

    • docker system prune
    • docker image prune
    • docker volume prune
  10. Ne pas arrêter, supprimer ou remplacer un conteneur existant sans confirmation explicite de l'utilisateur.

  11. Ne pas reconstruire une étiquette de version existante sauf confirmation claire de l'utilisateur.

Vérifications préalables

Exécutez ces vérifications en premier :

pwd
ls -la

test -f package.json && echo "OK: package.json trouvé" || echo "ATTENTION: package.json non trouvé"
test -f Dockerfile && echo "OK: Dockerfile trouvé" || echo "ERREUR: Dockerfile non trouvé"
test -f "$ENV_FILE" && echo "OK: fichier d'environnement trouvé : $ENV_FILE" || echo "ERREUR: fichier d'environnement non trouvé : $ENV_FILE"

docker --version
docker info >/dev/null && echo "OK: le démon Docker est en cours d'exécution" || echo "ERREUR: le démon Docker n'est pas en cours d'exécution"

Si Dockerfile est manquant, arrêtez-vous et signalez le problème.

Si le fichier d'environnement est manquant, arrêtez-vous et signalez le problème. Ne créez pas de fichier d'environnement factice sauf demande de l'utilisateur.

Si le démon Docker n'est pas en cours d'exécution, arrêtez-vous et dites à l'utilisateur de démarrer Docker Desktop ou Docker Engine.

Commandes d'aide suggérées

Pour déduire le nom de l'image à partir de package.json :

node -p "require('./package.json').name"

Si package.json n'existe pas ou n'a pas de name, utilisez le nom du répertoire courant :

basename "$PWD"

Pour normaliser manuellement un nom de projet, utilisez le kebab-case en minuscules.

Exemple :

My Next App -> my-next-app
nextjs_skill_app -> nextjs-skill-app

Vérification de l'étiquette de version

Avant de construire, vérifiez si l'étiquette d'image demandée existe déjà :

docker image inspect "$IMAGE_TAG" >/dev/null 2>&1 \
  && echo "EXISTE : $IMAGE_TAG" \
  || echo "DISPONIBLE : $IMAGE_TAG"

Listez également les versions locales existantes pour cette image :

docker images "$IMAGE_NAME" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}"

Si l'étiquette d'image demandée existe déjà :

  1. N'exécutez pas docker build.
  2. Signalez que la version existe déjà localement.
  3. Suggérez la prochaine version de correctif, par exemple 1.0.1.
  4. Demandez à l'utilisateur s'il souhaite utiliser une nouvelle version ou reconstruire explicitement la même étiquette.

Ne reconstruisez une étiquette existante que si l'utilisateur confirme clairement.

Vérification du nom du conteneur

Avant d'exécuter le conteneur, vérifiez si le nom du conteneur existe déjà :

docker ps -a --filter "name=^/${CONTAINER_NAME}$" \
  --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

Si un conteneur avec le même nom existe déjà :

  1. N'exécutez pas un autre conteneur avec le même nom.
  2. Signalez l'état du conteneur existant.
  3. Demandez à l'utilisateur s'il souhaite arrêter/supprimer le conteneur ou utiliser un nom de conteneur différent.
  4. Ne le supprimez pas automatiquement.

Commande de construction

Si l'étiquette d'image n'existe pas, exécutez :

docker build -t "$IMAGE_TAG" .

Après la construction, vérifiez que l'image existe :

docker image inspect "$IMAGE_TAG" >/dev/null \
  && echo "OK: image construite avec succès : $IMAGE_TAG" \
  || echo "ERREUR: image non trouvée après construction : $IMAGE_TAG"

Commande d'exécution

Si l'image existe et que le nom du conteneur est disponible, exécutez :

docker run --restart=always -d \
  --name "$CONTAINER_NAME" \
  --env-file "$ENV_FILE" \
  -p "${HOST_PORT}:${CONTAINER_PORT}" \
  "$IMAGE_TAG"

Validation après exécution

Après avoir exécuté le conteneur, validez avec :

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}"

Résultat attendu :

  1. Le statut du conteneur doit être Up.
  2. Le mappage de port doit inclure ${HOST_PORT}->${CONTAINER_PORT}.
  3. Les logs ne doivent pas montrer d'erreurs fatales.
  4. curl -I doit retourner une réponse HTTP telle que 200, 301, 302, 307 ou 308.

Si curl échoue, inspectez les logs et signalez la cause probable.

Gestion des échecs courants

L'étiquette d'image existe déjà

Signalez :

L'étiquette d'image existe déjà localement :
<IMAGE_TAG>

Action recommandée :
- Utiliser une nouvelle version de correctif, par exemple 1.0.1
- Ou confirmer explicitement la reconstruction de la même étiquette

Le nom du conteneur existe déjà

Signalez :

Le conteneur existe déjà :
<CONTAINER_NAME>

Veuillez confirmer si vous souhaitez l'arrêter/le supprimer, ou fournir un nom de conteneur différent.

Le port est déjà utilisé

Vérifiez :

lsof -i :"$HOST_PORT"

Signalez le processus utilisant le port et demandez si l'utilisateur souhaite changer HOST_PORT.

Fichier d'environnement manquant

Signalez :

Le fichier d'environnement est introuvable :
<ENV_FILE>

Je ne peux pas exécuter le conteneur avec --env-file tant que ce fichier n'existe pas.

N'affichez pas et ne déduisez pas de secrets.

Démon Docker non en cours d'exécution

Signalez :

Docker est installé mais le démon n'est pas en cours d'exécution.
Démarrez Docker Desktop ou Docker Engine, puis relancez les vérifications préalables.

Format de réponse final

Lorsque vous avez terminé, signalez :

Résultat :
- Projet : <PROJECT_NAME>
- Image : <IMAGE_TAG>
- Conteneur : <CONTAINER_NAME>
- Fichier d'environnement : <ENV_FILE>
- Port : http://localhost:<HOST_PORT>
- Politique de redémarrage : always
- Validation : réussie/échouée

Commandes utilisées :
<liste des commandes importantes>

Notes :
<avertissements éventuels, conflits d'image/conteneur existants, action de suivi>

Si le flux de travail s'arrête à cause d'une étiquette de version existante, d'un fichier d'environnement manquant, d'un conteneur existant, d'une erreur Docker ou d'un conflit de port, indiquez clairement le problème bloquant et la commande suivante la plus sûre.

Individual skills in this repo

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

Skills associés