Démarrage du backend Node.js dans Docker : un guide de dépannage
Vous rencontrez une erreur lors de la tentative d'exécution de votre Backend Node.js à l'intérieur d'un Conteneur Docker peut être frustrant, surtout lorsque cela est dû à un simple message « Script de démarrage manquant ». Cette erreur se produit souvent lorsque MNP Je ne parviens pas à localiser la commande de démarrage correcte dans votre configuration. Si cela vous frappe, vous n’êtes pas seul !
Dans de nombreux cas, le problème se résume à des chemins incorrects ou à des configurations mal alignées entre vos paramètres package.json et Docker. Il est facile de négliger un petit détail lorsqu’il s’agit de constructions en plusieurs étapes, la conteneurisation et les fichiers de configuration. Ayant moi-même été confronté à ce problème, je peux dire que le résoudre implique souvent de vérifier l'emplacement et les scripts de chaque fichier.
Par exemple, j'ai déjà déployé un backend et j'ai réalisé plus tard que mon dossier dist n'était pas correctement mappé, ce qui entraînait l'échec de la commande start. De simples ajustements peuvent résoudre ces problèmes, mais trouver le bon demande de la patience 🔍. Vérifier si toutes les dépendances et tous les scripts sont correctement mappés peut vous faire gagner des heures de débogage.
Dans ce guide, nous aborderons quelques étapes pratiques pour corriger cette erreur, surtout si vous exécutez votre backend avec une base de données telle que DynamoDB dans Docker. Résolvons ensemble l’erreur « script de démarrage manquant » pour que votre backend fonctionne correctement !
Commande | Description |
---|---|
CMD ["node", "dist/server.js"] | Définit la commande principale qui s'exécute dans le conteneur Docker au démarrage. Ici, il demande à Docker de démarrer l'application en exécutant server.js dans le dossier dist, en s'adressant au script de démarrage manquant problème en vous assurant que Docker sait quel script exécuter. |
WORKDIR /app | Définit le répertoire de travail à l’intérieur du conteneur sur /app. Ceci est essentiel pour garantir que tous les chemins de fichiers dans les commandes suivantes font référence à ce répertoire, rationalisant ainsi les processus de construction et d'exécution dans Docker. |
COPY --from=builder /app/dist ./dist | Copie les fichiers générés du dossier dist à l'étape du générateur vers le répertoire dist de l'environnement d'exécution. Cette commande est essentielle pour garantir que les fichiers TypeScript compilés sont disponibles dans le conteneur. |
RUN npm install --omit=dev | Installe uniquement les dépendances de production en omettant les dépendances de développement. Cette commande est optimisée pour les versions de production, réduisant la taille finale du conteneur et améliorant la sécurité en excluant les outils de développement. |
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000"] | Définit une vérification de l'état pour vérifier si le service DynamoDB dans Docker est en cours d'exécution. Il utilise curl pour tenter une connexion au point de terminaison local spécifié, garantissant ainsi que le service est disponible avant le démarrage du backend. |
depends_on: | Spécifie les dépendances dans docker-compose.yml. Ici, cela garantit que le service backend attend l'initialisation de DynamoDB, empêchant ainsi les erreurs de tentative de connexion à un service non prêt. |
EXPOSE 3001 | Ouvre le port 3001 dans le conteneur Docker, rendant le service backend accessible sur ce port. Cette commande est requise pour configurer la mise en réseau et permettre aux services externes ou à d'autres conteneurs d'accéder au backend. |
test('dist folder exists', ...) | Un test unitaire Jest qui vérifie si le dossier dist a été correctement généré. Ce test permet de vérifier que l'étape de construction a réussi, en détectant les problèmes potentiels liés aux fichiers manquants dans le répertoire dist. |
expect(packageJson.scripts.start) | Une ligne de test Jest qui confirme que le script de démarrage existe dans package.json. Cela permet d'éviter les erreurs d'exécution dues aux commandes de démarrage manquantes en garantissant l'exactitude de la configuration avant le déploiement. |
Configuration Docker pour Node.js et connexion à la base de données
Dans l'exemple ci-dessus, la configuration Docker exploite une construction en plusieurs étapes, ce qui est utile pour créer des conteneurs efficaces prêts pour la production. La première étape, définie comme « constructeur », installe les dépendances et compile les Manuscrit fichiers en JavaScript dans le dist dossier. Cette étape garantit que le code compilé est prêt pour la production sans inclure de dépendances de développement inutiles. Une fois construite, la deuxième étape (runtime) copie uniquement les fichiers compilés et les dépendances de production, minimisant ainsi la taille du conteneur. Cette configuration est particulièrement utile si vous effectuez fréquemment des déploiements dans des environnements cloud où chaque petite optimisation compte ! 🚀
Le RÉPERT TRAVAIL La commande dans les deux étapes définit le répertoire de travail du conteneur sur /app. Cela simplifie les chemins de fichiers et organise toutes les opérations autour de ce répertoire. Suite à cela, COPIE Les instructions déplacent des fichiers spécifiques de la machine hôte vers le conteneur. Dans la première étape, les fichiers package*.json et tsconfig.json sont copiés pour permettre l'installation des dépendances et la compilation TypeScript, et le EXÉCUTER l'installation de npm et RUN npm exécuter la construction Les commandes garantissent que tout est configuré correctement. Cette configuration permet d'éviter des problèmes tels que des scripts de démarrage manquants en garantissant que tous les fichiers sont correctement copiés et configurés.
Le docker-compose.yml le fichier connecte le backend avec DynamoDB, ce qui est essentiel pour les tests et le développement locaux. Le dépend_on L'option indique à Docker de démarrer DynamoDB avant le service backend, garantissant ainsi que la base de données est prête pour toute tentative de connexion depuis le backend. Dans des scénarios réels, ne pas disposer d'une telle configuration de dépendances peut entraîner des problèmes de connectivité lorsque le backend démarre avant la base de données, entraînant des erreurs frustrantes. Le bilan de santé La commande teste si DynamoDB est accessible en envoyant une requête ping au point de terminaison, en réessayant jusqu'à ce qu'une connexion soit établie. Ce niveau de gestion des erreurs permet de gagner du temps en garantissant que les services démarrent dans le bon ordre 🕒.
Enfin, dans package.json, nous avons défini le commencer script comme nœud dist/server.js. Cette commande garantit que NPM sait exactement quel fichier exécuter dans le conteneur, ce qui permet d'éviter l'erreur « script de démarrage manquant ». Il existe également une commande build pour compiler le code TypeScript et une commande clean pour supprimer le dossier dist, garantissant ainsi que chaque déploiement redémarre à zéro. L'utilisation de scripts npm comme ceux-ci rend la configuration plus fiable, en particulier lorsque Docker est impliqué, car elle offre des chemins et des actions prévisibles. Cette configuration complète des scripts Docker, Docker Compose et NPM fonctionne ensemble pour créer un flux de travail rationalisé du développement à la production.
Solution 1 : ajustement de Dockerfile et Package.json pour une copie correcte des fichiers
Cette solution utilise Docker et Node.js pour garantir que les fichiers sont correctement copiés dans le dist dossier et que NPM peut localiser le commencer scénario.
# Dockerfile
FROM node:18 AS builder
WORKDIR /app
# Copy necessary config files and install dependencies
COPY package*.json tsconfig.json ./
RUN npm install
# Copy all source files and build the project
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
RUN npm install --omit=dev
COPY --from=builder /app/dist ./dist
EXPOSE 3001
# Adjust command to start the server
CMD ["node", "dist/server.js"]
Solution 2 : modification de docker-compose.yml pour le contrôle de l'environnement
Cette solution modifie le docker-compose.yml configuration pour spécifier les commandes correctes et garantir que les scripts s’exécutent correctement dans Docker.
# docker-compose.yml
version: "3.9"
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- "3001:3001"
environment:
PORT: 3001
depends_on:
- dynamodb
command: ["npm", "run", "start"]
dynamodb:
image: amazon/dynamodb-local
ports:
- "8001:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"]
interval: 10s
timeout: 5s
retries: 5
Solution 3 : vérification et mise à jour des scripts Package.json
Cette solution consiste à s'assurer que le commencer le script est correctement défini dans le package.json fichier pour éviter les erreurs de script manquantes.
{
"name": "backend",
"version": "1.0.0",
"main": "dist/server.js",
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"dev": "nodemon --exec ts-node src/server.ts",
"clean": "rimraf dist"
}
}
Tests unitaires : garantir l'intégrité de la configuration des scripts et de Docker
Ces tests Jest valident que les fichiers essentiels sont correctement copiés et que les scripts NPM fonctionnent dans l'environnement conteneur.
// test/deployment.test.js
const fs = require('fs');
describe('Deployment Tests', () => {
test('dist folder exists', () => {
expect(fs.existsSync('./dist')).toBe(true);
});
test('start script exists in package.json', () => {
const packageJson = require('../package.json');
expect(packageJson.scripts.start).toBe("node dist/server.js");
});
test('Dockerfile has correct CMD', () => {
const dockerfile = fs.readFileSync('./Dockerfile', 'utf8');
expect(dockerfile).toMatch(/CMD \["node", "dist\/server.js"\]/);
});
});
Assurer une copie et une structure de fichiers appropriées dans Docker pour les projets Node.js
Lorsque vous travaillez avec des applications Node.js dans Docker, une considération clé est de garantir que tous les fichiers nécessaires sont correctement copiés et structurés dans le conteneur. Dans les builds en plusieurs étapes, comme dans l’exemple ci-dessus, chaque étape a un objectif spécifique. L'étape initiale, "builder", gère la compilation de TypeScript en JavaScript et prépare le dist dossier. Dans la deuxième étape, seuls les fichiers de production sont inclus, réduisant ainsi la taille du conteneur et optimisant le déploiement. Cette approche réduit non seulement les surcharges inutiles, mais améliore également la sécurité en laissant de côté les outils de développement.
Un aspect essentiel de Docker pour Node.js est d'organiser le package.json et démarrer le script avec précision. En spécifiant clairement les chemins dans le Dockerfile et en vous assurant que la commande start est correctement configurée dans package.json, vous minimisez les erreurs telles que « Script de démarrage manquant ». Il est également essentiel de confirmer que Docker sait où chaque fichier doit se trouver, en particulier dans les configurations complexes impliquant plusieurs services ou dossiers. Par exemple, en utilisant la commande COPY pour ajouter uniquement le dist le dossier et les configurations nécessaires dans le conteneur final garantissent que seuls les fichiers essentiels sont disponibles en production 📂.
Pour vérifier la santé de vos services, le docker-compose.yml Le fichier utilise une vérification de l'état pour vérifier que la base de données est prête. En définissant les dépendances, nous garantissons que le service backend ne démarre pas tant que la base de données n'est pas réactive, évitant ainsi les problèmes de connexion liés au timing. Cette configuration est particulièrement avantageuse dans les applications du monde réel où la connectivité aux bases de données est vitale. Sans cette structure, les services peuvent essayer de se connecter avant que les autres services ne soient opérationnels, entraînant des erreurs d'exécution et des temps d'arrêt potentiels pour les utilisateurs 🔄.
Questions courantes sur la correction du « script de démarrage manquant » dans Node.js
- Qu'est-ce qui cause l'erreur « script de démarrage manquant » dans NPM ?
- Cette erreur se produit souvent lorsque le package.json le fichier n'a pas de start script défini. NPM ne trouve pas le bon point d’entrée pour démarrer l’application.
- Est-ce que le package.json le fichier doit être dans le dist dossier?
- Non, le package.json réside généralement dans le répertoire racine et seuls les fichiers nécessaires sont copiés dans le répertoire racine. dist dossier.
- Pourquoi utilisons-nous des builds en plusieurs étapes dans Docker ?
- Les constructions en plusieurs étapes nous permettent de créer des conteneurs légers et prêts pour la production. En séparant les environnements de construction et d'exécution, les fichiers inutiles sont exclus, améliorant ainsi la sécurité et l'efficacité.
- Comment le healthcheck dans l'aide de Docker Compose ?
- Le healthcheck La commande vérifie si un service est opérationnel, ce qui est essentiel dans les cas où les services dépendants doivent d'abord être prêts, comme les bases de données.
- Puis-je utiliser d'autres bases de données au lieu de DynamoDB dans cette configuration ?
- Oui, vous pouvez remplacer DynamoDB avec d'autres bases de données. Ajustez la configuration de Docker Compose en fonction de votre service de base de données préféré.
- Pourquoi utilisons-nous le RUN npm install --omit=dev commande?
- Cette commande installe uniquement les dépendances de production, ce qui permet de maintenir la légèreté du conteneur en excluant les outils de développement.
- Comment puis-je confirmer le dist le dossier est-il correctement copié ?
- Vous pouvez ajouter un test dans votre code pour vérifier si dist existe, ou utilisez Docker CLI pour inspecter le contenu du conteneur après la construction.
- Dois-je spécifier le port dans Dockerfile et Docker Compose ?
- Oui, spécifier le port dans les deux garantit que le port du conteneur correspond au port hôte, rendant le service accessible depuis l'extérieur de Docker.
- Pourquoi le réglage WORKDIR dans Docker, c'est important ?
- Paramètre WORKDIR crée un chemin de répertoire par défaut pour toutes les commandes, simplifiant les chemins de fichiers et organisant systématiquement les fichiers conteneurs.
- Comment puis-je afficher les journaux Docker pour déboguer cette erreur ?
- Utiliser docker logs [container_name] pour accéder aux journaux, qui peuvent fournir des informations sur les erreurs de démarrage ou les fichiers manquants.
Correction des erreurs de démarrage de Node.js dans Docker
La résolution de l’erreur « script de démarrage manquant » nécessite une attention particulière aux détails, en particulier dans la configuration de la structure de fichiers de Docker et des scripts NPM. Vérifier votre Dockerfile pour vous assurer que les fichiers compilés sont copiés dans le dist dossier et que le script de démarrage dans package.json est correctement défini peut vous faire économiser des heures de débogage.
Le maintien d'une configuration claire et de scripts organisés aidera les conteneurs Docker à fonctionner sans problème, et l'utilisation des contrôles d'état dans Docker Compose garantit que les services se chargent dans le bon ordre. Avec ces ajustements, votre backend devrait démarrer de manière fiable, vous offrant un flux de travail de développement plus fluide. 🛠️
Sources et références
- Informations détaillées sur les builds en plusieurs étapes de Docker et les meilleures pratiques pour les applications Node.js dans Docker : Documentation Docker
- Guide complet sur la configuration des vérifications de l'état et des dépendances dans Docker Compose pour garantir que les services démarrent dans le bon ordre : Bilan de santé de Docker Compose
- Dépannage des erreurs de « script de démarrage manquant » et d'autres problèmes NPM courants, notamment la configuration correcte de package.json pour les versions de production : Documentation du MNP
- Introduction à la configuration et au test de DynamoDB Local dans les environnements Docker, y compris l'utilisation avec les backends Node.js : Guide local AWS DynamoDB