Skip to content

Commit 8e0c79f

Browse files
committed
Another fix
1 parent 591b70f commit 8e0c79f

4 files changed

Lines changed: 114 additions & 167 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,64 @@ name: Deploy to EC2
22

33
on:
44
push:
5-
branches:
6-
- main
5+
branches: [main]
76
workflow_dispatch:
87

98
jobs:
109
deploy:
1110
runs-on: ubuntu-latest
12-
11+
env:
12+
APP_DIR: ${{ secrets.EC2_APP_DIR }}
13+
PYTHON_BIN: ${{ secrets.EC2_PYTHON_BIN }}
14+
SERVICE_NAME: ${{ secrets.EC2_SERVICE_NAME }}
15+
UVICORN_PORT: ${{ secrets.EC2_UVICORN_PORT }}
1316
steps:
1417
- name: Checkout repository
1518
uses: actions/checkout@v4
1619

17-
- name: Export deployment settings
18-
run: |
19-
echo "EC2_HOST=${{ secrets.EC2_HOST }}" >> "$GITHUB_ENV"
20-
echo "EC2_USER=${{ secrets.EC2_USER }}" >> "$GITHUB_ENV"
21-
if [ -n "${{ vars.DEPLOY_PORT }}" ]; then
22-
echo "PORT=${{ vars.DEPLOY_PORT }}" >> "$GITHUB_ENV"
23-
else
24-
echo "PORT=80" >> "$GITHUB_ENV"
25-
fi
26-
27-
- name: Set up SSH key
28-
uses: webfactory/ssh-agent@v0.8.0
20+
- name: Start SSH agent
21+
uses: webfactory/ssh-agent@v0.9.0
2922
with:
3023
ssh-private-key: ${{ secrets.EC2_SSH_KEY }}
3124

3225
- name: Add EC2 host to known_hosts
3326
run: |
3427
mkdir -p ~/.ssh
35-
ssh-keyscan -H "$EC2_HOST" >> ~/.ssh/known_hosts
28+
ssh-keyscan -H "${{ secrets.EC2_HOST }}" >> ~/.ssh/known_hosts
29+
30+
- name: Ensure remote application directory exists
31+
env:
32+
REMOTE_APP_DIR: ${{ env.APP_DIR }}
33+
run: |
34+
set -euo pipefail
35+
APP_DIR="${REMOTE_APP_DIR:-/home/ubuntu/nasa-sky-explorer}"
36+
ssh "${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}" "mkdir -p ${APP_DIR}"
3637
37-
- name: Sync project to EC2
38+
- name: Sync repository to EC2
39+
env:
40+
REMOTE_APP_DIR: ${{ env.APP_DIR }}
3841
run: |
42+
set -euo pipefail
43+
APP_DIR="${REMOTE_APP_DIR:-/home/ubuntu/nasa-sky-explorer}"
3944
rsync -az --delete \
40-
--exclude '.git' \
41-
--exclude '.github' \
42-
--exclude '.venv' \
43-
--exclude '__pycache__' \
44-
--exclude '*.pyc' \
45-
--exclude '.ruff_cache' \
46-
./ "$EC2_USER@$EC2_HOST:/home/$EC2_USER/nasa-sky-app"
47-
48-
- name: Execute remote deployment
45+
--exclude ".git" \
46+
--exclude ".github/" \
47+
--exclude ".venv/" \
48+
--exclude "logs/" \
49+
./ "${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:${APP_DIR}/"
50+
51+
- name: Install Python dependencies and restart the service
52+
env:
53+
REMOTE_APP_DIR: ${{ env.APP_DIR }}
54+
REMOTE_PYTHON_BIN: ${{ env.PYTHON_BIN }}
55+
REMOTE_SERVICE: ${{ env.SERVICE_NAME }}
56+
REMOTE_PORT: ${{ env.UVICORN_PORT }}
4957
run: |
50-
ssh "$EC2_USER@$EC2_HOST" "
51-
set -euo pipefail
52-
cd ~/nasa-sky-app
53-
chmod +x deploy/deploy.sh
54-
APP_ROOT=/opt/nasa-sky-app SERVICE_NAME=nasa-sky-app PORT=${PORT:-80} ./deploy/deploy.sh
55-
"
58+
set -euo pipefail
59+
APP_DIR="${REMOTE_APP_DIR:-/home/ubuntu/nasa-sky-explorer}"
60+
PYTHON_BIN="${REMOTE_PYTHON_BIN:-/usr/bin/python3}"
61+
SERVICE_NAME="${REMOTE_SERVICE:-nasaspaceapps}"
62+
UVICORN_PORT="${REMOTE_PORT:-8000}"
63+
64+
ssh "${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}" \
65+
"cd '${APP_DIR}' && APP_DIR='${APP_DIR}' PYTHON_BIN='${PYTHON_BIN}' SERVICE_NAME='${SERVICE_NAME}' UVICORN_PORT='${UVICORN_PORT}' bash deploy/remote_deploy.sh"

README.md

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,51 @@ NASASpaceAppsChallenge2025/
3838
├── src/
3939
│ ├── __init__.py
4040
│ └── server.py # FastAPI application serving the HTML page
41-
└── web/
42-
└── index.html # Static HTML served at the root route
43-
└── deploy/
44-
└── deploy.sh # Helper script to install and run the service via systemd
41+
├── web/
42+
│ ├── index.html # Landing page served at the root route
43+
│ └── aladin.html # Secondary page under /aladin
44+
├── deploy/
45+
│ └── remote_deploy.sh # Remote helper script invoked by the CI workflow
46+
└── .github/
47+
└── workflows/
48+
└── deploy.yml # Continuous deployment pipeline for EC2
4549
```
4650

4751
Feel free to build on this foundation for richer APIs or interfaces.
4852

49-
## Deployment script
53+
## Continuous deployment to EC2
5054

51-
The `deploy/deploy.sh` script provisions the application on a Linux host using `systemd`. It:
55+
Every push to `main` triggers the GitHub Actions workflow in `.github/workflows/deploy.yml`. The
56+
pipeline performs the following steps:
5257

53-
- Syncs the repository into `/opt/nasa-sky-app/app` (configurable with `APP_ROOT`).
54-
- Ensures `/opt/nasa-sky-app` exists with the proper ownership, then syncs code and creates a
55-
virtual environment for dependencies.
56-
- Generates a `systemd` unit that runs Uvicorn on port `80` by default.
57-
- Enables and restarts the service.
58+
1. Checks out the latest code.
59+
2. Copies the repository to your EC2 instance via `rsync` (preserving any existing `.venv` or
60+
`logs` folders).
61+
3. Runs `deploy/remote_deploy.sh` on the instance to create/refresh a virtual environment, install
62+
dependencies, and restart the application via `systemd` when available. If a systemd service is
63+
not present, it falls back to launching Uvicorn in the background with `nohup`.
5864

59-
Run it directly on the target server after cloning or syncing the repository:
65+
### Required GitHub secrets
6066

61-
```bash
62-
chmod +x deploy/deploy.sh
63-
APP_ROOT=/opt/nasa-sky-app SERVICE_NAME=nasa-sky-app ./deploy/deploy.sh
64-
```
67+
Create the following secrets at **Settings → Secrets and variables → Actions**:
68+
69+
- `EC2_HOST` – Public DNS name or IP address of the instance.
70+
- `EC2_USER` – SSH user (for example, `ubuntu`).
71+
- `EC2_SSH_KEY` – Private SSH key allowed to log in as `EC2_USER`.
72+
73+
### Optional overrides
6574

66-
Override `SERVICE_USER`, `SERVICE_GROUP`, `PORT`, or `PYTHON_BIN` to fit your environment. When the
67-
port is below `1024` (the default `80`), the generated unit grants
68-
`CAP_NET_BIND_SERVICE` so the application can bind to the port without running as root.
75+
You can customise the deployment without editing the workflow by providing additional (optional)
76+
secrets:
6977

70-
### GitHub Actions deployment
78+
- `EC2_APP_DIR` – Absolute path where the repo should live (defaults to `/home/ubuntu/nasa-sky-explorer`).
79+
- `EC2_PYTHON_BIN` – Python interpreter used to build the virtual environment (defaults to
80+
`/usr/bin/python3`).
81+
- `EC2_SERVICE_NAME` – Name of the `systemd` service to restart (defaults to `nasaspaceapps`).
82+
- `EC2_UVICORN_PORT` – Port exposed by Uvicorn when no `systemd` unit is available (defaults to
83+
`8000`).
7184

72-
A workflow at `.github/workflows/deploy.yml` uses the repository secrets `EC2_HOST`, `EC2_USER`,
73-
and `EC2_SSH_KEY` to sync the codebase to an Ubuntu 24.04 EC2 instance and execute the deployment
74-
script remotely. It runs on every push to `main` (and can be triggered manually). Optional
75-
repository variable `DEPLOY_PORT` lets you override the port without editing the workflow.
85+
Ensure the EC2 machine has `git`, `rsync`, `python3`, and `pip` installed. If you prefer a managed
86+
service, create a `systemd` unit named after `EC2_SERVICE_NAME` that executes
87+
`/home/ubuntu/nasa-sky-explorer/.venv/bin/uvicorn src.server:app --host 0.0.0.0 --port 8000`
88+
and the workflow will restart it after each deployment.

deploy/deploy.sh

Lines changed: 0 additions & 111 deletions
This file was deleted.

deploy/remote_deploy.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
APP_DIR="${APP_DIR:-$(pwd)}"
5+
PYTHON_BIN="${PYTHON_BIN:-/usr/bin/python3}"
6+
SERVICE_NAME="${SERVICE_NAME:-nasaspaceapps}"
7+
UVICORN_PORT="${UVICORN_PORT:-8000}"
8+
9+
if [ ! -d ".venv" ]; then
10+
"${PYTHON_BIN}" -m venv .venv
11+
fi
12+
13+
# shellcheck source=/dev/null
14+
source .venv/bin/activate
15+
pip install --upgrade pip wheel
16+
pip install -r requirements.txt
17+
18+
deactivate || true
19+
20+
LOG_DIR="${APP_DIR}/logs"
21+
mkdir -p "${LOG_DIR}"
22+
23+
if command -v systemctl >/dev/null 2>&1; then
24+
sudo systemctl daemon-reload || true
25+
if sudo systemctl list-unit-files | grep -q "^${SERVICE_NAME}\.service"; then
26+
sudo systemctl restart "${SERVICE_NAME}.service"
27+
exit 0
28+
fi
29+
fi
30+
31+
echo "systemd unit ${SERVICE_NAME}.service not found or unavailable. Relaunching Uvicorn with nohup."
32+
33+
pkill -f "uvicorn src.server:app" || true
34+
nohup "${APP_DIR}/.venv/bin/uvicorn" src.server:app --host 0.0.0.0 --port "${UVICORN_PORT}" \
35+
>"${LOG_DIR}/uvicorn.log" 2>&1 &

0 commit comments

Comments
 (0)