184 lines
5.7 KiB
YAML
184 lines
5.7 KiB
YAML
stages:
|
|
- build
|
|
- test
|
|
- scan
|
|
- deploy
|
|
- load-test
|
|
- backup
|
|
.build-service:
|
|
stage: build
|
|
image: docker:27-cli
|
|
services: [] # host-socket build, same pattern as ci-images — no DinD
|
|
before_script:
|
|
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
|
|
script:
|
|
- docker build --pull -t "$CI_REGISTRY_IMAGE/$SERVICE_NAME:latest" -t "$CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_SHORT_SHA" "$SERVICE_NAME"
|
|
- docker push "$CI_REGISTRY_IMAGE/$SERVICE_NAME:latest"
|
|
- docker push "$CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_SHORT_SHA"
|
|
|
|
build-vote:
|
|
extends: .build-service
|
|
variables:
|
|
SERVICE_NAME: vote
|
|
|
|
build-result:
|
|
extends: .build-service
|
|
variables:
|
|
SERVICE_NAME: result
|
|
|
|
build-worker:
|
|
extends: .build-service
|
|
variables:
|
|
SERVICE_NAME: worker
|
|
|
|
test-vote:
|
|
stage: test
|
|
image: docker:27-cli
|
|
services: []
|
|
script:
|
|
- docker network create test-net-$CI_JOB_ID
|
|
- docker run -d --name vote-test-$CI_JOB_ID --network test-net-$CI_JOB_ID "$CI_REGISTRY_IMAGE/vote:$CI_COMMIT_SHORT_SHA"
|
|
- sleep 5
|
|
- docker run --rm --network test-net-$CI_JOB_ID curlimages/curl:latest curl -sf "http://vote-test-$CI_JOB_ID:80/"
|
|
after_script:
|
|
- docker rm -f vote-test-$CI_JOB_ID || true
|
|
- docker network rm test-net-$CI_JOB_ID || true
|
|
|
|
test-result:
|
|
stage: test
|
|
image: docker:27-cli
|
|
services: []
|
|
script:
|
|
- docker network create test-net-$CI_JOB_ID
|
|
- docker run -d --name result-test-$CI_JOB_ID --network test-net-$CI_JOB_ID "$CI_REGISTRY_IMAGE/result:$CI_COMMIT_SHORT_SHA"
|
|
- sleep 5
|
|
- docker run --rm --network test-net-$CI_JOB_ID curlimages/curl:latest curl -sf "http://result-test-$CI_JOB_ID:80/"
|
|
after_script:
|
|
- docker rm -f result-test-$CI_JOB_ID || true
|
|
- docker network rm test-net-$CI_JOB_ID || true
|
|
|
|
test-worker:
|
|
stage: test
|
|
image: docker:27-cli
|
|
services: []
|
|
script:
|
|
- docker run -d --name worker-test-$CI_JOB_ID "$CI_REGISTRY_IMAGE/worker:$CI_COMMIT_SHORT_SHA"
|
|
- sleep 5
|
|
- |
|
|
STATUS=$(docker inspect -f '{{.State.Running}}' worker-test-$CI_JOB_ID)
|
|
if [ "$STATUS" != "true" ]; then
|
|
echo "worker exited unexpectedly on startup"
|
|
docker logs worker-test-$CI_JOB_ID
|
|
exit 1
|
|
fi
|
|
after_script:
|
|
- docker rm -f worker-test-$CI_JOB_ID || true
|
|
.scan-service:
|
|
stage: scan
|
|
image:
|
|
name: aquasec/trivy:latest
|
|
entrypoint: [""]
|
|
variables:
|
|
TRIVY_DB_REPOSITORY: "ghcr.io/aquasecurity/trivy-db:2"
|
|
TRIVY_CACHE_DIR: ".trivycache/"
|
|
cache:
|
|
key: trivy-db-cache
|
|
paths:
|
|
- .trivycache/
|
|
script:
|
|
- trivy image --exit-code 1 --ignore-unfixed --severity CRITICAL,HIGH --format table "$CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_SHORT_SHA"
|
|
scan-vote:
|
|
extends: .scan-service
|
|
variables:
|
|
SERVICE_NAME: vote
|
|
|
|
scan-result:
|
|
extends: .scan-service
|
|
variables:
|
|
SERVICE_NAME: result
|
|
|
|
scan-worker:
|
|
extends: .scan-service
|
|
variables:
|
|
SERVICE_NAME: worker
|
|
|
|
deploy-dev:
|
|
stage: deploy
|
|
image: docker:27-cli
|
|
services: []
|
|
variables:
|
|
IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
|
|
VOTE_PORT: "5100"
|
|
RESULT_PORT: "5101"
|
|
environment:
|
|
name: dev
|
|
script:
|
|
- docker compose -p voting-dev -f docker-compose.deploy.yml up -d
|
|
- sleep 10
|
|
- docker compose -p voting-dev -f docker-compose.deploy.yml ps
|
|
- docker compose -p voting-dev -f docker-compose.deploy.yml exec -T vote curl -sf http://localhost:80/
|
|
- docker compose -p voting-dev -f docker-compose.deploy.yml exec -T result curl -sf http://localhost:80/
|
|
after_script:
|
|
- docker compose -p voting-dev -f docker-compose.deploy.yml down -v
|
|
|
|
deploy-staging:
|
|
stage: deploy
|
|
image: docker:27-cli
|
|
services: []
|
|
variables:
|
|
IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
|
|
VOTE_PORT: "5200"
|
|
RESULT_PORT: "5201"
|
|
environment:
|
|
name: staging
|
|
url: "http://192.168.100.6:5200"
|
|
when: manual
|
|
script:
|
|
- docker compose -p voting-staging -f docker-compose.deploy.yml up -d
|
|
- sleep 10
|
|
- docker compose -p voting-staging -f docker-compose.deploy.yml exec -T vote curl -sf http://localhost:80/
|
|
- docker compose -p voting-staging -f docker-compose.deploy.yml exec -T result curl -sf http://localhost:80/
|
|
deploy-prod:
|
|
stage: deploy
|
|
image: docker:27-cli
|
|
services: []
|
|
variables:
|
|
IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
|
|
VOTE_PORT: "5300"
|
|
RESULT_PORT: "5301"
|
|
environment:
|
|
name: production
|
|
url: "http://192.168.100.6:5300"
|
|
when: manual
|
|
script:
|
|
- docker compose -p voting-prod -f docker-compose.deploy.yml up -d
|
|
- sleep 10
|
|
- docker compose -p voting-prod -f docker-compose.deploy.yml exec -T vote curl -sf http://localhost:80/
|
|
- docker compose -p voting-prod -f docker-compose.deploy.yml exec -T result curl -sf http://localhost:80/
|
|
load-test-staging:
|
|
stage: load-test
|
|
image:
|
|
name: grafana/k6:latest
|
|
entrypoint: [""]
|
|
when: manual
|
|
needs: ["deploy-staging"]
|
|
script:
|
|
- k6 run -e TARGET_HOST=192.168.100.6 -e VOTE_PORT=5200 loadtest/vote-load-test.js
|
|
backup-prod-db:
|
|
stage: backup
|
|
image: docker:27-cli
|
|
services: []
|
|
when: manual
|
|
needs: ["deploy-prod"]
|
|
script:
|
|
- export BACKUP_FILE="voting-prod-$(date +%Y%m%d-%H%M%S).sql.gz"
|
|
- docker exec voting-prod-db-1 pg_dump -U postgres postgres | gzip > "$BACKUP_FILE"
|
|
- docker create --name mc-helper-$CI_JOB_ID --entrypoint sh minio/mc:RELEASE.2025-08-13T08-35-41Z-cpuv1 -c "sleep 300"
|
|
- docker start mc-helper-$CI_JOB_ID
|
|
- docker cp "$BACKUP_FILE" mc-helper-$CI_JOB_ID:/tmp/"$BACKUP_FILE"
|
|
- docker exec mc-helper-$CI_JOB_ID mc alias set localminio http://192.168.100.6:9500 "$MINIO_ACCESS_KEY" "$MINIO_SECRET_KEY"
|
|
- docker exec mc-helper-$CI_JOB_ID mc cp /tmp/"$BACKUP_FILE" localminio/postgres-backups/
|
|
- docker exec mc-helper-$CI_JOB_ID mc ls localminio/postgres-backups/
|
|
after_script:
|
|
- docker rm -f mc-helper-$CI_JOB_ID || true
|