{"id":18258900,"url":"https://github.com/pottava/nodejs-run","last_synced_at":"2025-04-08T23:27:36.204Z","repository":{"id":235216710,"uuid":"789591567","full_name":"pottava/nodejs-run","owner":"pottava","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-23T03:29:52.000Z","size":52,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T18:20:58.223Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/pottava.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":"2024-04-21T01:44:35.000Z","updated_at":"2024-04-23T03:29:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"6b6022ba-10e7-4eca-9454-c358306d12d7","html_url":"https://github.com/pottava/nodejs-run","commit_stats":null,"previous_names":["pottava/nodejs-run"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pottava%2Fnodejs-run","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pottava%2Fnodejs-run/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pottava%2Fnodejs-run/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pottava%2Fnodejs-run/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pottava","download_url":"https://codeload.github.com/pottava/nodejs-run/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247945121,"owners_count":21022694,"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":[],"created_at":"2024-11-05T10:35:20.819Z","updated_at":"2025-04-08T23:27:36.184Z","avatar_url":"https://github.com/pottava.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Node.js on Cloud Run\n=====\n\n## Google Cloud 準備\n\n### API の有効化\n\n```sh\ngcloud services enable compute.googleapis.com artifactregistry.googleapis.com \\\n    iamcredentials.googleapis.com run.googleapis.com bigquery.googleapis.com \\\n    secretmanager.googleapis.com\n```\n\n### Artifact Registry にリポジトリを作成\n\n```sh\ngcloud artifacts repositories create apps --repository-format docker --location asia-northeast1\n```\n\n### BigQuery\n\nデータセットを作成し\n\n```sh\nbq --location \"asia-northeast1\" mk --dataset default\n```\n\nテーブルを作成します\n\n```sh\nbq mk --table --description \"Metrics table\" \\\n    --schema 'ts:TIMESTAMP,key:STRING,metric:STRING' \\\n    --time_partitioning_field ts \\\n    --time_partitioning_type DAY \\\n    default.metrics\n```\n\n### API server on Cloud Run\n\nサービスアカウントを作成し、以下の権限を付与します。\n\n- BigQuery へデータを書き込む\n- Secret Manager からデータを読み込む（次の手順）\n\n```sh\nproject_id=$( gcloud config get-value project )\ngcloud iam service-accounts create \"sa-app\" \\\n    --display-name \"SA for APIs\" --description \"Service Account for APIs\"\ngcloud projects add-iam-policy-binding \"${project_id}\" \\\n    --member \"serviceAccount:sa-app@${project_id}.iam.gserviceaccount.com\" \\\n    --role \"roles/bigquery.dataEditor\"\n```\n\n### Secret Manager\n\n外部 API 用のキーを登録\n\n```sh\necho -n \"my-super-secret-apikey\" | gcloud secrets create apikey-001 \\\n    --replication-policy \"automatic\" --data-file=-\ngcloud secrets add-iam-policy-binding apikey-001 \\\n    --member \"serviceAccount:sa-app@${project_id}.iam.gserviceaccount.com\" \\\n    --role \"roles/secretmanager.secretAccessor\"\n```\n\n## GitHub Actions によるトリガー\n\n### Workload Identity Federation の準備\n\nCI/CD 用のサービスアカウント作成\n\n```sh\ngcloud iam service-accounts create \"sa-cicd\" \\\n    --display-name \"SA for CI/CD\" --description \"Service Account for CI/CD pipelines\"\ngcloud projects add-iam-policy-binding \"${project_id}\" \\\n    --member \"serviceAccount:sa-cicd@${project_id}.iam.gserviceaccount.com\" \\\n    --role \"roles/viewer\"\ngcloud projects add-iam-policy-binding \"${project_id}\" \\\n    --member \"serviceAccount:sa-cicd@${project_id}.iam.gserviceaccount.com\" \\\n    --role \"roles/storage.admin\"\ngcloud projects add-iam-policy-binding \"${project_id}\" \\\n    --member \"serviceAccount:sa-cicd@${project_id}.iam.gserviceaccount.com\" \\\n    --role \"roles/run.developer\"\n```\n\nCI ツールと連携する Workload Identity を作り\n\n```sh\ngcloud iam workload-identity-pools create \"idpool-cicd\" --location \"global\" \\\n    --display-name \"Identity pool for CI/CD services\"\ngcloud iam workload-identity-pools providers create-oidc \"idp-github\" \\\n    --workload-identity-pool \"idpool-cicd\" --location \"global\" \\\n    --issuer-uri \"https://token.actions.githubusercontent.com\" \\\n    --attribute-mapping \"google.subject=assertion.sub,attribute.repository=assertion.repository\" \\\n    --display-name \"Workload IdP for GitHub\"\nidp_id=$( gcloud iam workload-identity-pools describe \"idpool-cicd\" \\\n    --location \"global\" --format \"value(name)\" )\n```\n\nリポジトリに対し、この SA の利用を許可します。\n\n```sh\nrepo=\u003corg-id\u003e/\u003crepo-id\u003e\ngcloud iam service-accounts add-iam-policy-binding \\\n    sa-cicd@${project_id}.iam.gserviceaccount.com \\\n    --member \"principalSet://iam.googleapis.com/${idp_id}/attribute.repository/${repo}\" \\\n    --role \"roles/iam.workloadIdentityUser\"\ncat \u003c\u003c EOF\n\nGOOGLE_CLOUD_PROJECT:\n    ${project_id}\n\nGOOGLE_CLOUD_WORKLOAD_IDP:\n    $( gcloud iam workload-identity-pools providers describe \"idp-github\" \\\n        --workload-identity-pool \"idpool-cicd\" --location \"global\" \\\n        --format \"value(name)\" )\n\nEOF\n```\n\nプロジェクトの Actions secrets and variables に以下の値を設定します。\n\n- GOOGLE_CLOUD_PROJECT: プロジェクト ID\n- GOOGLE_CLOUD_WORKLOAD_IDP: Workload Identity の IdP ID\n\n### git コマンドでパイプラインを起動\n\n```sh\ngit add .\ngit commit -m \"Add files\"\ngit push origin main\n```\n\n## ローカル開発\n\n### API サーバーの起動\n\n```sh\ncd server/src\npnpm install\nnpm run lint\nexport PROJECT_ID=$( gcloud config get-value project )\nnpm start\n```\n\nアクセスしてみる\n\n```sh\nopen http://localhost:8080\ncurl -s http://localhost:8080/api/v1/versions | jq .\ncurl -iXPOST -H 'Content-Type: application/json' -d '{\"key\":1,\"value\":\"0.1\"}' http://localhost:8080/api/v1/metrics/001\n```\n\n### Docker での API サーバー起動\n\n```sh\ndocker build -t apis server/src\ndocker run --name apis --rm -p 8080:8080 \\\n    -v \"$HOME/.config/gcloud:/app/config:ro\" \\\n    --env PROJECT_ID=$PROJECT_ID \\\n    --env CLOUDSDK_CONFIG=/app/config \\\n    --env GOOGLE_APPLICATION_CREDENTIALS=/app/config/application_default_credentials.json \\\n    apis\n```\n\n### Cloud Run への接続\n\n```sh\nendpoint=\"$( gcloud run services describe \"app\" --region \"asia-northeast1\" --format 'value(status.url)' )\"\ncurl -iXPOST -H \"Authorization: Bearer $(gcloud auth print-identity-token)\" \\\n    -H 'Content-Type: application/json' -d '{\"key\":1,\"value\":\"0.1\"}' \\\n    \"${endpoint}/api/v1/external-apis/001\"\n```\n\n\n### おまけ\n\nデプロイした Cloud Run サービスをローカルに立てたプロキシを経由してアクセスしてみるには\n\n```sh\ngcloud beta run services proxy --region asia-northeast1 app\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpottava%2Fnodejs-run","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpottava%2Fnodejs-run","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpottava%2Fnodejs-run/lists"}