{"id":15371112,"url":"https://github.com/jch254/docker-node-terraform-aws","last_synced_at":"2026-03-17T21:04:39.577Z","repository":{"id":56457810,"uuid":"69950055","full_name":"jch254/docker-node-terraform-aws","owner":"jch254","description":"Docker-powered build/deployment environment for Node.js projects","archived":false,"fork":false,"pushed_at":"2025-09-29T08:00:00.000Z","size":101,"stargazers_count":12,"open_issues_count":1,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-29T09:29:33.691Z","etag":null,"topics":["aws","aws-codebuild","bitbucket-pipelines","build-environment","ci","codebuild","docker","docker-node-terraform-aws","nodejs","terraform"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/jch254/docker-node-terraform-aws/","language":"Dockerfile","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/jch254.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-10-04T09:15:50.000Z","updated_at":"2025-09-29T08:00:03.000Z","dependencies_parsed_at":"2024-10-16T11:40:38.151Z","dependency_job_id":"5bd9df6f-9a45-4327-b3d0-0e1450f7d9f4","html_url":"https://github.com/jch254/docker-node-terraform-aws","commit_stats":{"total_commits":103,"total_committers":3,"mean_commits":"34.333333333333336","dds":"0.029126213592232997","last_synced_commit":"5e407c7e0f82c6a99a40143afca8b3dcd6cb5987"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jch254/docker-node-terraform-aws","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jch254%2Fdocker-node-terraform-aws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jch254%2Fdocker-node-terraform-aws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jch254%2Fdocker-node-terraform-aws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jch254%2Fdocker-node-terraform-aws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jch254","download_url":"https://codeload.github.com/jch254/docker-node-terraform-aws/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jch254%2Fdocker-node-terraform-aws/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30631435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T17:32:55.572Z","status":"ssl_error","status_checked_at":"2026-03-17T17:32:38.732Z","response_time":56,"last_error":"SSL_read: 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":["aws","aws-codebuild","bitbucket-pipelines","build-environment","ci","codebuild","docker","docker-node-terraform-aws","nodejs","terraform"],"created_at":"2024-10-01T13:45:26.763Z","updated_at":"2026-03-17T21:04:39.572Z","avatar_url":"https://github.com/jch254.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docker-node-terraform-aws\n\n[![Docker Hub](https://img.shields.io/docker/pulls/jch254/docker-node-terraform-aws)](https://hub.docker.com/r/jch254/docker-node-terraform-aws) [![Docker Image Size](https://img.shields.io/docker/image-size/jch254/docker-node-terraform-aws/latest)](https://hub.docker.com/r/jch254/docker-node-terraform-aws) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\nContainer image providing a consistent build \u0026 deployment toolchain for Node.js projects targeting AWS infrastructure with Terraform. Designed for CI systems like [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) and [AWS CodeBuild](https://aws.amazon.com/codebuild).\n\nFocused goals:\n\n* Stable, reproducible CI environment (Node + Terraform + AWS CLI v2)\n* Lean Alpine base (fast pulls) while retaining essential utilities\n* Straightforward override of Terraform version \u0026 deterministic tagging\n* Proven to work in CodeBuild (avoid SINGLE_BUILD_CONTAINER_DEAD via correct architecture)\n\n## Included Tooling (see `Dockerfile` for authoritative list)\n\n| Tool | Version / Source | Notes |\n|------|------------------|-------|\n| Node.js | 22 (node:22-alpine) | Use tag `22.x` (pin by digest for immutability) |\n| Terraform | 1.13.1 (default) | Override with `--build-arg TERRAFORM_VERSION=...` |\n| AWS CLI v2 | Alpine repo | Installed via `apk add aws-cli` |\n| Python 3 + pip | Alpine repo | For helper scripts / AWS tooling |\n| npm | Bundled with Node | Core JS package manager |\n| pnpm | Latest (global install) | Fast dependency installs |\n| jq / curl / git / zip / unzip / bash / wget | Utilities | Common scripting + archive tasks |\n\nNot included by default: Yarn (available via Corepack: `corepack enable yarn`), extra pagers (less, groff), OpenSSL headers, build toolchains (add as needed).\n\nNo Docker `HEALTHCHECK` is defined to keep startup overhead minimal. CI systems typically exit on command failure; a healthcheck is seldom necessary. Add one if you run long‑lived build agents.\n\n## Tags \u0026 Versioning\n\nPrimary maintained tag in this repo: `22.x` (Node 22). The `latest` tag currently points to the same major (verify with `docker pull jch254/docker-node-terraform-aws:latest` then inspect digest). Older / newer majors may exist in other branches or historical tags; pin by digest for reproducibility:\n\n```bash\ndocker pull jch254/docker-node-terraform-aws:22.x@sha256:\u003cdigest\u003e\n```\n\nWhy digest pinning?\n\n* Guarantees identical toolchain across parallel / future CI runs\n* Enables staged rollouts (update tag, keep old digest in rollback config)\n\nTo discover the digest after pulling:\n\n```bash\ndocker inspect --format='{{index .RepoDigests 0}}' jch254/docker-node-terraform-aws:22.x\n```\n\n## Quick Start\n\nPull and run an interactive shell:\n\n```bash\ndocker run -it --rm jch254/docker-node-terraform-aws:22.x bash\n```\n\nCheck installed versions:\n\n```bash\ndocker run --rm jch254/docker-node-terraform-aws:22.x \"node --version \u0026\u0026 terraform version \u0026\u0026 aws --version\"\n```\n\n## Overriding Terraform Version (local build)\n\n```bash\ndocker build --build-arg TERRAFORM_VERSION=1.13.1 -t my/ci-image:tf-1.13.1 .\n```\n\nYou can substitute any published Terraform version; architecture (amd64 / arm64) is auto-detected during build.\n\nFor CodeBuild (currently x86_64 / amd64), ensure you build / push an amd64 image (or multi-arch) and explicitly pull it locally if you're on Apple Silicon:\n\n```bash\ndocker build --platform linux/amd64 -t jch254/docker-node-terraform-aws:22.x .\n```\n\n## Bitbucket Pipelines Example\n\n```yaml\nimage: jch254/docker-node-terraform-aws:22.x\n\npipelines:\n\tdefault:\n\t\t- step:\n\t\t\t\tname: Terraform Plan\n\t\t\t\tscript:\n\t\t\t\t\t- node --version\n\t\t\t\t\t- terraform -chdir=infrastructure init\n\t\t\t\t\t- terraform -chdir=infrastructure plan -out tfplan\n```\n\n## AWS CodeBuild `buildspec.yml` Example\n\n```yaml\nversion: 0.2\nphases:\n\tinstall:\n\t\truntime-versions: {}\n\tpre_build:\n\t\tcommands:\n\t\t\t- node --version\n\t\t\t- terraform -chdir=infrastructure init\n\tbuild:\n\t\tcommands:\n\t\t\t- terraform -chdir=infrastructure apply -auto-approve\n```\n\nConfigure the project to use the public image `jch254/docker-node-terraform-aws:22.x` (or a digest‑pinned variant) as a custom image.\n\nAdditional samples:\n\n* `buildspec-example.yml` – fuller workflow with conditional apply \u0026 caching\n* `buildspec-minimal.yml` – lean template useful for diagnosing environment problems\n\n## Caching Tips\n\n* Terraform plugin/cache directory: mount a volume to persist between runs:\n\n```bash\ndocker run -v \"$PWD\":/workspace -v tf_plugins:/root/.terraform.d/plugin-cache ...\n```\n\nThen add to `~/.terraformrc` (in your repo) if you want explicit plugin cache control:\n\n```hcl\nplugin_cache_dir = \"/root/.terraform.d/plugin-cache\"\n```\n\n* Node/Yarn dependencies: in CI, leverage built-in caching (Bitbucket `caches: node`) or mount a volume locally.\n\n## Architecture Notes\n\nAWS CodeBuild standard environments presently require `linux/amd64`. If you build this image on an ARM (e.g. Apple M-series) and push without a multi‑arch manifest, CodeBuild may pull an incompatible layer or fail early with opaque errors (e.g. `SINGLE_BUILD_CONTAINER_DEAD`). Always build with `--platform linux/amd64` (or use `docker buildx build --platform linux/amd64,linux/arm64 ...` for multi‑arch) before pushing.\n\n## Updating / Maintenance\n\n* Base updates: periodically rebuild when upstream `node:\u003cmajor\u003e-alpine` publishes security patches.\n* Terraform: bump default by updating `ARG TERRAFORM_VERSION` in `Dockerfile` (and rebuild / retag).\n* Tag discipline: prefer immutable CI references (e.g. digest pin) if supply chain repeatability is critical.\n\n## IAM \u0026 Terraform Troubleshooting\n\nCommon Terraform plan/apply AWS errors in CI \u0026 resolutions:\n\n| Symptom | Likely Cause | Fix |\n|---------|--------------|-----|\n| `AccessDenied: ec2:DescribeVpcAttribute` | Missing EC2 read perms on build role | Add `ec2:Describe*` minimal set needed by your data sources |\n| `UnauthorizedOperation: logs:ListTagsForResource` | CloudWatch Logs tag listing blocked | Grant `logs:ListTagsForResource` (or broader read if acceptable) |\n| `AccessDenied: ecr:DescribeRepositories` | Build role lacks ECR read | Add `ecr:DescribeRepositories` or scoped resource ARNs |\n\nLeast‑privilege tip: run `terraform plan` with `TF_LOG=DEBUG` (temporarily) to enumerate denied actions, aggregate, then tighten to wildcard groups (e.g. `ec2:Describe*`) where appropriate.\n\nEnvironment vars helpful in CI:\n\n```bash\nexport TF_IN_AUTOMATION=true\nexport AWS_PAGER=\"\"\nexport NODE_OPTIONS=\"--max-old-space-size=512\"  # adjust for instance size\n```\n\n## Building Docker Images Inside CodeBuild\n\nIf you see:\n\n```text\nERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\n```\n\nThe build container cannot reach a Docker daemon. Fix options:\n\n### 1. (Recommended) Enable Privileged Mode\n\nIn the CodeBuild project settings enable \"Privileged\" (or in IaC `privilegedMode: true`). This mounts the host Docker daemon socket inside your build so `docker build` works.\n\nMinimum IAM permissions added to the CodeBuild role when pushing to ECR (adjust resource ARNs):\n\n```json\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{ \"Effect\": \"Allow\", \"Action\": [\"ecr:GetAuthorizationToken\"], \"Resource\": \"*\" },\n\t\t{ \"Effect\": \"Allow\", \"Action\": [\n\t\t\t\t\"ecr:BatchCheckLayerAvailability\",\n\t\t\t\t\"ecr:CompleteLayerUpload\",\n\t\t\t\t\"ecr:DescribeRepositories\",\n\t\t\t\t\"ecr:BatchGetImage\",\n\t\t\t\t\"ecr:InitiateLayerUpload\",\n\t\t\t\t\"ecr:PutImage\",\n\t\t\t\t\"ecr:UploadLayerPart\"\n\t\t\t], \"Resource\": \"arn:aws:ecr:\u003cregion\u003e:\u003caccount\u003e:repository/\u003crepo-name\u003e\" }\n\t]\n}\n```\n\nTypical buildspec excerpt:\n\n```yaml\nphases:\n\tpre_build:\n\t\tcommands:\n\t\t\t- aws --version\n\t\t\t- aws ecr get-login-password | docker login --username AWS --password-stdin \"$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com\"\n\tbuild:\n\t\tcommands:\n\t\t\t- docker build --platform linux/amd64 -t \"$IMAGE_REPO_NAME:$IMAGE_TAG\" .\n\t\t\t- docker tag \"$IMAGE_REPO_NAME:$IMAGE_TAG\" \"$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG\"\n\tpost_build:\n\t\tcommands:\n\t\t\t- docker push \"$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG\"\n```\n\nAdd a quick guard early (helps fail fast if privileged not enabled):\n\n```bash\ntest -S /var/run/docker.sock || { echo \"Docker socket missing (privileged mode off)\"; exit 1; }\n```\n\n### 2. Use Kaniko (No Privileged Mode)\n\nIf you cannot enable privileged mode, swap Docker daemon usage for [Kaniko]. Example (add to this image at runtime):\n\n```bash\ncurl -sSL https://github.com/GoogleContainerTools/kaniko/releases/latest/download/executor-linux-amd64 -o /usr/local/bin/kaniko \u0026\u0026 chmod +x /usr/local/bin/kaniko\nkaniko --destination \"$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG\" --context . --build-arg TERRAFORM_VERSION=1.13.1\n```\n\nSupply `/kaniko/.docker/config.json` with ECR auth (or export `AWS_*` env vars—Kaniko supports the SDK creds).\n\n### 3. Use AWS CodeBuild Managed Builds / CodePipeline\n\nIf you only need to run Terraform (and not build container images) remove `docker build` lines entirely—this image already includes your toolchain.\n\n### 4. Install Docker CLI (if missing)\n\nThis image does not ship with the Docker CLI. If you enabled privileged mode but receive `docker: not found`, layer it:\n\n```bash\napk add --no-cache docker-cli\n```\n\nKeep this in a separate layer (or derive a child image) rather than bloating the base if most consumers do not need image builds.\n\n### Quick Decision Matrix\n\n| Need | Best Option |\n|------|-------------|\n| Build \u0026 push images (have permission) | Privileged mode + Docker CLI |\n| Build images without privileged mode | Kaniko (or BuildKit rootless) |\n| Only Terraform + Node builds | Drop Docker steps |\n| Multi-arch build inside CI | Buildx (privileged) or external pipeline |\n\nIf multi‑arch is required, add Buildx:\n\n```bash\ndocker buildx create --use --name ci-builder\ndocker buildx build --platform linux/amd64,linux/arm64 -t \"$IMAGE\" --push .\n```\n\nEnsure QEMU emulators are registered (standard CodeBuild privileged hosts usually have them, else install `qemu-user-static`).\n\n## Contributing\n\n1. Fork \u0026 branch (`feat/...` or `chore/...`).\n2. Make changes; keep layers minimal (group `apk add` lines, remove caches).\n3. Build \u0026 smoke test (force amd64 if on ARM host):\n\n```bash\ndocker build -t test-image . \u0026\u0026 docker run --rm test-image \"terraform version\"\n```\n\n1. Open PR describing rationale (tool additions, version bumps, optimizations, size/security impact).\n\n## Issues / Support\n\nPlease open a GitHub issue with:\n\n* Image tag / digest\n* CI environment (Bitbucket Pipelines, CodeBuild, local, etc.)\n* Repro steps \u0026 exact error output\n\n## Security\n\nBaseline hardening considerations (opt-in):\n\n* Run as non-root (add user + `USER` directive) if build steps permit.\n* Add vulnerability scanning (e.g. Trivy, Grype, or `docker scout cves`) in CI.\n* Pin Alpine repository snapshot (e.g. use a specific minor tag) for utility determinism.\n* Consider digest pinning of Terraform zip (verify SHA256) for supply chain integrity.\n* Trim unused package managers (remove pnpm if not needed) to reduce surface.\n\n## License\n\nReleased under the [MIT License](LICENSE). By contributing you agree that your contributions are licensed under the same MIT license.\n\n---\nPull requests to improve size, security posture, or docs are welcome.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjch254%2Fdocker-node-terraform-aws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjch254%2Fdocker-node-terraform-aws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjch254%2Fdocker-node-terraform-aws/lists"}