This project can deploy the Invoice Management Dashboard to an AWS EC2 VM. The VM runs the production Docker image with Docker Compose.
Deployment is optional for the assignment evidence. The GitHub Actions workflow always validates, scans, builds, and publishes the Docker image on main; the VM deploy job only runs when ENABLE_STAGING_DEPLOY=true.
- Image registry:
ghcr.io/putureyvan/invoice-app - VM app directory:
/opt/invoice-app - Runtime: Docker Compose
- Public port:
80 - Health check:
/health
Copy deploy/docker-compose.staging.yml to the VM as:
/opt/invoice-app/docker-compose.ymlCreate the VM environment file:
APP_IMAGE_TAG=<git-commit-sha>Save it as:
/opt/invoice-app/.env- Ubuntu LTS on AWS EC2.
- Docker Engine and Docker Compose plugin installed.
- Firewall allows:
tcp:22for SSHtcp:80for the web app
- If the GHCR package is private, the VM must login to GHCR:
echo "<github-token>" | docker login ghcr.io -u "<github-username>" --password-stdinRun this on the VM after the image is available in GHCR:
cd /opt/invoice-app
docker compose pull
docker compose up -d
curl --fail http://localhost/healthExpected health output:
ok
Set these repository secrets:
| Secret | Purpose |
|---|---|
STAGING_HOST |
AWS VM external IP or DNS |
STAGING_USER |
SSH user on the VM |
STAGING_SSH_KEY |
Private key for GitHub Actions SSH access |
STAGING_PORT |
SSH port, usually 22 |
STAGING_APP_URL |
Public health URL, for example http://<vm-ip>/health |
Set this repository variable only when the VM is ready:
| Variable | Value |
|---|---|
ENABLE_STAGING_DEPLOY |
true |
When enabled, the workflow deploy job:
- Uses the image tag from the current Git commit SHA.
- SSHes into
/opt/invoice-appon the VM. - Stores the previous
APP_IMAGE_TAGfor rollback. - Writes the new
APP_IMAGE_TAGto.env. - Runs
docker compose pullanddocker compose up -d. - Runs the health check.
- Restores the previous tag if the health check fails.