kind: pipeline type: docker name: default trigger: branch: - main - develop - feature/* event: - push - pull_request - tag volumes: - name: docker host: path: /var/run/docker.sock steps: # Frontend Tests - name: frontend-test image: node:18-alpine commands: - cd frontend - npm ci --legacy-peer-deps - npm run lint - npm run build when: event: - push - pull_request # Backend Tests - name: backend-test image: node:18-alpine commands: - cd backend - npm ci - npm run lint - npm test environment: NODE_ENV: test JWT_SECRET: test-secret when: event: - push - pull_request # Build Frontend Docker Image - name: build-frontend image: plugins/docker settings: repo: registry.local.nothaft.cloud/wedding-photo-sharing-frontend tags: - latest - ${DRONE_COMMIT_SHA:0:8} - ${DRONE_TAG} dockerfile: frontend/Dockerfile context: frontend registry: registry.local.nothaft.cloud when: branch: - main event: - push - tag # Build Backend Docker Image - name: build-backend image: plugins/docker settings: repo: registry.local.nothaft.cloud/wedding-photo-sharing-backend tags: - latest - ${DRONE_COMMIT_SHA:0:8} - ${DRONE_TAG} dockerfile: backend/Dockerfile context: backend registry: registry.local.nothaft.cloud when: branch: - main event: - push - tag # Security Scan - name: security-scan image: aquasec/trivy:latest commands: - trivy image --exit-code 0 --no-progress registry.local.nothaft.cloud/wedding-photo-sharing-frontend:${DRONE_COMMIT_SHA:0:8} - trivy image --exit-code 0 --no-progress registry.local.nothaft.cloud/wedding-photo-sharing-backend:${DRONE_COMMIT_SHA:0:8} environment: DOCKER_HOST: tcp://docker:2375 volumes: - name: docker path: /var/run/docker.sock when: branch: - main event: - push # Deploy to Staging - name: deploy-staging image: alpine:latest environment: SWARM_HOST: from_secret: staging_swarm_host SWARM_USER: from_secret: staging_swarm_user SWARM_KEY: from_secret: staging_swarm_key REGISTRY_URL: from_secret: docker_registry VERSION: ${DRONE_COMMIT_SHA:0:8} commands: - apk add --no-cache openssh-client - mkdir -p ~/.ssh - echo "$SWARM_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H $SWARM_HOST >> ~/.ssh/known_hosts - | ssh $SWARM_USER@$SWARM_HOST << EOF cd /opt/wedding-photo-sharing export REGISTRY_URL=registry.local.nothaft.cloud export VERSION=$VERSION docker stack deploy -c deploy/docker-stack.yml wedding-photo-sharing EOF when: branch: - develop event: - push # Deploy to Production - name: deploy-production image: alpine:latest environment: SWARM_HOST: from_secret: prod_swarm_host SWARM_USER: from_secret: prod_swarm_user SWARM_KEY: from_secret: prod_swarm_key REGISTRY_URL: from_secret: docker_registry VERSION: ${DRONE_TAG:-latest} commands: - apk add --no-cache openssh-client - mkdir -p ~/.ssh - echo "$SWARM_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H $SWARM_HOST >> ~/.ssh/known_hosts - | ssh $SWARM_USER@$SWARM_HOST << EOF cd /opt/wedding-photo-sharing export REGISTRY_URL=registry.local.nothaft.cloud export VERSION=$VERSION # Backup database before deployment docker exec \$(docker ps -q -f name=wedding-photo-sharing_db) pg_dump -U postgres wedding_photo_sharing > /backup/db-backup-\$(date +%Y%m%d-%H%M%S).sql # Deploy stack docker stack deploy -c deploy/docker-stack.yml wedding-photo-sharing --with-registry-auth # Wait for services to be ready sleep 30 # Run migrations if needed docker exec \$(docker ps -q -f name=wedding-photo-sharing_backend) npm run migrate EOF when: event: - tag # Health Check - name: health-check image: alpine:latest commands: - apk add --no-cache curl - sleep 30 - curl -f https://${FRONTEND_HOST}/health || exit 1 - curl -f https://${BACKEND_HOST}/api/health || exit 1 when: branch: - main event: - push - tag # Notification - Success - name: notify-success image: plugins/slack settings: webhook: from_secret: slack_webhook channel: deployments template: | ✅ *Build {{build.number}} succeeded* for {{repo.name}} Branch: {{build.branch}} Commit: {{build.commit}} Author: {{build.author}} {{#if build.tag}} 🏷️ Tag: {{build.tag}} 🚀 Deployed to *PRODUCTION* {{else}} 📦 Deployed to *{{build.branch}}* {{/if}} 🔗 {{build.link}} when: status: - success # Notification - Failure - name: notify-failure image: plugins/slack settings: webhook: from_secret: slack_webhook channel: deployments template: | ❌ *Build {{build.number}} failed* for {{repo.name}} Branch: {{build.branch}} Commit: {{build.commit}} Author: {{build.author}} 🔗 {{build.link}} when: status: - failure --- kind: pipeline type: docker name: rollback trigger: event: - rollback steps: - name: rollback-production image: alpine:latest environment: SWARM_HOST: from_secret: prod_swarm_host SWARM_USER: from_secret: prod_swarm_user SWARM_KEY: from_secret: prod_swarm_key REGISTRY_URL: from_secret: docker_registry commands: - apk add --no-cache openssh-client - mkdir -p ~/.ssh - echo "$SWARM_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H $SWARM_HOST >> ~/.ssh/known_hosts - | ssh $SWARM_USER@$SWARM_HOST << EOF cd /opt/wedding-photo-sharing export REGISTRY_URL=registry.local.nothaft.cloud export VERSION=${DRONE_ROLLBACK_TO} # Deploy previous version docker stack deploy -c deploy/docker-stack.yml wedding-photo-sharing --with-registry-auth EOF --- kind: secret name: slack_webhook get: path: drone/slack name: webhook