@@ -65,109 +65,68 @@ jobs:
65
65
tags : ${{ steps.vars.outputs.image }}
66
66
cache-from : type=gha
67
67
cache-to : type=gha,mode=max
68
-
69
- # ---- Final deploy step (fixes region expansion & non-TTY login; Ubuntu 24.04-safe) ----
70
- - name : Deploy on EC2 via SSM
71
- env :
72
- IMAGE : ${{ steps.vars.outputs.image }}
73
- run : |
74
- set -euo pipefail
75
-
76
- # 1) Write a neutral script with placeholders so we can safely inject values
77
- cat > deploy.sh <<'EOF'
78
- #!/bin/sh
79
- set -eu
80
-
81
- REGION="__REGION__"
82
- IMAGE="__IMAGE__"
83
- SERVICE_NAME="__SERVICE_NAME__"
84
- APP_PORT="__APP_PORT__"
85
-
86
- # ---- Install Docker (Ubuntu path uses docker.asc; no gpg --dearmor / TTY) ----
87
- if command -v apt-get >/dev/null 2>&1; then
88
- export DEBIAN_FRONTEND=noninteractive
89
- apt-get update -y
90
-
91
- # Remove conflicting Ubuntu docker/containerd packages (prevents "containerd.io : Conflicts: containerd")
92
- for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
93
- apt-get remove -y "$pkg" || true
94
- done
95
-
96
- apt-get install -y ca-certificates curl unzip
97
- install -m 0755 -d /etc/apt/keyrings
98
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
99
- chmod a+r /etc/apt/keyrings/docker.asc
100
- . /etc/os-release
101
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" > /etc/apt/sources.list.d/docker.list
102
-
103
- apt-get update -y
104
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
105
-
106
- elif command -v dnf >/dev/null 2>&1; then
107
- dnf -y update || true
108
- dnf -y install docker curl unzip || yum -y install docker curl unzip
109
- elif command -v yum >/dev/null 2>&1; then
110
- yum -y update || true
111
- yum -y install docker curl unzip
112
- else
113
- echo "no supported package manager found"
114
- exit 1
115
- fi
116
-
117
- systemctl enable --now docker || true
118
-
119
- # ---- ECR login (non-interactive per AWS docs) ----
120
- ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
121
- REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
122
-
123
- aws ecr get-login-password --region "${REGION}" \
124
- | docker login --username AWS --password-stdin "${REGISTRY}"
125
-
126
- # ---- Pull & run on host 80 -> container ${APP_PORT} ----
127
- docker rm -f "${SERVICE_NAME}" || true
128
- docker pull "${IMAGE}"
129
- docker run -d --restart unless-stopped --name "${SERVICE_NAME}" -p 80:"${APP_PORT}" "${IMAGE}"
130
-
131
- # ---- Evidence / health check ----
132
- docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
133
- curl -sS -o /dev/null -w '%{http_code}\n' http://localhost/hello
134
- EOF
135
- chmod +x deploy.sh
136
-
137
- # 2) Inject real values (this avoids single-quoted heredoc expansion issues)
138
- sed -i "s|__REGION__|${{ env.AWS_REGION }}|g" deploy.sh
139
- sed -i "s|__IMAGE__|${{ steps.vars.outputs.image }}|g" deploy.sh
140
- sed -i "s|__SERVICE_NAME__|${{ env.SERVICE_NAME }}|g" deploy.sh
141
- sed -i "s|__APP_PORT__|${{ env.APP_PORT }}|g" deploy.sh
142
-
143
- # 3) Send to SSM (no YAML/JSON quoting headaches) and execute
144
- B64=$(base64 -w0 deploy.sh || base64 deploy.sh | tr -d '\n')
145
- CMD_ID=$(aws ssm send-command \
146
- --instance-ids "${EC2_INSTANCE_ID}" \
147
- --document-name "AWS-RunShellScript" \
148
- --comment "Deploy ${SERVICE_NAME}" \
149
- --parameters "commands=[\"echo ${B64} | base64 -d > /tmp/deploy.sh\",\"sudo sh /tmp/deploy.sh\"]" \
150
- --query "Command.CommandId" --output text)
151
- echo "CommandId: ${CMD_ID}"
152
-
153
- # 4) Wait for completion and surface logs
154
- for i in $(seq 1 30); do
155
- STATUS=$(aws ssm get-command-invocation \
156
- --command-id "$CMD_ID" \
157
- --instance-id "${EC2_INSTANCE_ID}" \
158
- --query "Status" --output text)
159
- echo "SSM status: $STATUS"
160
- case "$STATUS" in
161
- Success) break ;;
162
- Cancelled|Failed|TimedOut) break ;;
163
- esac
164
- sleep 5
165
- done
166
-
167
- aws ssm get-command-invocation \
168
- --command-id "$CMD_ID" \
169
- --instance-id "${EC2_INSTANCE_ID}" \
170
- --query "{Status:Status, StdOut:StandardOutputContent, StdErr:StandardErrorContent}" \
171
- --output text
172
-
173
- [ "$STATUS" = "Success" ]
68
+ - name : Deploy over SSH (no SSM)
69
+ uses : appleboy/ssh-action@v1.2.1
70
+ with :
71
+ host : ${{ vars.EC2_PUBLIC_IP }}
72
+ username : ubuntu
73
+ key : ${{ secrets.EC2_SSH_KEY }}
74
+ port : 22
75
+ script_stop : true
76
+ envs : AWS_REGION,APP_PORT,SERVICE_NAME
77
+ script : |
78
+ set -eu
79
+
80
+ REGION="${AWS_REGION}"
81
+ IMAGE="${{ steps.vars.outputs.image }}"
82
+ SERVICE="${SERVICE_NAME}"
83
+ PORT="${APP_PORT}"
84
+
85
+ # --- Ensure Docker (Ubuntu 24.04-safe: remove conflicts, use Docker repo .asc key) ---
86
+ if ! command -v docker >/dev/null 2>&1; then
87
+ if command -v apt-get >/dev/null 2>&1; then
88
+ sudo apt-get update -y
89
+ for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
90
+ sudo apt-get remove -y "$pkg" || true
91
+ done
92
+ sudo apt-get install -y ca-certificates curl unzip
93
+ sudo install -m 0755 -d /etc/apt/keyrings
94
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc >/dev/null
95
+ sudo chmod a+r /etc/apt/keyrings/docker.asc
96
+ . /etc/os-release
97
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
98
+ sudo apt-get update -y
99
+ sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
100
+ elif command -v dnf >/dev/null 2>&1; then
101
+ sudo dnf -y update || true
102
+ sudo dnf -y install docker curl unzip || sudo yum -y install docker curl unzip
103
+ elif command -v yum >/dev/null 2>&1; then
104
+ sudo yum -y update || true
105
+ sudo yum -y install docker curl unzip
106
+ else
107
+ echo "no supported package manager found"; exit 1
108
+ fi
109
+ fi
110
+
111
+ sudo systemctl enable --now docker || true
112
+
113
+ # --- ECR login (non-TTY per AWS docs) ---
114
+ ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
115
+ REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
116
+ aws ecr get-login-password --region "$REGION" | sudo docker login --username AWS --password-stdin "$REGISTRY"
117
+
118
+ # --- Pull & run: host 80 -> container ${PORT} ---
119
+ sudo docker rm -f "$SERVICE" || true
120
+ sudo docker pull "$IMAGE"
121
+ sudo docker run -d --restart unless-stopped --name "$SERVICE" -p 80:"$PORT" "$IMAGE"
122
+
123
+ # --- Health check w/ retries (avoid curl 56 during boot) ---
124
+ for i in $(seq 1 30); do
125
+ code=$(curl -sS -o /dev/null -w '%{http_code}' http://localhost/hello || true)
126
+ [ "$code" = "200" ] && { echo "Health: OK (200)"; break; }
127
+ echo "Health: not ready (code=${code:-none}), retrying..."
128
+ sleep 3
129
+ done
130
+
131
+ # Evidence
132
+ sudo docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
0 commit comments