Skip to content

Deploy to EC2

Deploy to EC2 #83

name: Deploy to EC2
on:
workflow_dispatch:
workflow_run:
workflows: ["Build and Push to Dockerhub"]
types:
- completed
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Sync docker-compose and deploy via SSM
env:
DOCKER_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/smr-website:latest
run: |
COMPOSE_B64=$(base64 -w0 docker-compose.yaml)
# Build SSM parameters as a JSON file to avoid quoting issues
jq -n \
--arg compose "$COMPOSE_B64" \
--arg image "$DOCKER_IMAGE" \
'{commands: [
("echo " + $compose + " | base64 -d > /opt/app/docker-compose.yaml"),
"chown ubuntu:ubuntu /opt/app/docker-compose.yaml",
("grep -q DOCKER_IMAGE /opt/app/.env 2>/dev/null || echo DOCKER_IMAGE=" + $image + " > /opt/app/.env"),
"cd /opt/app && docker compose pull && docker compose up -d --remove-orphans && docker image prune -f"
]}' > /tmp/ssm-params.json
COMMAND_ID=$(aws ssm send-command \
--instance-ids "${{ secrets.EC2_INSTANCE_ID }}" \
--document-name "AWS-RunShellScript" \
--parameters file:///tmp/ssm-params.json \
--query "Command.CommandId" \
--output text)
echo "Command ID: $COMMAND_ID"
# Wait for completion, but don't exit on failure so we can capture output
aws ssm wait command-executed \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" || true
echo "=== STDOUT ==="
aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "StandardOutputContent" \
--output text
echo "=== STDERR ==="
aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "StandardErrorContent" \
--output text
# Now check actual status and fail if needed
STATUS=$(aws ssm get-command-invocation \
--command-id "$COMMAND_ID" \
--instance-id "${{ secrets.EC2_INSTANCE_ID }}" \
--query "Status" \
--output text)
if [ "$STATUS" != "Success" ]; then
echo "SSM command failed with status: $STATUS"
exit 1
fi