如何配置Docker使init.js仅运行一次、app.js每次执行docker compose up时均运行?
init.js Once on First Setup, app.js Every Time with Docker Compose Absolutely, there's a straightforward, reliable way to make this work with Docker Compose! Let's break down the setup so other users can pull your repo and run docker compose up without worrying about init.js running every time.
Core Approach
We'll split your stack into three dedicated services in docker-compose.yml:
- A MongoDB service with persistent storage (so your seeded data stays intact across restarts).
- A one-off initialization service that runs
init.jsexactly once (only after MongoDB is fully ready). - Your main app service that runs
app.jsevery time you start the stack.
Step 1: Keep Your Existing Dockerfile
No changes needed here! Your current Dockerfile already includes all dependencies, init.js, and app.js—it works perfectly for both the initialization and app services.
Step 2: Create/Update Your docker-compose.yml
Add this complete configuration to your project root:
version: '3.8' services: # MongoDB service with persistent data storage mongo: image: mongo:latest volumes: - mongodb_data:/data/db # Persists DB data between container restarts ports: - "27017:27017" # One-time DB seeding service init-mongo: build: ./backend # Reuses your Node.js Dockerfile depends_on: - mongo restart: "no" # Critical: prevents this service from re-running after completion # Wait for MongoDB to be fully operational before running init.js command: > sh -c " until mongosh --host mongo --eval 'db.runCommand({ ping: 1 })'; do echo 'Waiting for MongoDB to be ready...'; sleep 2; done; echo 'MongoDB is ready! Seeding database...'; node init.js; " # Main app service (runs every time) app: build: ./backend depends_on: - mongo - init-mongo # Ensures app starts only after DB seeding finishes restart: "always" # Guarantees the app runs on every docker compose up ports: - "3000:3000" # Adjust to match your app's listening port environment: - MONGO_URI=mongodb://mongo:27017/your-database-name # Update to your actual DB name # Persistent volume for MongoDB data volumes: mongodb_data:
What Happens for Other Users
When someone pulls your repo and runs docker compose up:
- The
mongoservice starts and creates a persistent volume to store database data. - The
init-mongoservice builds your Node image, waits for MongoDB to be fully ready (not just the container running), then executesinit.jsto seed the database. Once done, the container exits and won't restart. - The
appservice launches only afterinit-mongocompletes, runningapp.jsvia yournpm startcommand. Every subsequentdocker compose upwill skip theinit-mongoservice (since its container already ran successfully) and start the app immediately.
Resetting the Initialization (If Needed)
If you or a user ever needs to re-run init.js (e.g., to reset the database), just delete the MongoDB volume and restart the stack:
docker compose down -v docker compose up
内容的提问来源于stack exchange,提问作者Jushraf Rahi

