Files
jiu/scripts/ci/deploy.sh
T
wangjia f039bd0c61
Deploy / build-windows (push) Failing after 25s
Deploy / build-linux-web (push) Successful in 1m14s
Deploy / build-macos (push) Successful in 1m12s
Deploy / release-deploy (push) Has been skipped
fix(ci): deploy 适配容器化 nginx(pangolin-edge)
nginx 已从主机迁入 pangolin-edge 容器(host 网络模式),其
/etc/nginx/conf.d 由主机 ~/pangolin/edge/conf.d bind-mount。
deploy 改为:jiu.conf 写入该挂载目录 + docker exec pangolin-edge
nginx -t/-s reload,不再 cp 到主机 /etc/nginx 或 systemctl 操作
已废弃的主机 nginx。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 07:20:50 +08:00

144 lines
4.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# deploy.sh <tag> — deploy release to EC2
# Works in two modes:
# 1. Automated (after compile.sh): uses dist/ built in the same job
# 2. Manual/rollback: downloads assets from Forgejo Release by tag
set -euo pipefail
TAG="$1"
echo "==> deploy: tag=${TAG}"
# Download from Forgejo if dist/ was not built in this job
if [ ! -f dist/jiu-server ] || [ ! -f dist/web.tar.gz ] || [ ! -f dist/configs.tar.gz ] || [ ! -f dist/marketing.tar.gz ]; then
echo "==> deploy: dist/ incomplete — downloading assets for ${TAG} from Forgejo"
mkdir -p dist
curl -kf \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/tags/${TAG}" \
-o /tmp/release-info.json
python3 - <<'PYEOF'
import json, urllib.request, ssl, os, sys
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
with open('/tmp/release-info.json') as f:
release = json.load(f)
token = os.environ['FORGEJO_TOKEN']
forgejo_url = os.environ['FORGEJO_URL']
repo = os.environ['GITEA_REPOSITORY']
release_id = release['id']
for asset in release.get('assets', []):
url = f"{forgejo_url}/api/v1/repos/{repo}/releases/{release_id}/assets/{asset['id']}"
req = urllib.request.Request(url, headers={'Authorization': f'token {token}'})
with urllib.request.urlopen(req, context=ctx) as resp:
with open(f"dist/{asset['name']}", 'wb') as out:
out.write(resp.read())
print(f"Downloaded: {asset['name']}")
PYEOF
fi
echo "==> deploy: dist/ contents:"
ls -lh dist/
# Extract configs (nginx, version.yaml, etc.)
rm -rf /tmp/jiu-configs
mkdir -p /tmp/jiu-configs
tar -xzf dist/configs.tar.gz -C /tmp/jiu-configs
# Extract Flutter web build
rm -rf /tmp/jiu-web-new
mkdir -p /tmp/jiu-web-new
tar -xzf dist/web.tar.gz -C /tmp/jiu-web-new --strip-components=1
# Extract marketing site
rm -rf /tmp/jiu-marketing-new
mkdir -p /tmp/jiu-marketing-new
tar -xzf dist/marketing.tar.gz -C /tmp/jiu-marketing-new
# Setup SSH
mkdir -p ~/.ssh
printf '%s' "${EC2_SSH_KEY}" > ~/.ssh/ec2_deploy.pem
chmod 600 ~/.ssh/ec2_deploy.pem
ssh-keyscan -H "${EC2_HOST}" >> ~/.ssh/known_hosts
SSH="ssh -i ~/.ssh/ec2_deploy.pem -o StrictHostKeyChecking=no"
SCP="scp -O -i ~/.ssh/ec2_deploy.pem"
echo "==> deploy: uploading files to EC2"
# Upload backend binary
${SCP} dist/jiu-server "${EC2_USER}@${EC2_HOST}:/tmp/jiu-server"
# Upload version.yaml
${SCP} /tmp/jiu-configs/backend/config/version.yaml "${EC2_USER}@${EC2_HOST}:/tmp/version.yaml"
# Upload nginx config
${SCP} /tmp/jiu-configs/deploy/nginx-jiu.conf "${EC2_USER}@${EC2_HOST}:/tmp/nginx-jiu.conf"
# Upload Flutter web
rsync -avz --delete -e "ssh -i ~/.ssh/ec2_deploy.pem -o StrictHostKeyChecking=no" \
/tmp/jiu-web-new/ "${EC2_USER}@${EC2_HOST}:/tmp/jiu-web-new/"
# Upload marketing site (built by compile.sh)
rsync -avz --delete -e "ssh -i ~/.ssh/ec2_deploy.pem -o StrictHostKeyChecking=no" \
/tmp/jiu-marketing-new/ "${EC2_USER}@${EC2_HOST}:/tmp/jiu-marketing-new/"
echo "==> deploy: running remote deploy"
${SSH} "${EC2_USER}@${EC2_HOST}" << 'ENDSSH'
set -e
# Replace backend binary
sudo systemctl stop jiu
cp /tmp/jiu-server /opt/jiu/backend/jiu-server
chmod +x /opt/jiu/backend/jiu-server
# Update version configWorkingDirectory=/opt/jiu,读 config/version.yaml
mkdir -p /opt/jiu/config
cp /tmp/version.yaml /opt/jiu/config/version.yaml
# Start and health check
sudo systemctl start jiu
echo "Waiting for health check..."
for i in $(seq 1 30); do
if curl -f http://localhost:8080/health > /dev/null 2>&1; then
echo "Health check passed"
break
fi
sleep 2
done
curl -f http://localhost:8080/health > /dev/null || { echo "Health check failed!"; exit 1; }
# Swap Flutter web app (atomic)
rm -rf /opt/jiu/web-old
mv /opt/jiu/web /opt/jiu/web-old 2>/dev/null || true
mv /tmp/jiu-web-new /opt/jiu/web
# Update marketing site
mkdir -p /opt/jiu/marketing
rsync -a --delete /tmp/jiu-marketing-new/ /opt/jiu/marketing/
rm -rf /tmp/jiu-marketing-new
# Update jiu nginx config in the pangolin-edge reverse proxy.
# nginx now runs inside the `pangolin-edge` container (host networking), not on
# the host. Its /etc/nginx/conf.d is bind-mounted from the host dir below, so we
# write the config there and reload nginx *inside the container*.
cp /tmp/nginx-jiu.conf /home/ec2-user/pangolin/edge/conf.d/jiu.conf
docker exec pangolin-edge nginx -t && docker exec pangolin-edge nginx -s reload
echo "Deploy complete!"
ENDSSH
# Cleanup SSH key
rm -f ~/.ssh/ec2_deploy.pem
rm -rf /tmp/jiu-configs /tmp/jiu-web-new
echo "==> deploy: done"