Node.js, Express, MongoDB, and Handlebars portfolio project for managing courses, news, users, and admin workflows.
- Node.js 20
- Express 5
- MongoDB + Mongoose
- express-session + connect-mongo
- Handlebars
- Jest + Supertest
- Docker + Docker Compose
- GitHub Actions
Install dependencies from the lockfile:
npm ciCreate a local .env file from .env.example, then run:
npm run startThe current start script uses nodemon --inspect src/index.js, so it is intended for local development. The Docker image runs the production entrypoint directly with node src/index.js.
Run tests:
npm testStart the full app stack with MongoDB:
docker compose up --buildStop containers without deleting the MongoDB volume:
docker compose downInspect logs:
docker compose logs -fThe Compose app service connects to MongoDB through Docker networking:
mongodb://mongo:27017/baokim_prod
Override the host port with APP_PORT and the container database URI with APP_MONGO_URI when needed.
GET /healthExpected response:
{
"status": "ok"
}Docker Compose and GitHub Actions use this endpoint to verify the application starts correctly.
GitHub Actions runs:
tests
-> Docker build
-> Docker Compose integration startup
-> /health check
-> Docker Hub image publish on main
Pull requests run tests plus Docker/Compose health checks. Pushes to main also publish the Docker image after those checks pass.
Configure these repository secrets before Docker Hub publishing:
DOCKERHUB_USERNAME
DOCKERHUB_TOKEN
The workflow publishes:
<DOCKERHUB_USERNAME>/my-backend-app:latest
<DOCKERHUB_USERNAME>/my-backend-app:<git-sha>
Change IMAGE_NAME in .github/workflows/ci.yml if your Docker Hub repository name is different.
.
|- Dockerfile
|- docker-compose.yml
|- package.json
|- scripts/
|- src/
| |- index.js
| |- app/
| |- config/
| |- middleware/
| |- resources/
| |- routes/
| |- util/
|- __tests__/