{"id":13553445,"url":"https://github.com/BretFisher/node-docker-good-defaults","last_synced_at":"2025-04-03T05:30:55.427Z","repository":{"id":37587873,"uuid":"55176340","full_name":"BretFisher/node-docker-good-defaults","owner":"BretFisher","description":"sample node app for Docker examples","archived":false,"fork":false,"pushed_at":"2025-02-18T00:37:11.000Z","size":537,"stargazers_count":2363,"open_issues_count":10,"forks_count":490,"subscribers_count":57,"default_branch":"main","last_synced_at":"2025-03-27T06:05:35.886Z","etag":null,"topics":["docker","docker-compose","dockerfile","nodejs","nodemon","npm","vscode"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BretFisher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"bretfisher.com/members"}},"created_at":"2016-03-31T19:13:33.000Z","updated_at":"2025-03-22T22:36:54.000Z","dependencies_parsed_at":"2024-01-14T16:08:14.276Z","dependency_job_id":"23acb571-56b4-4d2b-b0cc-fd8252fa177e","html_url":"https://github.com/BretFisher/node-docker-good-defaults","commit_stats":{"total_commits":108,"total_committers":29,"mean_commits":"3.7241379310344827","dds":0.6111111111111112,"last_synced_commit":"b9a1d894fcc61175711371ec9297584fecadce18"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BretFisher%2Fnode-docker-good-defaults","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BretFisher%2Fnode-docker-good-defaults/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BretFisher%2Fnode-docker-good-defaults/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BretFisher%2Fnode-docker-good-defaults/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BretFisher","download_url":"https://codeload.github.com/BretFisher/node-docker-good-defaults/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246944377,"owners_count":20858773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","dockerfile","nodejs","nodemon","npm","vscode"],"created_at":"2024-08-01T12:02:24.899Z","updated_at":"2025-04-03T05:30:55.159Z","avatar_url":"https://github.com/BretFisher.png","language":"JavaScript","readme":"# Node.js + Docker for Showing Good Defaults in Using Node.js with Docker\n\n[![Lint Code Base](https://github.com/BretFisher/node-docker-good-defaults/actions/workflows/call-super-linter.yaml/badge.svg)](https://github.com/BretFisher/node-docker-good-defaults/actions/workflows/call-super-linter.yaml)\n[![Docker Build](https://github.com/BretFisher/node-docker-good-defaults/actions/workflows/call-docker-build.yaml/badge.svg)](https://github.com/BretFisher/node-docker-good-defaults/actions/workflows/call-docker-build.yaml)\n\n\u003e This tries to be a \"good defaults\" example of starting to use Node.js in Docker for local development and shipping to production with basic bells, whistles, and best practices. Issues/PR welcome.\n\n**Note** I have more advanced examples of Node.js Dockerfiles and Compose files in my [DockerCon 2022 talk and repository](https://github.com/BretFisher/nodejs-rocks-in-docker).\nI also have more about everything Docker and Node.js in my 8 hour video course [Docker for Node.js](https://www.bretfisher.com/node/).\n\n**Also Note**, I have other resources on [Docker and Kubernetes here](https://www.bretfisher.com/docker).\n\n## Local Development Features\n\n- **Dev as close to prod as you can**.\nDocker Compose builds a local development image that is just like the production image except for the\nbelow dev-only features needed in the image.\nThe goal is to have dev environment be as close to test and prod as possible while still giving all the\nnice tools to make you a happy dev.\n- **Prevent needing node/npm on host**.\nThis installs `node_modules` outside app root in the container image so local development won't run into a\nproblem of bind-mounting over it with local source code. This means it will run `npm install`\nonce on container build and you don't need to run npm on host or on each docker run.\nIt will re-run on build if you change `package.json`.\n- **One line startup**. Uses `docker compose up` for single-line build and run of local\ndevelopment server.\n- **Edit locally while code runs in container**.\nDocker Compose uses proper bind-mounts of host source code into container so you can edit\nlocally while running code in Linux container.\n- **Use nodemon in container**. Docker Compose uses nodemon for development for auto-restarting\nNode.js in container when you change files on host.\n- **Enable debug from host to container**. Opens the inspect port 9229 for using host-based\ndebugging like chrome tools or VS Code. Nodemon enables `--inspect` by default in Docker Compose.\n- **Provides VSCode debug configs and tasks for tests**. for Visual Studio Code fans,\n`.vscode` directory has the goods, thanks to @JPLemelin.\n- **Small image and quick re-builds**. `COPY` in `package.json` and run `npm install`\n**before** `COPY` in your source code. This saves big on build time and keeps the container image lean.\n- **Bind-mount package.json**. This allows adding packages in realtime without rebuilding images. e.g.\n`docker compose exec -w /opt/node_app node npm install --save \u003cpackage name\u003e`\n\n## Production-minded Features\n\n- **Use Docker built-in healthchecks**. This uses Dockerfile `HEALTHCHECK` with `/healthz` route to\nhelp Docker know if your container is running properly (example always returns 200, but you get the idea).\n- **Proper NODE_ENV use**. Defaults to `NODE_ENV=production` in Dockerfile and overrides to\n`development` in docker-compose for local dev.\n- **Don't add dev dependencies into the production image**. Proper `NODE_ENV` use means dev dependencies\nwon't be installed in the image by default. Using Docker Compose will build with them by default.\n- **Enables proper SIGTERM/SIGINT for graceful exit**. Defaults to `node index.js` rather than npm\nfor allowing graceful shutdown of node.\nnpm doesn't pass SIGTERM/SIGINT properly (you can't ctrl-c when running `docker run` in foreground).\nTo get `node index.js` to graceful exit, extra signal-catching code is needed.\nThe `Dockerfile` and `index.js` document the options and links to known issues.\n- **Run Node.js in the container as `node` user, not `root`**.\n- **Use docker-stack.yml example for Docker Swarm deployments**.\n\n## Assumptions\n\n- You have Docker and Docker Compose installed (Docker Desktop for Mac/Windows/Linux).\n- You want to use Docker for local development (i.e. never need to install Node.js/npm on host)\nand have dev and prod Docker images be as close as possible.\n- You don't want to lose fidelity in your dev workflow. You want a easy environment setup,\nusing local editors, Node.js debug/inspect, local code repository, while Node.js server runs in a container.\n- You use `docker-compose` for local development only (docker-compose was never intended to be\na production deployment tool anyway).\n- The `docker-compose.yml` is not meant for `docker stack deploy` in Docker Swarm,\nit's meant for happy local development. Use `docker-stack.yml` for Swarm.\n\n## Getting Started\n\nIf this was your Node.js app, to start local development you would:\n\n- Running `docker compose up` is all you need. It will:\n- Build custom local image enabled for development (nodemon, `NODE_ENV=development`).\n- Start container from that image with ports 80 and 9229 open (on localhost).\n- Starts with `nodemon` to restart Node.js on file change in host pwd.\n- Mounts the pwd to the app dir in container.\n- If you need other services like databases,\njust add to compose file and they'll be added to the custom Docker network for this app on `up`.\n- Compose won't rebuild automatically, so either run `docker compose build` after changing `package.json`\nor do what I do and always run `docker compose up --build`.\n- Be sure to use `docker compose down` to cleanup after your done dev'ing.\n\nIf you wanted to add a package while docker-compose was running your app:\n\n- `docker compose exec -w /opt/node_app node npm install --save \u003cpackage name\u003e`\n- This installs it inside the running container.\n- Nodemon will detect the change and restart.\n- `--save` will add it to the package.json for next `docker compose build`\n\nTo execute the unit-tests, you would:\n\n- Execute `docker compose exec node npm test`, It will:\n- Run a process `npm test` in the container.\n- You can use the *vscode* to debug unit-tests with config `Docker Test (Attach 9230 --inspect)`,\nIt will:\n  - Start a debugging process in the container and wait-for-debugger, this is done by *vscode tasks*\n  - It will also kill a previous debugging process if existing.\n\n## Ways to improve security\n\n### Run Node.js as Non-Root User\n\nAs mentioned in the official docker Node.js image docs, Docker runs the image as root.\nThis can pose a\n[potential security issue](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#non-root-user).\n\nAs a security best practice, it is recommended for Node.js apps to listen on non-privileged ports\n[as mentioned here](https://github.com/i0natan/nodebestpractices/blob/master/sections/security/non-root-user.md).\n\n## Other Resources\n\n- [https://blog.hasura.io/an-exhaustive-guide-to-writing-dockerfiles-for-node-js-web-apps-bbee6bd2f3c4](https://blog.hasura.io/an-exhaustive-guide-to-writing-dockerfiles-for-node-js-web-apps-bbee6bd2f3c4)\n","funding_links":["bretfisher.com/members"],"categories":["JavaScript","docker","npm","vscode"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBretFisher%2Fnode-docker-good-defaults","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBretFisher%2Fnode-docker-good-defaults","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBretFisher%2Fnode-docker-good-defaults/lists"}