I built a containerized Node.js application and configured GitHub Actions to test it, build a Docker image, and publish versioned images to GitHub Container Registry (GHCR) and Amazon Elastic Container Registry (Amazon ECR).
I configured GitHub OpenID Connect (OIDC) so the workflow could assume an AWS IAM role and receive temporary credentials, avoiding long-lived AWS access keys in GitHub.
Architecture
Developer pushes code to GitHub | v GitHub Actions | v Install dependencies | v Run automated tests | v Build Docker image | v Is this a push to main? / \ No Yes | | Stop after Authenticate to test/build AWS using OIDC | +-----+------+ | | v v Amazon ECR GitHub Container Registry (GHCR)
The workflow was configured to run tests and build the Docker image for pull requests targeting main. It published images only after pushes to main.
Technology Stack
Application: Node.js and Express
Containerization: Docker
Automated testing: Node.js test runner and Supertest
CI/CD: GitHub Actions
Container registries: Amazon ECR and GitHub Container Registry
AWS authentication: IAM OIDC identity provider and IAM role
AWS Region: us-east-1
What I Implemented
Configured automated dependency installation and testing.
Added Docker image building to the CI workflow.
Configured publishing to Amazon ECR and GHCR.
Published images with latest and full commit-SHA tags for traceability.
Configured AWS authentication through temporary OIDC credentials.
Scoped the IAM permissions to the Project 02 ECR repository, with the required account-level authorization-token permission.
Avoided storing permanent AWS access keys in GitHub.
Restricted publishing steps to pushes to main.
Application and Tests
The Express application serves a simple web page on port 3000.
Replace AWS_ACCOUNT_ID with your AWS account's 12-digit account ID when constructing the actual URI.
Amazon ECR is private by default. Pulling from it requires AWS authentication and permission to download the image.
CI/CD Workflow
Workflow file: .github/workflows/ci.yml
I configured the workflow to:
Check out the repository.
Set up Node.js.
Install dependencies with npm ci.
Run the automated tests.
Build the Docker image.
Authenticate to GHCR.
Assume the configured AWS IAM role using GitHub OIDC.
Authenticate to Amazon ECR.
Push the image to both registries using latest and commit-SHA tags.
On pull requests targeting main, the workflow runs tests and builds the image without publishing it. On pushes to main, it also publishes the images.
AWS Security Design
I configured GitHub Actions to assume the IAM role GitHubActions-PelumiContainerizedCICD through the GitHub OIDC identity provider.
The role's trust policy restricts access to the intended repository and main branch subject. The attached IAM policy grants the ECR permissions needed to publish images to this project's repository.
I stored the role ARN in the GitHub repository variable AWS_ROLE_ARN. The workflow does not require permanent AWS access keys.
Cost Considerations
The project uses Amazon ECR for container image storage. Storage and data transfer charges may apply depending on usage and applicable AWS allowances.
I did not include an ECS cluster, Fargate service, NAT Gateway, or continuously running EC2 instance in this project. Those deployment components remain outside the current scope, keeping the implementation focused on testing, containerization, and registry publishing.
Review AWS Billing and Cost Management periodically.
Evidence
I uploaded implementation screenshots to the evidence gallery , including the successful workflow, automated tests, ECR image tags, OIDC role, local container, and GHCR package.
Verification
The successful GitHub Actions run completed the automated tests, Docker image build, AWS OIDC authentication, ECR authentication, and image publishing to both container registries.
The ECR repository screenshot also showed the published image tags.