✨ feat(next.config.js): update image domains to remotePatterns for en… #12
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Deploy to Production | |
on: | |
push: | |
branches: ['main'] | |
paths-ignore: | |
- '**.md' | |
- '.gitignore' | |
- 'LICENSE' | |
env: | |
IMAGE_NAME: docker-registry.baobo.me/gengar-bark | |
NODE_VERSION: '18' | |
DOCKER_BUILDKIT: 1 | |
COMPOSE_DOCKER_CLI_BUILD: 1 | |
jobs: | |
test: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Setup Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
cache: 'npm' | |
- name: Install dependencies | |
run: npm ci | |
- name: Run tests | |
run: npm test | |
deploy: | |
needs: test | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
with: | |
version: latest | |
platforms: linux/amd64 | |
driver-opts: | | |
image=moby/buildkit:latest | |
network=host | |
- name: Generate version tag | |
id: tag | |
run: | | |
SHA_SHORT=$(git rev-parse --short HEAD) | |
TS=$(date +%Y%m%d%H%M) | |
echo "VERSION=${TS}-${SHA_SHORT}" >> $GITHUB_OUTPUT | |
- name: Create env file | |
shell: bash | |
env: | |
ENV_CONTENT: ${{ secrets.ENV_PROD }} | |
run: | | |
echo "$ENV_CONTENT" > .env | |
- name: Login to Registry | |
uses: docker/login-action@v2 | |
with: | |
registry: docker-registry.baobo.me | |
username: ${{ secrets.REGISTRY_USERNAME }} | |
password: ${{ secrets.REGISTRY_PASSWORD }} | |
# 修改缓存配置,确保目录存在 | |
- name: Prepare cache directory | |
run: | | |
mkdir -p /tmp/.buildx-cache | |
chmod 777 /tmp/.buildx-cache | |
- name: Build and push | |
uses: docker/build-push-action@v4 | |
with: | |
context: . | |
push: true | |
tags: | | |
${{ env.IMAGE_NAME }}:latest | |
${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.VERSION }} | |
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max | |
cache-from: type=local,src=/tmp/.buildx-cache | |
build-args: | | |
NODE_ENV=production | |
BUILDKIT_INLINE_CACHE=1 | |
target: production | |
platforms: linux/amd64 | |
labels: | | |
org.opencontainers.image.source=${{ github.event.repository.html_url }} | |
org.opencontainers.image.revision=${{ github.sha }} | |
# 修改压缩配置 | |
outputs: | | |
type=registry,compression=zstd,compression-level=5,force-compression=true | |
# 临时缓存处理 | |
- name: Move cache | |
run: | | |
rm -rf /tmp/.buildx-cache | |
mv /tmp/.buildx-cache-new /tmp/.buildx-cache | |
- name: Deploy | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.HOST }} | |
username: ${{ secrets.HOST_USERNAME }} | |
key: ${{ secrets.HOST_SSHKEY }} | |
script: | | |
# 创建应用目录 | |
mkdir -p /app/gengar-bark | |
cd /app/gengar-bark | |
# 清理旧容器 | |
echo "Stopping and removing old container if exists..." | |
if docker ps -a | grep -q "gengar-bark"; then | |
docker stop gengar-bark || true | |
docker rm -f gengar-bark || true | |
fi | |
# 拉取新镜像 | |
echo "Pulling new image..." | |
docker pull ${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.VERSION }} | |
# 启动新容器 | |
echo "Starting new container..." | |
docker run -d \ | |
--name gengar-bark \ | |
--restart unless-stopped \ | |
-p 127.0.0.1:3001:3000 \ | |
--memory="1g" \ | |
--memory-reservation="512m" \ | |
--health-cmd="curl -f http://localhost:3000/api/health || exit 1" \ | |
--health-interval=30s \ | |
--health-timeout=10s \ | |
--health-retries=3 \ | |
--health-start-period=40s \ | |
--log-driver json-file \ | |
--log-opt max-size=50m \ | |
--log-opt max-file=3 \ | |
--label "deployment.version=${{ steps.tag.outputs.VERSION }}" \ | |
--label "deployment.timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \ | |
${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.VERSION }} | |
# 等待服务健康检查通过 | |
echo "Waiting for health check..." | |
max_retries=30 | |
count=0 | |
while [ $count -lt $max_retries ]; do | |
if docker inspect gengar-bark --format='{{.State.Health.Status}}' | grep -q "healthy"; then | |
echo "Service is healthy!" | |
break | |
fi | |
count=$((count + 1)) | |
echo "Waiting for service to be healthy... ($count/$max_retries)" | |
sleep 2 | |
done | |
if [ $count -eq $max_retries ]; then | |
echo "Health check failed after $max_retries attempts" | |
docker logs --tail 100 gengar-bark | |
exit 1 | |
fi | |
# 验证部署 | |
if ! curl -f http://localhost:3001/api/health; then | |
echo "Final health check failed" | |
docker logs --tail 100 gengar-bark | |
exit 1 | |
fi | |
# 清理旧镜像和缓存 | |
echo "Cleaning up old images..." | |
docker system prune -af --filter "until=24h" || true | |
- name: Verify Deployment | |
if: success() | |
run: | | |
echo "✅ Deployment successful" | |
echo "Version: ${{ steps.tag.outputs.VERSION }}" | |
echo "Deployed at: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" | |
- name: Notify on Failure | |
if: failure() | |
run: | | |
echo "❌ Deployment failed" | |
echo "Please check the logs for more details" | |
- name: Clean up | |
if: always() | |
run: | | |
docker builder prune -f | |
docker image prune -f |