feat: add production deployment artifacts for ghl.cast.ph (Vultr)
Align Woodpecker CI pipeline with team standard (cast-backend pattern): - Replace plugins/docker with woodpeckerci/plugin-docker-buildx - Use git.sds.dev registry; tag with CI_COMMIT_SHA short + latest - Use team secret names: registry_user/password, deploy_ssh_key - Add golangci-lint, semgrep, gosec, trivy-fs, trivy-secrets security gates - Deploy on push to main (not on tag): build-and-push then deploy step calls bash /opt/cast-ghl-provider/deploy/deploy.sh on server - Add Telegram notification on success/failure docker-compose.yaml: add image: git.sds.dev/cast/cast-ghl-provider:latest (server pulls from registry; build: kept for local dev only) deploy/deploy.sh: simplified to docker compose pull + up (build now happens in CI, not on the server) Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
877895f43e
commit
7745d205cb
136
.woodpecker.yml
136
.woodpecker.yml
@ -1,62 +1,96 @@
|
|||||||
steps:
|
steps:
|
||||||
- name: ci
|
- name: lint
|
||||||
|
image: golangci/golangci-lint:latest
|
||||||
|
commands:
|
||||||
|
- golangci-lint run ./...
|
||||||
|
|
||||||
|
- name: test
|
||||||
image: golang:1.22-alpine
|
image: golang:1.22-alpine
|
||||||
commands:
|
commands:
|
||||||
- go vet ./...
|
|
||||||
- go test ./...
|
- go test ./...
|
||||||
- go build ./cmd/server/
|
|
||||||
|
|
||||||
- name: docker-build
|
- name: semgrep
|
||||||
image: plugins/docker
|
image: semgrep/semgrep:latest
|
||||||
|
commands:
|
||||||
|
- >
|
||||||
|
semgrep scan --config auto --error
|
||||||
|
--exclude-rule go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure
|
||||||
|
--exclude-rule go.lang.security.audit.net.unescaped-data-in-url.unescaped-data-in-url
|
||||||
|
--exclude-rule go.lang.security.audit.xss.template-html-does-not-escape.unsafe-template-type
|
||||||
|
--exclude-rule html.security.audit.missing-integrity.missing-integrity
|
||||||
|
.
|
||||||
|
when:
|
||||||
|
- event: [push, pull_request]
|
||||||
|
|
||||||
|
- name: gosec
|
||||||
|
image: golang:1.22-bookworm
|
||||||
|
commands:
|
||||||
|
- go install github.com/securego/gosec/v2/cmd/gosec@latest
|
||||||
|
- gosec -exclude=G120,G706,G101,G115,G203,G124 ./...
|
||||||
|
when:
|
||||||
|
- event: [push, pull_request]
|
||||||
|
|
||||||
|
- name: trivy-fs
|
||||||
|
image: aquasec/trivy:latest
|
||||||
|
commands:
|
||||||
|
- trivy fs --severity HIGH,CRITICAL --exit-code 1 .
|
||||||
|
when:
|
||||||
|
- event: [push, pull_request]
|
||||||
|
|
||||||
|
- name: trivy-secrets
|
||||||
|
image: aquasec/trivy:latest
|
||||||
|
commands:
|
||||||
|
- trivy fs --scanners secret --exit-code 1 .
|
||||||
|
when:
|
||||||
|
- event: [push, pull_request]
|
||||||
|
|
||||||
|
- name: build-and-push
|
||||||
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
settings:
|
settings:
|
||||||
repo: registry.sds.dev/cast/cast-ghl-provider
|
repo: git.sds.dev/cast/cast-ghl-provider
|
||||||
registry: registry.sds.dev
|
registry: git.sds.dev
|
||||||
tags:
|
tag:
|
||||||
|
- ${CI_COMMIT_SHA:0:8}
|
||||||
- latest
|
- latest
|
||||||
- "${CI_COMMIT_TAG}"
|
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: registry_user
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: registry_password
|
||||||
when:
|
when:
|
||||||
event: tag
|
- branch: main
|
||||||
ref: refs/tags/v*
|
|
||||||
|
|
||||||
- name: deploy-tag
|
|
||||||
image: appleboy/drone-ssh
|
|
||||||
settings:
|
|
||||||
host:
|
|
||||||
from_secret: deploy_host
|
|
||||||
username:
|
|
||||||
from_secret: deploy_user
|
|
||||||
key:
|
|
||||||
from_secret: deploy_key
|
|
||||||
script:
|
|
||||||
- cd /opt/cast-ghl-provider
|
|
||||||
- docker compose pull bridge
|
|
||||||
- docker compose up -d --remove-orphans
|
|
||||||
- sleep 5
|
|
||||||
- docker compose ps bridge
|
|
||||||
when:
|
|
||||||
event: tag
|
|
||||||
ref: refs/tags/v*
|
|
||||||
|
|
||||||
- name: deploy-main
|
|
||||||
image: appleboy/drone-ssh
|
|
||||||
settings:
|
|
||||||
host:
|
|
||||||
from_secret: deploy_host
|
|
||||||
username:
|
|
||||||
from_secret: deploy_user
|
|
||||||
key:
|
|
||||||
from_secret: deploy_key
|
|
||||||
script:
|
|
||||||
- cd /opt/cast-ghl-provider
|
|
||||||
- git pull --ff-only
|
|
||||||
- docker compose build --no-cache bridge
|
|
||||||
- docker compose up -d --remove-orphans
|
|
||||||
- sleep 5
|
|
||||||
- docker compose ps bridge
|
|
||||||
when:
|
|
||||||
branch: main
|
|
||||||
event: push
|
event: push
|
||||||
|
|
||||||
|
- name: deploy
|
||||||
|
image: appleboy/drone-ssh
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: deploy_host
|
||||||
|
username:
|
||||||
|
from_secret: deploy_user
|
||||||
|
key:
|
||||||
|
from_secret: deploy_ssh_key
|
||||||
|
script:
|
||||||
|
- bash /opt/cast-ghl-provider/deploy/deploy.sh
|
||||||
|
when:
|
||||||
|
- branch: main
|
||||||
|
event: push
|
||||||
|
|
||||||
|
- name: notify-telegram
|
||||||
|
image: appleboy/drone-telegram
|
||||||
|
settings:
|
||||||
|
token:
|
||||||
|
from_secret: telegram_bot_token
|
||||||
|
to:
|
||||||
|
from_secret: telegram_chat_id
|
||||||
|
message: >
|
||||||
|
{{#success build.status}}✅{{else}}❌{{/success}} **{{repo.name}}**
|
||||||
|
|
||||||
|
Branch: `{{commit.branch}}`
|
||||||
|
|
||||||
|
Status: **{{build.status}}**
|
||||||
|
|
||||||
|
Commit: `{{commit.message}}`
|
||||||
|
|
||||||
|
{{build.link}}
|
||||||
|
when:
|
||||||
|
- status: [success, failure]
|
||||||
|
|||||||
@ -1,37 +1,22 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# deploy.sh — Manual redeploy on an existing Docker server.
|
# deploy.sh — Called by Woodpecker CI on every push to main.
|
||||||
# Normally Woodpecker CI handles deploys automatically on push to main or tag.
|
# Can also be run manually for emergency redeployments.
|
||||||
# Use this script only for manual/emergency redeploys.
|
# Pulls the latest image from the registry and restarts the stack.
|
||||||
# Usage: bash deploy/deploy.sh [--from-registry]
|
|
||||||
# --from-registry Pull the pre-built image from registry instead of building locally
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
APP_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
APP_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
cd "$APP_DIR"
|
cd "$APP_DIR"
|
||||||
|
|
||||||
FROM_REGISTRY=false
|
echo "==> Pulling latest image from registry"
|
||||||
[[ "${1:-}" == "--from-registry" ]] && FROM_REGISTRY=true
|
|
||||||
|
|
||||||
echo "==> Pulling latest code"
|
|
||||||
git pull --ff-only
|
|
||||||
|
|
||||||
if $FROM_REGISTRY; then
|
|
||||||
echo "==> Pulling pre-built image from registry"
|
|
||||||
docker compose pull bridge
|
docker compose pull bridge
|
||||||
else
|
|
||||||
echo "==> Building image locally"
|
|
||||||
docker compose build --no-cache bridge
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "==> Restarting services"
|
echo "==> Restarting services"
|
||||||
docker compose up -d --remove-orphans
|
docker compose up -d --remove-orphans
|
||||||
|
|
||||||
echo "==> Waiting for health check"
|
echo "==> Status"
|
||||||
sleep 5
|
sleep 3
|
||||||
docker compose ps bridge
|
docker compose ps bridge
|
||||||
docker compose logs --tail=20 bridge
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== Deploy complete ==="
|
echo "=== Deploy complete — https://hl.cast.ph/health ==="
|
||||||
echo "Health endpoint: https://hl.cast.ph/health"
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
bridge:
|
bridge:
|
||||||
build: .
|
image: git.sds.dev/cast/cast-ghl-provider:latest
|
||||||
|
build: . # used only for local dev (docker compose up --build); production uses the registry image
|
||||||
# No port binding — nginx-proxy routes traffic via the shared proxy network
|
# No port binding — nginx-proxy routes traffic via the shared proxy network
|
||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user