{"id":15870281,"url":"https://github.com/mkabumattar/express-boilerplate","last_synced_at":"2026-04-02T22:40:13.847Z","repository":{"id":245136334,"uuid":"817402529","full_name":"MKAbuMattar/express-boilerplate","owner":"MKAbuMattar","description":"A boilerplate for building scalable applications with Express.js and TypeScript.","archived":false,"fork":false,"pushed_at":"2026-01-10T20:41:44.000Z","size":2288,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-10T22:12:13.217Z","etag":null,"topics":["docker","esnext","express","nodejs","pino","swagger-ui","tsup","typescript","vitest"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/MKAbuMattar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-19T16:19:47.000Z","updated_at":"2026-01-10T12:55:21.000Z","dependencies_parsed_at":"2024-08-12T17:18:11.645Z","dependency_job_id":"14652f69-8dbf-421a-931f-13b391d6c892","html_url":"https://github.com/MKAbuMattar/express-boilerplate","commit_stats":{"total_commits":194,"total_committers":3,"mean_commits":64.66666666666667,"dds":"0.27835051546391754","last_synced_commit":"3b1b67d9c1e311c5dd94853651968449028b84d8"},"previous_names":["mkabumattar/express-boilerplate"],"tags_count":70,"template":true,"template_full_name":null,"purl":"pkg:github/MKAbuMattar/express-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MKAbuMattar%2Fexpress-boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MKAbuMattar%2Fexpress-boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MKAbuMattar%2Fexpress-boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MKAbuMattar%2Fexpress-boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MKAbuMattar","download_url":"https://codeload.github.com/MKAbuMattar/express-boilerplate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MKAbuMattar%2Fexpress-boilerplate/sbom","scorecard":{"id":339909,"data":{"date":"2025-08-18T05:30:19Z","repo":{"name":"github.com/MKAbuMattar/express-boilerplate","commit":"59fd7dfd2d66f017f9206b2fa61e0601df99bb99"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":6.8,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: RenovateBot: .github/renovate.json:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Code-Review","score":0,"reason":"Found 0/14 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: .github/SECURITY.md:1","Info: Found linked content: .github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: .github/SECURITY.md:1","Info: Found text in security policy: .github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel permissions set to 'write-all': .github/workflows/ci-pipeline.yml:11"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":9,"reason":"dependency not pinned by hash detected -- score normalized to 9","details":["Warn: npmCommand not pinned by hash: Dockerfile:4","Warn: npmCommand not pinned by hash: Dockerfile.aws:4","Info:  23 out of  23 GitHub-owned GitHubAction dependencies pinned","Info:  22 out of  22 third-party GitHubAction dependencies pinned","Info:   8 out of   8 containerImage dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: SAST configuration detected: CodeQL","Info: all commits (27) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci-pipeline.yml:143"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"Contributors","score":6,"reason":"project has 2 contributing companies or organizations -- score normalized to 6","details":["Info: found contributions from: semantic-release, withrawi@ibdaaicloud @qawnapp @cirrusgo"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"19 out of 19 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-08-18T05:32:59.192Z","repository_id":245136334,"created_at":"2025-08-18T05:32:59.192Z","updated_at":"2025-08-18T05:32:59.192Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28506593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T10:25:30.148Z","status":"ssl_error","status_checked_at":"2026-01-17T10:25:29.718Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["docker","esnext","express","nodejs","pino","swagger-ui","tsup","typescript","vitest"],"created_at":"2024-10-06T00:05:25.304Z","updated_at":"2026-01-17T11:03:24.877Z","avatar_url":"https://github.com/MKAbuMattar.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Express Boilerplate\n\nA boilerplate for building scalable applications with Express.js, TypeScript, TSOA, and Pino Logger\n\n\u003cdiv class=\"badges\" align=\"center\"\u003e\n\n[![GitHub](https://img.shields.io/badge/github-%23181717.svg?style=for-the-badge\u0026logo=github\u0026logoColor=white)](https://github.com/MKAbuMattar/express-boilerplate)\n[![GitHub Releases](https://img.shields.io/github/v/release/MKAbuMattar/express-boilerplate?include_prereleases\u0026sort=date\u0026style=for-the-badge)](https://github.com/MKAbuMattar/express-boilerplate/releases)\n[![GitHub Stars](https://img.shields.io/github/stars/MKAbuMattar/express-boilerplate.svg?style=for-the-badge)](https://github.com/MKAbuMattar/express-boilerplate/stargazers)\n[![GitHub Forks](https://img.shields.io/github/forks/MKAbuMattar/express-boilerplate.svg?style=for-the-badge)](https://github.com/MKAbuMattar/express-boilerplate/forks)\n[![GitHub Issues](https://img.shields.io/github/issues/MKAbuMattar/express-boilerplate.svg?style=for-the-badge)](https://github.com/MKAbuMattar/express-boilerplate/issues)\n[![GitHub License](https://img.shields.io/github/license/MKAbuMattar/express-boilerplate.svg?style=for-the-badge)](LICENSE)\n[![Node.js Version](https://img.shields.io/badge/node-%3E%3D%2020.0.0-brightgreen.svg?style=for-the-badge\u0026logo=node.js\u0026logoColor=white)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/language-TypeScript-blue.svg?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![CI Pipeline](https://img.shields.io/github/actions/workflow/status/MKAbuMattar/express-boilerplate/ci-pipeline.yml?branch=main\u0026style=for-the-badge\u0026label=CI%20Pipeline)](https://github.com/MKAbuMattar/express-boilerplate/actions/workflows/ci-pipeline.yml)\n[![CI CodeQL Analysis](https://img.shields.io/github/actions/workflow/status/MKAbuMattar/express-boilerplate/codeql-analysis.yml?branch=main\u0026style=for-the-badge\u0026label=CodeQL%20Analysis)](https://github.com/MKAbuMattar/express-boilerplate/actions/workflows/codeql-analysis.yml)\n[![CI Docker Cleanup](https://img.shields.io/github/actions/workflow/status/MKAbuMattar/express-boilerplate/docker-image-cleanup.yml?branch=main\u0026style=for-the-badge\u0026label=CI%20Docker%20Cleanup)](https://github.com/MKAbuMattar/express-boilerplate/actions/workflows/docker-image-cleanup.yml)\n\n\u003c/div\u003e\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Features](#features)\n- [Getting Started](#getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Installation](#installation)\n- [Usage](#usage)\n  - [Running the Server](#running-the-server)\n  - [Building for Production](#building-for-production)\n  - [Running with Docker](#running-with-docker)\n- [Project Structure](#project-structure)\n- [Testing](#testing)\n- [Git Strategy](#git-strategy)\n  - [Branches](#branches)\n  - [Workflow](#workflow)\n  - [Semantic Commit Messages and Versioning](#semantic-commit-messages-and-versioning)\n- [GitHub Environments](#github-environments)\n  - [Why Use GitHub Environments?](#why-use-github-environments)\n  - [Setting Up GitHub Environments](#setting-up-github-environments)\n  - [Using Secrets in Your Workflow](#using-secrets-in-your-workflow)\n  - [Best Practices for Managing GitHub Environments](#best-practices-for-managing-github-environments)\n- [Running the Server with Docker and GitHub Container Registry (ghcr.io)](#running-the-server-with-docker-and-github-container-registry-ghcrio)\n  - [Login to GitHub Container Registry](#login-to-github-container-registry)\n  - [Run the Docker Container](#run-the-docker-container)\n    - [Explanation of the Command:](#explanation-of-the-command)\n  - [Verify the Container is Running](#verify-the-container-is-running)\n- [Contributing](#contributing)\n  - [Additional Guidelines](#additional-guidelines)\n- [License](#license)\n- [Further Reading](#further-reading)\n\n## Introduction\n\nThis boilerplate provides a strong foundation for building applications using Express.js and TypeScript. It follows best practices for code quality, structure, and development workflow. The repository also supports Docker and includes preconfigured Git workflows for streamlined project management.\n\n## Features\n\n- **Express.js** with **TypeScript**: Combines the simplicity of Express.js with the type safety and scalability of TypeScript.\n- **Docker** support: Ensures consistent environment setups across different machines, simplifying deployment and scaling.\n- Centralized **logging** with [Pino](https://getpino.io/): A high-performance logger designed to handle heavy workloads with minimal overhead.\n- **Error handling** middleware: Built-in centralized error handling to manage different error types efficiently.\n- Unit and integration testing with [Vitest](https://vitest.dev/): Fast and simple testing for both unit and integration tests.\n- **API documentation** with OpenAPI Swagger: Automatically generate API documentation from your codebase.\n- **Linting** and **Formatting** with [Biome](https://biomejs.dev/): Ensures code consistency and quality across the project.\n- **GitHub Actions** for CI/CD pipelines: Automates testing, linting, and deployment workflows.\n- **Semantic Versioning** and **Conventional Commits**: Ensures a structured release process and maintainable commit history.\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) (v20 or later)\n- [Docker](https://www.docker.com/get-started) (optional, for containerization)\n\n### Installation\n\n1. Clone the repository:\n\n   ```sh\n   git clone https://github.com/MKAbuMattar/express-boilerplate.git\n   cd express-boilerplate\n   ```\n\n2. Install dependencies:\n\n   ```sh\n   pnpm install\n   ```\n\n3. Set up environment variables:\n\n   ```sh\n   cp .env.example .env\n   ```\n\n## Usage\n\n### Running the Server\n\nTo start the development server, run:\n\n```sh\npnpm dev\n```\n\nThe server will start on the port specified in your `.env` file (default: 8080).\n\n### Building for Production\n\nTo build the project for production:\n\n```sh\npnpm build\n```\n\nThen, to start the production server:\n\n```sh\npnpm start\n```\n\n### Running with Docker\n\nUsing Docker helps maintain a consistent development environment across machines. To build and run the project using Docker, use the following commands:\n\n```sh\ndocker-compose up -d --build\n```\n\n## Project Structure\n\n```\nexpress-boilerplate/\n├── .github/               # GitHub configurations for CI/CD and issue templates\n├── .vscode/               # VSCode-specific settings for workspace\n├── plugins/               # Custom plugins (e.g., Pino transports)\n├── src/                   # Core application source code\n│   ├── api/               # API routes and controllers\n│   ├── bin/               # Application entry point (startup scripts)\n│   ├── configs/           # Configuration files for logger, environment, etc.\n│   ├── docs/              # API documentation and OpenAPI specs\n│   ├── libs/              # Reusable libraries\n│   ├── middlewares/       # Custom middleware logic\n│   ├── models/            # Data models and schemas\n│   ├── schemas/           # Validation schemas\n│   ├── utils/             # Utility functions for the app\n│   ├── validations/       # Business logic validations\n│   └── index.ts           # Main server file\n├── Dockerfile             # Docker configuration\n├── compose.yml            # Docker Compose for multi-service applications\n├── .env.example           # Example environment variables\n├── LICENSE                # License file\n├── package.json           # Project metadata and scripts\n├── tsconfig.json          # TypeScript configuration\n└── README.md              # Project documentation\n```\n\n## Testing\n\nTesting is crucial to ensure code reliability and prevent regressions. This project uses [Vitest](https://vitest.dev/) for running unit and integration tests.\n\n- **Unit Tests**: Test individual units of code in isolation.\n- **Integration Tests**: Test the interaction between different units of code.\n\n- **Test Files**: Test files are located in the `src` directory with the `.test.ts` extension.\n  ```sh\n  pnpm test\n  ```\n- **Coverage Reports**: To generate a code coverage report:\n  ```sh\n  pnpm test:cov\n  ```\n- **Watch Mode**: To run tests in watch mode (ideal for active development):\n  ```sh\n  pnpm test:dev\n  ```\n\n\u003e [!TIP]\n\u003e Focus on writing tests that verify the behavior of the code, not implementation details.\n\n## Git Strategy\n\n### Branches\n\n- `main`: Reflects the production-ready state of the source code.\n- `develop`: Contains the latest delivered changes for the next release.\n\n### Workflow\n\n1. Create a new branch from `main` for each feature or bug fix.\n   - Use descriptive branch names with a prefix (e.g., `feat/`, `fix/`).\n2. Make changes and commit them.\n   - Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.\n   - Write descriptive commit messages.\n3. Push the branch to the remote repository.\n4. Create a pull request to merge the branch into `develop`.\n5. After approval, merge the pull request into `develop`.\n6. Create a pull request to merge `develop` into `main`.\n7. After approval, merge the pull request into `main`.\n\n### Semantic Commit Messages and Versioning\n\nThis project adheres to [Semantic Versioning](https://semver.org/) and uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to manage releases. Every commit message and version change should follow this standard:\n\n- **fix**: Patches a bug in your codebase (`PATCH` release) or a hotfix.\n  ```sh\n  git commit -m \"fix(api): fix health check route\"\n  ```\n- **feat**: Introduces a new feature (`MINOR` release) or enhancement.\n  ```sh\n  git commit -m \"feat(api): add user route\"\n  ```\n- **BREAKING CHANGE**: Introduces breaking changes (`MAJOR` release) that require a manual update.\n  ```sh\n  git commit -m \"feat!(api): change user route to use UUID\"\n  ```\n- **chore**: Updates dependencies, refactors code, or makes other changes that don't affect the user-facing code.\n  ```sh\n  git commit -m \"chore: update dependencies\"\n  ```\n- **docs**: Updates documentation, README, or other non-code files.\n  ```sh\n  git commit -m \"docs: update README\"\n  ```\n- **ci**: Updates CI/CD configurations or workflows.\n  ```sh\n  git commit -m \"ci: add GitHub Actions workflow\"\n  ```\n\n## GitHub Environments\n\nGitHub environments empower you to manage deployment settings and configure workflows in GitHub Actions more effectively. This feature enhances the security, control, and visibility of your CI/CD pipeline. Below, you'll find a step-by-step guide to setting up environments and securely managing secrets, such as `PAT_TOKEN`, for Docker image builds.\n\n### Why Use GitHub Environments?\n\nUsing GitHub Environments offers several advantages:\n\n- **Security**: Secrets stored in environments are encrypted, ensuring that sensitive information is only accessible to workflows running within those environments.\n- **Controlled Deployments**: You can enforce rules for approval before deployments, ensuring that changes are reviewed before going live.\n- **Environment-Specific Settings**: Manage different configurations tailored for development, staging, and production, reducing the risk of errors during deployment.\n\n### Setting Up GitHub Environments\n\nFollow these steps to set up GitHub Environments for your project:\n\n1. **Navigate to Your Repository**:\n\n   - Open your web browser and go to your GitHub repository.\n\n2. **Access Environment Settings**:\n\n   - Click on the **Settings** tab at the top of the repository page.\n   - In the left sidebar, find and select **Environments** under the **Security** section.\n\n3. **Create a New Environment**:\n\n   - Click the **New environment** button.\n   - Provide a meaningful name for your environment (e.g., `development`, `staging`, `production`) to indicate its purpose.\n   - (Optional) Configure specific rules, such as requiring manual approval for deployment, to enhance control over the process.\n\n4. **Add Secrets to Your Environment**:\n   - After creating your environment, click on its name to access its settings.\n   - In the **Secrets** section, click on **Add secret**.\n   - Enter `PAT_TOKEN` as the secret name and paste your Personal Access Token into the value field.\n   - Click **Add secret** to save the secret securely.\n\n### Using Secrets in Your Workflow\n\nTo utilize the `PAT_TOKEN` secret in your GitHub Actions workflow for building Docker images, reference the secret using the syntax shown in the example workflow below. You can find this configuration in your [docker-image.yml](.github/workflows/docker-image.yml) file:\n\n```yaml\nname: Docker Image CI\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\npermissions:\n  contents: read\n  issues: write\n  pull-requests: write\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    environment: development # Specify the environment\n\n    steps:\n      - uses: actions/checkout@v4\n\n      # Log in to the GitHub Container Registry only on main branch pushes\n      - name: Login to GitHub Container Registry\n        if: github.ref == 'refs/heads/main'\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.PAT_TOKEN }}\n\n      # Add additional steps here (e.g., building and pushing the Docker image)\n```\n\n### Best Practices for Managing GitHub Environments\n\n- **Limit Access**: Only grant access to environments to those who require it. Utilize branch protection rules to ensure that only specific users can deploy to production.\n- **Review Approvals**: For sensitive environments, set up an approval process to require reviews before deployments occur. This adds a layer of safety to your deployment strategy.\n- **Monitor Usage**: Regularly review and audit your environment settings and secrets to ensure compliance with best practices and security policies.\n\nBy following these guidelines, you can establish a robust and secure CI/CD process that enhances your development workflow while maintaining best practices for managing sensitive information.\n\n## Running the Server with Docker and GitHub Container Registry (ghcr.io)\n\n### Login to GitHub Container Registry\n\nBefore running the Docker container, ensure you're logged into the GitHub Container Registry (GHCR). Replace `TOKEN` and `USERNAME` with your GitHub Personal Access Token (PAT) and GitHub username, respectively:\n\n```sh\necho \u003cYOUR_PAT_TOKEN\u003e | docker login ghcr.io -u \u003cUSERNAME\u003e --password-stdin\n```\n\n- **`\u003cYOUR_PAT_TOKEN\u003e`**: Your GitHub Personal Access Token with access to the container registry.\n- **`\u003cUSERNAME\u003e`**: Your GitHub username.\n\nYou can create a GitHub PAT [here](https://github.com/settings/tokens), ensuring it has the `read:packages` scope.\n\n\u003e [!NOTE]\n\u003e This step is required to pull the Docker image from the GitHub Container Registry for private repositories.\n\n### Run the Docker Container\n\nOnce logged in, run the Docker container using the following command. Be sure to replace the environment variables and image information with your specific values:\n\n```sh\ndocker run -d -p 8080:8080 \\\n    -e NODE_ENV=\"development\" \\\n    -e PORT=\"8080\" \\\n    -e HOST=\"localhost\" \\\n    -e CORS_WHITELIST=\"*\" \\\n    -e API_KEY=\"uk6XUcp7Hj6f4O+w6b\u003cO\" \\\n    ghcr.io/\u003cUSERNAME\u003e/\u003cREPOSITORY_NAME\u003e:\u003cDIGEST\u003e\n```\n\n#### Explanation of the Command:\n\n- **`-p 8080:8080`**: Maps the container's internal port `8080` to port `8080` on your machine.\n- **`-e NODE_ENV=\"development\"`**: Sets the `NODE_ENV` environment variable to `development`. Other options might be `production` or `staging` depending on your setup.\n- **`-e PORT=\"8080\"`**: Specifies the port on which the app should run inside the container.\n- **`-e HOST=\"localhost\"`**: Defines the host, typically `localhost` for local development.\n- **`-e CORS_WHITELIST=\"*\"`**: Allows all domains by using a wildcard for CORS. Adjust this according to your security needs.\n- **`-e API_KEY=\"uk6XUcp7Hj6f4O+w6b\u003cO\"`**: An API key required by your application. Replace with your actual key.\n- **`ghcr.io/\u003cUSERNAME\u003e/\u003cREPOSITORY_NAME\u003e:\u003cDIGEST\u003e`**: Replace `\u003cUSERNAME\u003e`, `\u003cREPOSITORY_NAME\u003e`, and `\u003cDIGEST\u003e` with your GitHub username, the repository name, and the specific image digest or tag (e.g., `latest`).\n\n```sh\ndocker run -d --network host \\\n    -e NODE_ENV=\"production\" \\\n    -e PORT=\"8080\" \\\n    -e HOST=\"0.0.0.0\" \\\n    -e CORS_WHITELIST=\"https://example.com\" \\\n    -e API_KEY=\"superSecretAPIKey123\" \\\n    ghcr.io/mkabumattar/express-boilerplate:latest\n```\n\n### Verify the Container is Running\n\nTo check if your container is running, you can use the following command:\n\n```sh\ndocker ps\n```\n\nThis will display a list of all active containers. You should see your container listed with the port mappings (`8080:8080` in this case).\n\n## Contributing\n\nContributions are welcome! Please follow the guidelines in [CONTRIBUTING.md](.github/CONTRIBUTING.md). If you don't have this file, consider creating one with instructions for how to fork the project, make changes, and submit pull requests.\n\n### Additional Guidelines\n\n- Follow the coding style outlined in the `Biome` configuration files.\n- Use the PR template provided in the `.github` folder to ensure all necessary details are included when submitting a pull request.\n- Report issues using the provided issue template.\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details by [@MKAbuMattar](https://github.com/MKAbuMattar).\n\n## Further Reading\n\n- [Express.js Documentation](https://expressjs.com/)\n- [TypeScript Documentation](https://www.typescriptlang.org/docs/)\n- [Docker Documentation](https://docs.docker.com/)\n- [GitHub Actions Documentation](https://docs.github.com/en/actions)\n- [Pino Logger](https://getpino.io/)\n- [Vitest Testing Framework](https://vitest.dev/)\n- [Biome Linting](https://biomejs.dev/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkabumattar%2Fexpress-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkabumattar%2Fexpress-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkabumattar%2Fexpress-boilerplate/lists"}