feat: entrypoint.sh dosyasındaki izin kontrolü güncellendi; dosya sis… #136
Workflow file for this run
This file contains hidden or 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: Notification Service CI/CD | |
| on: | |
| push: | |
| branches: [master] | |
| paths: | |
| - "notification-service/**" | |
| - "pom.xml" | |
| - ".github/workflows/notification-service-ci-cd.yml" | |
| workflow_dispatch: | |
| jobs: | |
| build-and-deploy: | |
| runs-on: self-hosted | |
| defaults: | |
| run: | |
| working-directory: ./notification-service | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - id: "auth" | |
| name: "Authenticate to Google Cloud" | |
| uses: "google-github-actions/auth@v1" | |
| with: | |
| credentials_json: "${{ secrets.GCP_SA_KEY }}" | |
| - name: Set up JDK | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: "21" | |
| distribution: "temurin" | |
| - name: Cache Maven packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.m2 | |
| key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: ${{ runner.os }}-m2 | |
| - name: Grant execute permission for mvnw | |
| run: chmod +x mvnw | |
| - name: Build | |
| run: ./mvnw clean package -DskipTests | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v2 | |
| with: | |
| platforms: arm64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| with: | |
| platforms: linux/arm64 | |
| - name: Login to DockerHub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| logout: true | |
| - name: Build and Push Docker image | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: ./notification-service # Değiştirildi | |
| file: ./notification-service/Dockerfile | |
| platforms: linux/arm64 | |
| push: true | |
| tags: | | |
| ${{ secrets.DOCKERHUB_USERNAME }}/notification-service:latest-arm64 | |
| ${{ secrets.DOCKERHUB_USERNAME }}/notification-service:${{ github.sha }}-arm64 | |
| cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/notification-service:buildcache-arm64 | |
| cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/notification-service:buildcache-arm64,mode=max | |
| - name: Deploy to VPS | |
| uses: appleboy/ssh-action@master | |
| with: | |
| host: ${{ secrets.VPS_HOST }} | |
| username: ${{ secrets.SSH_USERNAME }} | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| script: | | |
| echo "Starting deployment process..." | |
| # Debug mode enabled | |
| set -x | |
| echo "Checking Docker service status..." | |
| systemctl status docker || true | |
| # Infrastructure containers | |
| docker network create craftpilot-network || true | |
| # MongoDB container check | |
| MONGODB_CONTAINER="craftpilot-mongodb" | |
| if ! docker ps | grep -q "$MONGODB_CONTAINER"; then | |
| echo "WARNING: Default MongoDB container not found ($MONGODB_CONTAINER)" | |
| # Try to detect any MongoDB container as fallback | |
| MONGODB_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E 'mongo|mongodb' | head -n 1) | |
| if [ -z "$MONGODB_CONTAINER" ]; then | |
| echo "ERROR: No MongoDB container found! Using default name, but connection may fail." | |
| MONGODB_CONTAINER="craftpilot-mongodb" # Fallback to default | |
| else | |
| echo "Found alternative MongoDB container: $MONGODB_CONTAINER" | |
| fi | |
| fi | |
| echo "Using MongoDB container: $MONGODB_CONTAINER" | |
| # Test MongoDB connection before deployment | |
| echo "Testing MongoDB connection..." | |
| if docker run --rm --network craftpilot-network mongo:6.0 mongosh --quiet --eval "db.runCommand({ping:1}).ok" admin --host $MONGODB_CONTAINER --port 27017 -u ${{ secrets.MONGO_ROOT_USERNAME }} -p ${{ secrets.MONGO_ROOT_PASSWORD }} --authenticationDatabase admin | grep -q "1"; then | |
| echo "✅ MongoDB connection test successful!" | |
| else | |
| echo "⚠️ MongoDB connection test failed! Deployment will continue but may have issues." | |
| echo "Checking MongoDB container status:" | |
| docker ps | grep -i $MONGODB_CONTAINER || echo "Container not found!" | |
| fi | |
| echo "Checking existing containers..." | |
| docker ps -a | grep notification-service || true | |
| echo "Stopping and removing existing container..." | |
| docker stop notification-service || true | |
| docker rm notification-service || true | |
| echo "Setting up directories and permissions..." | |
| mkdir -p /opt/craftpilot/config/notification-service | |
| mkdir -p /craftpilot | |
| echo "Creating Firebase credentials..." | |
| # Standardize credentials path to /craftpilot/gcp-credentials.json | |
| echo '${{ secrets.GCP_SA_KEY }}' > /craftpilot/gcp-credentials.json | |
| chmod 644 /craftpilot/gcp-credentials.json | |
| ls -la /craftpilot/gcp-credentials.json | |
| # Also keep existing path for backward compatibility | |
| echo '${{ secrets.GCP_SA_KEY }}' > /opt/craftpilot/config/notification-service/firebase-service-account.json | |
| chmod 644 /opt/craftpilot/config/notification-service/firebase-service-account.json | |
| ls -la /opt/craftpilot/config/notification-service/firebase-service-account.json | |
| echo "#!/bin/sh | |
| curl -f http://localhost:8053/actuator/health || exit 1" > /opt/craftpilot/config/notification-service/healthcheck.sh | |
| chmod +x /opt/craftpilot/config/notification-service/healthcheck.sh | |
| # Create function definition in a variable to avoid semicolon issues | |
| FUNCTION_DEF="notificationEventConsumer;notificationEventProducer" | |
| # Setup networking config | |
| echo "Setting up networking config..." | |
| cat > /opt/craftpilot/config/notification-service/grpc-netty.properties << EOF | |
| io.netty.handler.ssl.openssl.useKeyManagerFactory=true | |
| EOF | |
| # Build MongoDB URI with the correct container name | |
| if [ -n "${{ secrets.MONGODB_URI }}" ]; then | |
| # Parse the URI and replace the hostname with our container name | |
| URI_PREFIX=$(echo "${{ secrets.MONGODB_URI }}" | grep -oP 'mongodb://[^@]+@') | |
| URI_SUFFIX=$(echo "$URI_PREFIX" | grep -oP '(?<=@)[^/]+/.*') | |
| URI_HOST=$(echo "$URI_SUFFIX" | grep -oP '^[^:/]+') | |
| URI_REMAINDER=$(echo "$URI_SUFFIX" | grep -oP '(?<='"$URI_HOST"')[:/].*') | |
| MONGODB_URI="${URI_PREFIX}${MONGODB_CONTAINER}${URI_REMAINDER}" | |
| echo "Modified MongoDB URI with correct container name: $(echo $MONGODB_URI | sed 's/:[^:]*@/:*****@/g')" | |
| else | |
| MONGODB_URI="mongodb://${{ secrets.MONGO_ROOT_USERNAME }}:${{ secrets.MONGO_ROOT_PASSWORD }}@${MONGODB_CONTAINER}:27017/craftpilot_notification_db?authSource=admin&retryWrites=true&w=majority&serverSelectionTimeoutMS=60000" | |
| echo "Built MongoDB URI from credential components: $(echo $MONGODB_URI | sed 's/:[^:]*@/:*****@/g')" | |
| fi | |
| echo "Starting container..." | |
| docker run -d \ | |
| --name notification-service \ | |
| --network craftpilot-network \ | |
| --restart unless-stopped \ | |
| --memory="1g" \ | |
| --memory-swap="2g" \ | |
| --memory-reservation="512m" \ | |
| --cpus="1.0" \ | |
| -p 8053:8053 \ | |
| -v /opt/craftpilot/config/notification-service:/app/config:ro \ | |
| -v "/opt/craftpilot/config/notification-service/firebase-service-account.json:/app/credentials/firebase-credentials.json:ro" \ | |
| -v "/craftpilot/gcp-credentials.json:/app/gcp-credentials.json:ro" \ | |
| -v "/opt/craftpilot/config/notification-service/grpc-netty.properties:/app/config/grpc-netty.properties:ro" \ | |
| -v "/opt/craftpilot/config/notification-service/healthcheck.sh:/app/healthcheck.sh:ro" \ | |
| -e FIREBASE_CONFIG=/app/credentials/firebase-credentials.json \ | |
| -e GOOGLE_APPLICATION_CREDENTIALS=/app/gcp-credentials.json \ | |
| -e SPRING_PROFILES_ACTIVE=prod \ | |
| -e SERVER_PORT=8053 \ | |
| -e KAFKA_BOOTSTRAP_SERVERS=kafka:9092 \ | |
| -e SPRING_KAFKA_BOOTSTRAP_SERVERS=kafka:9092 \ | |
| -e SPRING_CLOUD_STREAM_KAFKA_BINDER_BROKERS=kafka:9092 \ | |
| -e SPRING_CLOUD_STREAM_DEFAULT_BINDER=kafka \ | |
| -e "SPRING_CLOUD_FUNCTION_DEFINITION=${FUNCTION_DEF}" \ | |
| -e SPRING_CLOUD_STREAM_BINDINGS_PROCESSNOTIFICATION_IN_0_DESTINATION=notifications \ | |
| -e SPRING_CLOUD_STREAM_BINDINGS_PROCESSNOTIFICATION_IN_0_GROUP=notification-service-group \ | |
| -e SPRING_CLOUD_STREAM_BINDINGS_PROCESSNOTIFICATION_OUT_0_DESTINATION=notifications \ | |
| -e REDIS_HOST=redis \ | |
| -e REDIS_PORT=6379 \ | |
| -e REDIS_PASSWORD=13579ada \ | |
| -e SPRING_DATA_REDIS_HOST=redis \ | |
| -e SPRING_DATA_REDIS_PORT=6379 \ | |
| -e SPRING_DATA_REDIS_PASSWORD=13579ada \ | |
| -e MONGODB_URI="${MONGODB_URI}" \ | |
| -e SPRING_DATA_MONGODB_URI="${MONGODB_URI}" \ | |
| -e SPRING_DATA_MONGODB_DATABASE=craftpilot_notification_db \ | |
| -e EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://craftpilot:13579ada@eureka-server:8761/eureka/ \ | |
| -e SPRING_MAIL_SENDGRID_FROM='${{ secrets.SENDGRID_FROM_EMAIL }}' \ | |
| -e SPRING_MAIL_HOST=smtp.sendgrid.net \ | |
| -e SPRING_MAIL_PORT=587 \ | |
| -e SPRING_MAIL_USERNAME=apikey \ | |
| -e SPRING_MAIL_PASSWORD='${{ secrets.SENDGRID_API_KEY }}' \ | |
| -e MANAGEMENT_HEALTH_MAIL_ENABLED=false \ | |
| -e SPRING_MAIL_ENABLED=false \ | |
| -e SPRING_SENDGRID_API_KEY='${{ secrets.SENDGRID_API_KEY }}' \ | |
| -e SPRING_SENDGRID_ENABLED=true \ | |
| --dns 8.8.8.8 \ | |
| --dns 8.8.4.4 \ | |
| --health-cmd="/healthcheck.sh" \ | |
| --health-interval=30s \ | |
| --health-timeout=10s \ | |
| --health-retries=5 \ | |
| --health-start-period=180s \ | |
| ${{ secrets.DOCKERHUB_USERNAME }}/notification-service:latest-arm64 | |
| echo "Waiting for container to start..." | |
| sleep 30 | |
| echo "Performing enhanced health checks..." | |
| # Install jq if not present for proper JSON parsing | |
| if ! command -v jq &> /dev/null; then | |
| apt-get update && apt-get install -y jq || echo "Could not install jq, will use alternatives" | |
| fi | |
| # Enhanced health check with component verification | |
| for i in {1..20}; do | |
| if ! docker ps | grep -q "notification-service"; then | |
| echo "❌ Container stopped unexpectedly!" | |
| docker logs notification-service || echo "No logs available" | |
| exit 1 | |
| fi | |
| # Try health check with better parsing | |
| HEALTH_CHECK=$(curl -s http://localhost:8053/actuator/health || echo "{}") | |
| # Check if overall service is UP | |
| if echo "$HEALTH_CHECK" | grep -q '"status":"UP"'; then | |
| echo "✅ Service reports overall status as UP!" | |
| # Try to parse with jq if available | |
| if command -v jq &> /dev/null; then | |
| MONGO_STATUS=$(echo "$HEALTH_CHECK" | jq -r '.components.mongodb.status' 2>/dev/null || echo "UNKNOWN") | |
| REDIS_STATUS=$(echo "$HEALTH_CHECK" | jq -r '.components.redis.status' 2>/dev/null || echo "UNKNOWN") | |
| if [ "$MONGO_STATUS" = "UP" ] && [ "$REDIS_STATUS" = "UP" ]; then | |
| echo "✅ All critical components are healthy!" | |
| echo "Deployment completed successfully!" | |
| docker logs notification-service --tail 20 | |
| exit 0 | |
| else | |
| echo "⚠️ Service is UP but component statuses - MongoDB: $MONGO_STATUS, Redis: $REDIS_STATUS" | |
| fi | |
| elif echo "$HEALTH_CHECK" | grep -q '"mongodb":{.*"status":"UP"' && echo "$HEALTH_CHECK" | grep -q '"redis":{.*"status":"UP"'; then | |
| echo "✅ All critical components are healthy based on string search!" | |
| echo "Deployment completed successfully!" | |
| docker logs notification-service --tail 20 | |
| exit 0 | |
| fi | |
| # If we've been UP for several checks, assume success | |
| if [ $i -ge 10 ]; then | |
| echo "✅ Service has been reporting UP status for multiple checks" | |
| echo "Assuming deployment is successful" | |
| docker logs notification-service --tail 20 | |
| exit 0 | |
| fi | |
| fi | |
| echo "Health check attempt $i/20 - service not ready yet or components not healthy" | |
| # Enhanced diagnostics on certain iterations | |
| if [ $i -eq 5 ] || [ $i -eq 10 ] || [ $i -eq 15 ]; then | |
| echo "--- Connection Diagnostics ---" | |
| echo "MongoDB container status:" | |
| docker ps | grep $MONGODB_CONTAINER || echo "MongoDB container not running!" | |
| echo "Redis container status:" | |
| docker ps | grep redis || echo "Redis container not running!" | |
| echo "Testing network connectivity:" | |
| docker exec notification-service nc -zv $MONGODB_CONTAINER 27017 || echo "Cannot connect to MongoDB" | |
| docker exec notification-service nc -zv redis 6379 || echo "Cannot connect to Redis" | |
| echo "Container environment variables:" | |
| docker exec notification-service env | grep -E 'MONGO|REDIS|SENDGRID' || echo "No relevant env vars found" | |
| echo "Network details:" | |
| docker network inspect craftpilot-network | grep -A 5 -E "$MONGODB_CONTAINER|redis|notification-service" || echo "Network inspection failed" | |
| fi | |
| sleep 15 | |
| done | |
| echo "❌ Service failed to become fully healthy within timeout period." | |
| echo "Final container logs:" | |
| docker logs notification-service --tail 50 | |
| echo "Container is still running for debugging purposes." | |
| # Testing external connectivity | |
| echo "Testing SendGrid API connectivity..." | |
| docker exec notification-service curl -v https://api.sendgrid.com/v3/mail/send -H "Authorization: Bearer $SENDGRID_API_KEY" || echo "SendGrid connection failed" | |
| exit 1 | |
| # Disable debug mode | |
| set +x |