Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 34 additions & 25 deletions .github/actions/deploy-to-ec2/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ inputs:
description: 'EC2 SSH user'
required: true
repo_base_dir:
description: 'Base directory on EC2 where cloud-services and web-client are located'
description: 'Base directory on EC2 where cloud-services is located'
required: false
default: '/home/ubuntu'
branch:
description: 'Git branch to deploy'
required: false
default: 'main'
web_api_base_url:
description: 'API URL baked into the web-client build; empty keeps the value in web-client/.env.production'
description: 'API URL baked into the web-client build; empty means the page origin, which nginx proxies to cloud-services'
required: false
default: ''

Expand Down Expand Up @@ -48,9 +48,8 @@ runs:
env:
WEB_API_BASE_URL: ${{ inputs.web_api_base_url }}
run: |
if [ -n "$WEB_API_BASE_URL" ]; then
export VITE_API_BASE_URL="$WEB_API_BASE_URL"
fi
# Set even when empty so it overrides web-client/.env.production
export VITE_API_BASE_URL="$WEB_API_BASE_URL"
npm ci
npm run build
tar -czf "$RUNNER_TEMP/web-client-dist.tgz" -C dist .
Expand All @@ -69,9 +68,9 @@ runs:
StrictHostKeyChecking no
EOF

- name: Upload web-client build
- name: Upload web-client build and nginx config
shell: bash
run: scp "$RUNNER_TEMP/web-client-dist.tgz" ec2-deploy:/tmp/web-client-dist.tgz
run: scp "$RUNNER_TEMP/web-client-dist.tgz" "$GITHUB_WORKSPACE/deploy/nginx/hyperloop-gui.conf" ec2-deploy:/tmp/

- name: Deploy to EC2
shell: bash
Expand All @@ -82,26 +81,36 @@ runs:
BASE_DIR="${{ inputs.repo_base_dir }}"
BRANCH="${{ inputs.branch }}"

# Deploy Web Client
# Deploy Web Client: nginx serves the build and proxies the API (deploy/nginx/hyperloop-gui.conf)
echo "Deploying web-client..."
cd "$BASE_DIR/web-client"

# Update repository
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"

# `vite preview` serves dist/ from this checkout, so it still needs node_modules
npm ci
rm -rf dist
mkdir dist
tar -xzf /tmp/web-client-dist.tgz -C dist
if ! command -v nginx >/dev/null; then
sudo apt-get update -q
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q nginx
# The stock site listens on :80, which this deployment does not use
sudo rm -f /etc/nginx/sites-enabled/default
fi

WEB_ROOT=/var/www/hyperloop-gui
sudo rm -rf "$WEB_ROOT.new" "$WEB_ROOT.old"
sudo mkdir -p "$WEB_ROOT.new"
sudo tar -xzf /tmp/web-client-dist.tgz --no-same-owner -C "$WEB_ROOT.new"
if [ -d "$WEB_ROOT" ]; then sudo mv "$WEB_ROOT" "$WEB_ROOT.old"; fi
sudo mv "$WEB_ROOT.new" "$WEB_ROOT"
sudo rm -rf "$WEB_ROOT.old"
rm -f /tmp/web-client-dist.tgz

# Restart frontend service
echo "Restarting frontend service..."
sudo systemctl restart frontend


sudo install -m 644 /tmp/hyperloop-gui.conf /etc/nginx/sites-available/hyperloop-gui
sudo ln -sfn /etc/nginx/sites-available/hyperloop-gui /etc/nginx/sites-enabled/hyperloop-gui
rm -f /tmp/hyperloop-gui.conf
sudo nginx -t

# nginx takes over port 4173 from the old `vite preview` service
if systemctl cat frontend >/dev/null 2>&1; then
sudo systemctl disable --now frontend
fi
sudo systemctl enable nginx
sudo systemctl reload-or-restart nginx

# Deploy Cloud Services API with venv
echo "Deploying cloud-services..."
cd "$BASE_DIR/cloud-services"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
type: string
default: 'main'
repo_base_dir:
description: 'Base directory on EC2 where cloud-services and web-client are located'
description: 'Base directory on EC2 where cloud-services is located'
required: false
type: string
default: '/home/ubuntu'
Expand Down
50 changes: 50 additions & 0 deletions deploy/nginx/hyperloop-gui.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Serves the web-client build and proxies cloud-services on the same origin, so the
# browser needs no CORS and port 8080 does not have to be reachable from the internet.
# The deploy action installs this as /etc/nginx/sites-available/hyperloop-gui.

map $http_upgrade $hyperloop_connection_upgrade {
default upgrade;
'' close;
}

server {
listen 4173;
server_name _;

root /var/www/hyperloop-gui;
index index.html;

gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;

# Flash requests carry the firmware base64-encoded in the JSON body
client_max_body_size 25m;

proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $hyperloop_connection_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Hub and browser websockets can sit idle between messages
proxy_read_timeout 1h;
proxy_send_timeout 1h;

location /auth/ { proxy_pass http://127.0.0.1:8080; }
location /api/ { proxy_pass http://127.0.0.1:8080; }
location /ws/ { proxy_pass http://127.0.0.1:8080; }
location = /hub { proxy_pass http://127.0.0.1:8080; }
location = /health { proxy_pass http://127.0.0.1:8080; }

# File names under /assets/ change with their content on every build
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}

# Client-side routes (/devices, /telemetry, ...) load the app shell
location / {
add_header Cache-Control "no-cache";
try_files $uri $uri/ /index.html;
}
}