{"id":15687427,"url":"https://github.com/lirantal/nodepulse","last_synced_at":"2025-05-07T14:25:22.777Z","repository":{"id":40337213,"uuid":"266109056","full_name":"lirantal/nodepulse","owner":"lirantal","description":"NodePulse is a live Node.js dashboard","archived":false,"fork":false,"pushed_at":"2023-06-23T03:47:50.000Z","size":2347,"stargazers_count":9,"open_issues_count":29,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-07T14:25:16.589Z","etag":null,"topics":["dashboard","live","nodejs","statistics"],"latest_commit_sha":null,"homepage":"https://nodepulse.web.app/","language":"Vue","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/lirantal.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-22T12:48:25.000Z","updated_at":"2023-04-24T17:04:27.000Z","dependencies_parsed_at":"2024-10-23T20:40:25.458Z","dependency_job_id":"c3973129-2873-41b6-8f29-12e712d80c2e","html_url":"https://github.com/lirantal/nodepulse","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirantal%2Fnodepulse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirantal%2Fnodepulse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirantal%2Fnodepulse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lirantal%2Fnodepulse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lirantal","download_url":"https://codeload.github.com/lirantal/nodepulse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252893628,"owners_count":21820849,"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":["dashboard","live","nodejs","statistics"],"created_at":"2024-10-03T17:48:23.128Z","updated_at":"2025-05-07T14:25:22.757Z","avatar_url":"https://github.com/lirantal.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NodePulse\n\n\u003e NodePulse is a live Node.js dashboard\n\n## Build Setup\n\n```bash\n# install dependencies\n$ yarn install\n\n# serve with hot reload at localhost:8080\n$ yarn dev\n\n# build for production and launch server\n$ yarn build\n$ yarn start\n\n# generate static project\n$ yarn generate\n```\n\n## Google Cloud Run\n\n### Initialize\n\nLogin with glcoud:\n\n```bash\ngcloud auth login\n```\n\nFollow that with ensuring the nodepulse project is set to active:\n\n```\ngcloud config set project nodepulse\n```\n\n### Build docker image locally\n\n```\ndocker build . -t nodepulse\n```\n\n### Create an application credentials\n\nTo access the google APIs for secrets and otherwise, we'll need to\ncreate a local application credentials:\n\n```\ngcloud auth application-default login\n```\n\nAnd follow with your google account on GCP for access granting.\n\n## GitHub Actions CI\n\n### Docker Hub image build\n\nThe following YAML builds the docker image and pushes it to Docker Hub as a public image.\n\nCreate the `DOCKER_USERNAME` and `DOCKER_PASSWORD` secrets on the repository's settings page.\nGrab the tokens for these from the Docker account settings page.\n\n```yaml\nname: Publish Docker\non:\n  push:\n    branches:\n      - master\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@master\n      - uses: docker/build-push-action@v1\n        name: Build and push Docker images\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n          repository: lirantal/nodepulse\n          tags: latest\n```\n\n### Secrets setup\n\nWe'll need to work with some sensitive API keys such as the GitHub token.\nTo keep them same, we'll store and access them via Secrets Manager.\n\n1. To begin with, enable the Secrets Manager on GCP\n2. Once you obtained the GitHub token let's create it as a secret:\n\n```sh\necho \"GITHUB_TOKEN_GOES_HERE\" | gcloud secrets create \\\n  --data-file=- --replication-policy=automatic github-token\n```\n\nWe called this secret `github-token` and this is what we'll use to identify and access it in the future.\n\n3. We'll need to find out the default IAM service account that will be used by the running container:\n\n```sh\ngcloud iam service-accounts list\n```\n\nIt will show up on the list with a name of `Default compute service account`.\nFor example:\n\n```\n989220244463-compute@developer.gserviceaccount.com\n```\n\n4. Grant access only to this secret:\n\n```sh\ngcloud secrets add-iam-policy-binding github-token --member=serviceAccount:989220244463-compute@developer.gserviceaccount.com \\\n  --role=roles/secretmanager.secretReader --project=nodepulse\n```\n\n### Build and Deploy to Google Cloud\n\n#### Setup\n\nThe following is the first time only setup that needs to be done to provide access\nto the GitHub CI to deploy new container images.\n\nEnable the Google Cloud Run APIs on the project:\n\n1. Visit https://console.cloud.google.com/flows/enableapi?apiid=cloudbuild.googleapis.com,run.googleapis.com\n2. Choose the project from the drop-down list and hit continue\n\nCreate a service account to be used on the GitHub Action so we can deploy the image built to Google Cloud Run as a service container:\n\n```sh\n# nodepulse-deployer is the service account name\ngcloud iam service-accounts create nodepulse-deployer\n\n# provide the service-account the `run.admin` role to allow it to deploy\n# see: https://cloud.google.com/run/docs/reference/iam/roles\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role \"roles/run.admin\"\n\n# provide the service-account the `builder editor` and `builder viewer`\n# role so it can create and update images to google container registry\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role \"roles/cloudbuild.builds.editor\"\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role \"roles/cloudbuild.builds.viewer\"\n\n# and then grant it the following membership and role\n# so it can assume this user for the runtime service\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role=\"roles/iam.serviceAccountUser\"\n\n# allow the service account to view/create storage assets (the container images)\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role=\"roles/storage.objectAdmin\"\n\n# allow the service account to view logs required for the container build\ngcloud projects add-iam-policy-binding nodepulse --member \"serviceAccount:nodepulse-deployer@nodepulse.iam.gserviceaccount.com\" --role=\"roles/viewer\"\n\n# export the service-account details to a file called gcloud_auth.json\n# as follows:\ngcloud iam service-accounts keys create gcloud_auth.json --iam-account nodepulse-deployer@nodepulse.iam.gserviceaccount.com --project nodepulse\n```\n\nThen update the GitHub repository's secrets with the following\nkeys and values:\n\n```\n# the contents of gcloud_auth.json file\nRUN_SA_KEY=\n\n# the cloud service name\nCLOUD_RUN_SERVICE_NAME=nodepulse-ssr\n```\n\n#### Deploy to Google Cloud Run from CI\n\nCreate a `.github/workflows/deploy.yml` file that includes the following to build and deploy the image on a push to `master` branch.\n\n```\n# Copyright 2019 Google, LLC.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nname: Build and Deploy to Cloud Run\n\non:\n  push:\n    branches:\n      - master\n\nenv:\n  PROJECT_ID: ${{ secrets.RUN_PROJECT }}\n  RUN_REGION: us-central1\n  SERVICE_NAME: ${{ secrets.CLOUD_RUN_SERVICE_NAME }}\n\njobs:\n  setup-build-deploy:\n    name: Setup, Build, and Deploy\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v2\n\n      # Setup gcloud CLI\n      - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master\n        with:\n          version: '290.0.1'\n          service_account_key: ${{ secrets.RUN_SA_KEY }}\n          project_id: ${{ secrets.RUN_PROJECT }}\n\n      # Build and push image to Google Container Registry\n      - name: Build\n        run: |-\n          gcloud builds submit \\\n            --quiet \\\n            --tag \"gcr.io/$PROJECT_ID/$SERVICE_NAME:$GITHUB_SHA\"\n\n      # Deploy image to Cloud Run\n      - name: Deploy\n        run: |-\n          gcloud run deploy \"$SERVICE_NAME\" \\\n            --quiet \\\n            --region \"$RUN_REGION\" \\\n            --image \"gcr.io/$PROJECT_ID/$SERVICE_NAME:$GITHUB_SHA\" \\\n            --platform \"managed\" \\\n            --allow-unauthenticated\n```\n\n#### Deploy to Google Cloud Run from local dev\n\nTo experiment with building and deploying the container from localhost\nso that you can avoid the cumbersome and delay of git pushes to the\nremote registry you can use the following:\n\n```sh\n# build the image:\ngcloud builds submit \\\n            --quiet \\\n            --tag \"gcr.io/nodepulse/nodepulse-ssr\"\n\n# deploy it:\ngcloud run deploy nodepulse-ssr \\\n          --quiet \\\n          --region us-central1 \\\n          --image \"gcr.io/nodepulse/nodepulse-ssr\" \\\n          --platform \"managed\" \\\n          --allow-unauthenticated\n```\n\n### Connect to Firebase Hosting\n\nWe can connect the Cloud Run service to Firebase Hostin, which will allow\nus to use the capability of short URLs, such as:\n\n```\nhttps://nodepulse.web.app\n```\n\nAt this point, that's the only reason to connect Firebase Hosting capabilities\ninto the current GCP project.\n\nIn the root directory, run:\n\n```sh\nfirebase init\n```\n\nIn the interactive CLI choose:\n\n1. Hosting project\n2. Use existing project, and select `nodepulse`\n3. Confirm the `public/` directory for resources\n\nThe CLI will scaffold default index files in the `public/` directory\nwhich we need to remove. We have to remove them because if these files\nexist then the rewrite rules won't affect the top-level domain request\nsuch as hits to `nodepulse.web.app`.\n\n```sh\nrm public/*\n```\n\nThen update `firebase.json` to include the rewrite rules to forward\nall requests to files not found to the Cloud Run Service:\n\n```json\n{\n  \"hosting\": {\n    \"public\": \"public\",\n    \"ignore\": [\"firebase.json\", \"**/.*\", \"**/node_modules/**\"],\n    \"rewrites\": [\n      {\n        \"source\": \"**\",\n        \"run\": {\n          \"serviceId\": \"nodepulse-ssr\",\n          \"region\": \"us-central1\"\n        }\n      }\n    ]\n  }\n}\n```\n\nAnd deploy it:\n\n```sh\nfirebase deploy\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flirantal%2Fnodepulse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flirantal%2Fnodepulse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flirantal%2Fnodepulse/lists"}