{"id":21023203,"url":"https://github.com/tkssharma/12-factor-app-microservices","last_synced_at":"2025-07-31T17:09:39.095Z","repository":{"id":37661290,"uuid":"382786262","full_name":"tkssharma/12-factor-app-microservices","owner":"tkssharma","description":"12 factor principles using nestjs ","archived":false,"fork":false,"pushed_at":"2021-08-21T12:21:32.000Z","size":1792,"stargazers_count":149,"open_issues_count":0,"forks_count":51,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-06T12:46:49.535Z","etag":null,"topics":["knex","microservices","nestjs","sequelize","typeorm","typescript"],"latest_commit_sha":null,"homepage":"https://www.youtube.com/playlist?list=PLIGDNOJWiL18srI6BmFLfwDPvorTmyQ_c","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tkssharma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-04T07:03:47.000Z","updated_at":"2025-04-20T14:35:00.000Z","dependencies_parsed_at":"2022-08-08T21:15:37.520Z","dependency_job_id":null,"html_url":"https://github.com/tkssharma/12-factor-app-microservices","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tkssharma/12-factor-app-microservices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkssharma%2F12-factor-app-microservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkssharma%2F12-factor-app-microservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkssharma%2F12-factor-app-microservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkssharma%2F12-factor-app-microservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tkssharma","download_url":"https://codeload.github.com/tkssharma/12-factor-app-microservices/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tkssharma%2F12-factor-app-microservices/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268075031,"owners_count":24191652,"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","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["knex","microservices","nestjs","sequelize","typeorm","typescript"],"created_at":"2024-11-19T11:17:12.118Z","updated_at":"2025-07-31T17:09:39.060Z","avatar_url":"https://github.com/tkssharma.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Application with 12 factor App\n\n[NestJS](https://github.com/nestjs/nest) framework starter repository.\n\n| 12 Factor App                 | Nest JS App Example |\n| ----------------------------- | ------------------- |\n| Baseline                      |                     |\n| lint \u0026 test configurations    |                     |\n| migration setup               |                     |\n| unit \u0026 integration test setup |                     |\n\n![](snap.png)\n\n## Libraries \u0026 Technologies\n\n- Language\n\n  - Docs\n    - TypeScript: \u003chttps://www.typescriptlang.org/docs/\u003e\n  - Packages\n    - typescript: \u003chttps://github.com/microsoft/TypeScript\u003e\n\n- Web Application Framework\n  - Docs\n    - NestJS: \u003chttps://docs.nestjs.com/\u003e\n  - Packages\n    - @nestjs: \u003chttps://github.com/nestjs/nest\u003e\n\n# Twelve Factor nodejs app\n\nThis app demonstrates the [twelve-factor methodology](https://12factor.net) in\nNode.js on cloud.gov.\n\nThe goal is to walk a user through the twelve-factor methodology with specific\nexamples of how you would implement them in Node.js on cloud.gov. The companion\napplication that demonstrates the principles is not implemented yet, but the\nidea is that you could link to specific line numbers to see a working app, with\nworking code implementing best practices.\n\nThe twelve-factor methodology is not specific to Node.js and much of these tips\nare already general enough for any cloud.gov application.\n\n- Pin Down NPM Package Versions with Yarn.lock\n- Use Git Flow as a Reliable Version Control Model\n- Manage Configuration Values with Environment Variables\n- Build, Release and Run Containers with Docker Compose\n- Run Stateless Docker Containers\n- Export Services with Docker Port Binding\n- Scale Docker Horizontally with Nginx Load Balancing\n- Ensure Containers Run with High-Availability\n- Run Consistent Dev, Stage \u0026 Prod Docker Environments\n- Pipe Log Output to STDOUT with Docker\n\n## The Twelve Factors\n\n### [I. Codebase](https://12factor.net/codebase)\n\nOne codebase tracked in revision control, many deploys.\n\n#### How we do it\n\nThis code is tracked on github. [Git\nflow](https://danielkummer.github.io/git-flow-cheatsheet/) can be used to manage\nbranches for releases.\n\n[comment]: # 'include notes on the CD scripts'\n\n### [II. Dependencies](https://12factor.net/dependencies)\n\nExplicitly declare and isolate dependencies.\n\n#### How we do it\n\n[package.json][package-json] declare and lock dependencies to specific versions.\n[npm][npmjs] installs modules to a local `node_modules` dir so each\napplication's dependencies are isolated from the rest of the system.\n\n### [III. Config](https://12factor.net/config)\n\nStore config in the environment.\n\n#### How we do it\n\nConfiguration is stored in enviornment variables and supplied through the\n[manifest.yml][manifest-yml].\n\nSecrets are also stored in environment variables but supplied through a [Cloud\nFoundry User Provided\nService](https://docs.cloudfoundry.org/devguide/services/user-provided.html).\nWhen setting up the app, they are created with a one-time command `cf create-user-provided-service tfn-secrets -p '{\"SECRET_KEY\": \"your-secret-key\"}'`.\n\nConnection configuration to Cloud Foundry Services, like our database, are\nprovided through the `VCAP_SERVICES` environment variable.\n\n### [IV. Backing services](https://12factor.net/backing-services)\n\nTreat backing services as attached resources.\n\n#### How we do it\n\nWe connect to the database via a connection url provided by the\n`VCAP_SERVICES` environment variable. If we needed to setup a new database, we\nwould simply create a new database with `cf create-service` and bind the\ndatabase to our application. After restaging with `cf restage`, the\n`VCAP_SERVICES` environment will be updated with the new connection url and our\napp would be talking to the new database.\n\nWe use a library which handles the database connection. This library abstracts\naway the differences between different SQL-based databases. This makes it easier\nto migrate from one database provider to another.\n\nWe expect to be using a database hosted on Cloud Foundry, but using this\nstrategy we could store the connection url in a separate environment variable\nwhich could point to a database outside of the Cloud Foundry environment and\nthis strategy would work fine.\n\nOf course, how you handle migrating your data from one database to another can\nbe complicated and is out of scope with regard to the twelve factor app.\n\n### [V. Build, release, run](https://12factor.net/build-release-run)\n\nStrictly separate build and run stages.\n\n#### How we do it\n\n`package.json` allows to configure \"scripts\" so that we can codify various\ntasks. `npm run build` is used to build this application and produces minified\njavascript and css files to be served as static assets.\n\n`npm start` is used to start the application. The `nodejs_buildpack` runs this\ncommand by default to start your application.\n\n### [VI. Processes](https://12factor.net/processes)\n\nExecute the app as one or more stateless processes.\n\n#### How we do it\n\nWe listen to SIGTERM and SIGINT to know it's time to shutdown. The platform is\nconstantly being updated even if our application is not. Machines die, security\npatches cause reboots. Server resources become consumed. Any of these things\ncould cause the platform to kill your application. Don't worry though, Cloud\nFoundry makes sure to start a new process on the new freshly patched host before\nkilling your old process.\n\nBy listening to process signals, we know when to stop serving requests, flush\ndatabase connections, and close any open resources.\n\n### [VII. Port binding](https://12factor.net/port-binding)\n\nExport services via port binding.\n\n#### How we do it\n\nCloud Foundry assigns your application instance a port on the host machine and\nexposes it through the `PORT` environment variable.\n\n### [VIII. Concurrency](https://12factor.net/concurrency)\n\nScale out via the process model\n\n#### How we do it\n\nOur app keeps no state on it's own. Configuration is stored in the environment\nand read at startup. User sessions are stored as cookies on the client. Any\nother state is kept in the database. This allows our application to scale simply\nby adding more processes.\n\nWe are running [two application instances][manifest-yml-instances] on Cloud\nFoundry. Each application instance represents a running process of our\napplication. The two instances are likely running on different host machines and\nhave no way of communicating with each other. By making our processes stateless,\nthe two application instances have no need to communicate because all state is\nstored in our backing service (the database in our case).\n\nHere are the steps the app takes when a request comes in:\n\n1. A user request comes in.\n1. We parse their session cookie to figure out who they are.\n1. We lookup their user information in the database.\n1. Process their request, possibly with additional database lookups.\n\nNotice how if a user's request comes in on instance 1, the same user's second\nrequest could be served by any instance. The steps to process subsequent requests are\nthe same.\n\nIf you wanted to add some kind of session caching, that would be a job for\nanother backing service like Memcached or Redis. That way all instances of your\napplication could use a shared cache.\n\n### [IX. Disposability](https://12factor.net/disposability)\n\nMaximize robustness with fast startup and graceful shutdown.\n\n#### How we do it\n\n_SIGTERM SIGINT above?_\n\n### [X. Dev/prod parity](https://12factor.net/dev-prod-parity)\n\nKeep development, staging, and production as similar as possible\n\n#### How we do it\n\nChoosing your environments is up to you, but it's probably good to have at least\ntwo for development. For us, development is our local laptop. Staging is a Cloud\nFoundry environment we use to preview the application to our partners.\nProduction is a Cloud Foundry environment once it has been accepted by our\npartners.\n\nAs much as possible, the differences between development, staging, and\nproduction is simply the configuration which is stored in the environment.\n\nOccasionally we use `NODE_ENV`, `NODE_CONFIG` to produce slightly different\nbehavior. Specifically, anything we\n\n| Environment variable | Description                 |\n| -------------------- | --------------------------- |\n| `NODE_ENV`           | _How_ the app is running.   |\n| `NODE_CONFIG`        | _Where_ the app is running. |\n\n| Environment variable | development | staging       | production   |\n| -------------------- | ----------- | ------------- | ------------ |\n| `NODE_ENV`           | `\u003cunset\u003e`   | `production`† | `production` |\n| `NODE_CONFIG`        | `\u003cunset\u003e`   | `staging`     | `production` |\n\n_† That's not a typo, remeber `NODE_ENV` is *how* the app is running. Both\nstaging and production are Cloud Foundry environments and warrant a production setup._\n\nFor nodejs, `NODE_ENV=production` has special meaning. `npm install` will only\ninstall `dependencies` listed in your `package.json` and will omit any\n`devDependencies`. We also use `NODE_ENV` to condition on how we build our\nstatic assets. `NODE_ENV=production` will include some extra optimizations.\n\n`NODE_CONFIG` is used sparingly, and only to load environment specific\nconfiguration files.\n\n### [XI. Logs](https://12factor.net/logs)\n\nTreat logs as event streams.\n\n#### How we do it\n\nWe use `winston` as our logger. We use logging levels to provide feedback about\nhow the application is working. Some of this feedback could warrant a bug fix.\n\nWarnings are conditions that are unexpected and might hint that a bug exists in\nthe code.\n\n### [XII. Admin processes](https://12factor.net/admin-processes)\n\nRun admin/management tasks as one-off processes.\n\n#### How we do it\n\nAny one-off tasks are added as npm scripts. The meat of these tasks is added to\nthe `tasks` directory. Some take inputs which can be specified when running the\ntask `npm run script -- arguments`. Note that by default, we avoid writing\ninteractive scripts. If configuration is complex, the task can accept\na configuration file or read a configuration from stdin.\n\n## Beyond Twelve Factor\n\n### Blue/green deploy\n\nBy default, `cf push` will stop your application while it rebuilds the new one.\nThat means that a `cf push` results in a service disruption. If your application\nfails to build, the old application is gone so you are left with no running\napplication at all. Blue/green is a strategy that creates a new application\nliving side-by-side your old application. When the new application is known to\nbe good, the old application is removed and you are left with a working new\nversion of your application.\n\nThe [autopilot zero-downtime-push](https://github.com/contraband/autopilot)\nplugin will do this for you automatically.\n\n### Continuous Integration and Delivery with Git Flow\n\nGit Flow is a useful process for managing relases using git branches. The idea\nis that branches map to different deployment environments.\n\n`master` represents well-vetted and partner accepted work and deploys to the\nproduction environment.\n\n`release-x.y` is on track for release and deploys to your staging environment.\nThis allows partners to review the work before it is released. Each release\nbranch is based on development. Once created, this allows developers to commit\nbug fixes directly to the release branch without hindering development on the\nnext release.\n\n`development` is an integration branch. This allows developers on your team\nto test their work-in-progress features with features from other developers.\n\n`feature-\\*` branches represent a single feature. One or more developers may be\ncommitting to this branch. When the feature is tested and reviewed it can be\nmerged to `development`.\n\n[manifest-yml]: https://github.com/adborden/twelve-factor-node/blob/master/manifest.prod.yml\n[manifest-yml-instances]: https://github.com/adborden/twelve-factor-node/blob/master/manifest.prod.yml#L3\n[npmjs]: https://npmjs.org/\n[package-json]: https://github.com/adborden/twelve-factor-node/blob/master/package.json\n[package-json-scripts]: https://github.com/adborden/twelve-factor-node/blob/master/package.json#L5\n\n## Node.js Best Practices\n\n\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"src/assets/images/banner-2.jpg\" alt=\"Node.js Best Practices\"\u003e\n\u003c/h1\u003e\n\n### 1. Project Structure Practices\n\n[✔️] 1.1 Structure your solution by components\n\n[✔️] 1.2 Layer your components, keep Express within its boundaries\n\n[✔️] 1.3 Wrap common utilities as npm packages\n\n[❌] No neccessary - 1.4 Separate Express 'app' and 'server'\n\n[✔️] 1.5 Use environment aware, secure and hierarchical config\n\n### 2. Error Handling Practices\n\n[✔️] 2.1 Use Async-Await or promises for async error handling\n\n[✔️] 2.2 Use only the built-in Error object\n\n![❔] 2.3 Distinguish operational vs programmer errors\n\n[✔️] 2.4 Handle errors centrally, not within an Express middleware\n\n[✔️] 2.5 Document API errors using Swagger or GraphQL\n\n[✔️] 2.6 Exit the process gracefully when a stranger comes to town\n\n[✔️] 2.7 Use a mature logger to increase error visibility\n\n[✔️️] use Jest - 2.8 Test error flows using your favorite test framework\n\n![❔] 2.9 Discover errors and downtime using APM products\n\n[✔️] 2.10 Catch unhandled promise rejections\n\n[✔️] 2.11 Fail fast, validate arguments using a dedicated library\n\n### 3. Code Style Practices\n\n[❌] No neccessary - 3.1 Use ESLint\n\n[❔] 3.2 Node.js specific plugins\n\n[✔️] 3.3 Start a Codeblock's Curly Braces on the Same Line\n\n[✔️] 3.4 Separate your statements properly\n\n[✔️] 3.5 Name your functions\n\n[✔️] 3.6 Use naming conventions for variables, constants, functions and classes\n\n[✔️] 3.7 Prefer const over let. Ditch the var\n\n[✔️] 3.8 Require modules first, not inside functions\n\n[✔️] Nest must import files directly - 3.9 Require modules by folders, opposed to the files directly\n\n[✔️] 3.10 Use the `===` operator\n\n[✔️] 3.11 Use Async Await, avoid callbacks\n\n[✔️] 3.12 Use arrow function expressions (=\u003e)\n\n### 4. Testing And Overall Quality Practices\n\n[✔️] 4.1 At the very least, write API (component) testing\n\n[✔️] use Jest - 4.2 Include 3 parts in each test name\n\n[✔️] use Jest - 4.3 Structure tests by the AAA pattern\n\n[✔️] 4.4 Detect code issues with a linter\n\n[〽️] use Jest - 4.5 Avoid global test fixtures and seeds, add data per-test\n\n[✔️] 4.6 Constantly inspect for vulnerable dependencies\n\n![❔] 4.7 Tag your tests\n\n[✔️] 4.8 Check your test coverage, it helps to identify wrong test patterns\n\n[✔️] 4.9 Inspect for outdated packages\n\n[✔️] 4.10 Use production-like env for e2e testing\n\n[✔️] 4.11 Refactor regularly using static analysis tools\n\n[✔️] 4.12 Carefully choose your CI platform (Jenkins vs CircleCI vs Travis vs Rest of the world)\n\n### 5. Going To Production Practices\n\n![❔] 5.1. Monitoring!\n\n[✔️] 5.2. Increase transparency using smart logging\n\n![❔] 5.3. Delegate anything possible (e.g. gzip, SSL) to a reverse proxy\n\n[✔️] 5.4. Lock dependencies\n\n![❔] 5.5. Guard process uptime using the right tool\n\n[✔️] 5.6. Utilize all CPU cores\n\n[✔️] 5.7. Create a ‘maintenance endpoint’\n\n[✔️] 5.8. Discover errors and downtime using APM products\n\n[✔️] 5.9. Make your code production-ready\n\n![❔] 5.10. Measure and guard the memory usage\n\n[✔️] 5.11. Get your frontend assets out of Node\n\n![❔] 5.12. Be stateless, kill your servers almost every day\n\n[✔️] 5.13. Use tools that automatically detect vulnerabilities\n\n![❔] 5.14. Assign a transaction id to each log statement\n\n[✔️] 5.15. Set NODE_ENV=production\n\n![❔] 5.16. Design automated, atomic and zero-downtime deployments\n\n![❔] 5.17. Use an LTS release of Node.js\n\n![❔] 5.18. Don't route logs within the app\n\n### 6. Security Best Practices\n\n[✔️] 6.1. Embrace linter security rules\n\n[✔️] 6.2. Limit concurrent requests using a middleware\n\n[✔️] 6.3 Extract secrets from config files or use packages to encrypt them\n\n[✔️] 6.4. Prevent query injection vulnerabilities with ORM/ODM libraries\n\n![❔] 6.5. Collection of generic security best practices\n\n[✔️] 6.6. Adjust the HTTP response headers for enhanced security\n\n[✔️] 6.7. Constantly and automatically inspect for vulnerable dependencies\n\n[✔️] 6.8. Avoid using the Node.js crypto library for handling passwords, use Bcrypt\n\n![❔] 6.9. Escape HTML, JS and CSS output\n\n[✔️] 6.10. Validate incoming JSON schemas\n\n![❔] 6.11. Support blacklisting JWTs\n\n![❔] 6.12. Prevent brute-force attacks against authorization\n\n[✔️] 6.13. Run Node.js as non-root user\n\n[✔️] 6.14. Limit payload size using a reverse-proxy or a middleware\n\n![❔] 6.15. Avoid JavaScript eval statements\n\n![❔] 6.16. Prevent evil RegEx from overloading your single thread execution\n\n[✔️] 6.17. Avoid module loading using a variable\n\n![❔] 6.18. Run unsafe code in a sandbox\n\n![❔] 6.19. Take extra care when working with child processes\n\n[✔️] 6.20. Hide error details from clients\n\n[✔️] 6.21. Configure 2FA for npm or Yarn\n\n[❌] No neccessary - 6.22. Modify session middleware settings\n\n![❔] 6.23. Avoid DOS attacks by explicitly setting when a process should crash\n\n[❌] No neccessary - 6.24. Prevent unsafe redirects\n\n[✔️] 6.25. Avoid publishing secrets to the npm registry\n\n### 7. Performance Best Practices\n\nOur contributors are working on this section. [Would you like to join?](https://github.com/i0natan/nodebestpractices/issues/256)\n\n[✔️] 7.1. Prefer native JS methods over user-land utils like Lodash\n\n[❔] 7.2. Use Fastify in place of Express\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkssharma%2F12-factor-app-microservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftkssharma%2F12-factor-app-microservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkssharma%2F12-factor-app-microservices/lists"}