feat: modify deployment workflow to use local Dockerfiles and enhance… #84
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: Build and Deploy to VM | |
| on: | |
| push: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| jobs: | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| env: | |
| ORACLE_VM_IP: ${{ secrets.ORACLE_VM_IP }} | |
| DOCKER_REGISTRY: ${{ secrets.OCI_REGISTRY }} | |
| OCI_USERNAME: ${{ secrets.OCI_USERNAME }} | |
| OCI_AUTH_TOKEN: ${{ secrets.OCI_AUTH_TOKEN }} | |
| SSH_KEY_PATH: ~/.ssh/id_rsa | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| - name: Set up JDK 8 | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: '8' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Configure Maven settings | |
| run: | | |
| mkdir -p ~/.m2 | |
| cat > ~/.m2/settings.xml << EOF | |
| <settings> | |
| <mirrors> | |
| <mirror> | |
| <id>google-maven-central</id> | |
| <name>Google Maven Central</name> | |
| <url>https://maven-central.storage-download.googleapis.com/maven2/</url> | |
| <mirrorOf>central</mirrorOf> | |
| </mirror> | |
| </mirrors> | |
| </settings> | |
| EOF | |
| - name: Build with Maven (with retries) | |
| run: | | |
| max_attempts=3 | |
| attempt=1 | |
| while [ $attempt -le $max_attempts ]; do | |
| echo "Build attempt $attempt of $max_attempts" | |
| if mvn -B clean package -DskipTests; then | |
| echo "Build succeeded" | |
| break | |
| else | |
| echo "Build failed, retrying..." | |
| attempt=$((attempt+1)) | |
| sleep 30 | |
| fi | |
| done | |
| if [ $attempt -gt $max_attempts ]; then | |
| echo "Build failed after $max_attempts attempts" | |
| exit 1 | |
| fi | |
| - name: Verify build artifacts | |
| run: | | |
| echo "Checking JAR files..." | |
| for service in eureka-server api-gateway recommendation-service statistics-service user-tracking-service; do | |
| jar_files=$(find $service/target -type f -name "$service*.jar" | grep -v original || echo "") | |
| if [ -z "$jar_files" ]; then | |
| echo "ERROR: JAR file for $service not found!" | |
| find $service/target -type f -name "*.jar" || echo "No JARs found" | |
| exit 1 | |
| fi | |
| done | |
| - name: List target directory contents | |
| run: | | |
| echo "Listing all target directories contents..." | |
| for service in eureka-server api-gateway recommendation-service statistics-service user-tracking-service; do | |
| echo "=== $service/target contents: ===" | |
| ls -la $service/target/ || echo "No target directory found" | |
| done | |
| - name: Prepare Docker build context | |
| run: | | |
| # Create directories under vm-deploy for each service | |
| mkdir -p vm-deploy/eureka-server \ | |
| vm-deploy/api-gateway \ | |
| vm-deploy/recommendation-service \ | |
| vm-deploy/statistics-service \ | |
| vm-deploy/user-tracking-service | |
| # Copy the pre-built JAR files directly into the vm-deploy directories with simplified names | |
| cp $(find eureka-server/target -type f -name "eureka-server*.jar" | grep -v original) vm-deploy/eureka-server/eureka-server.jar | |
| cp $(find api-gateway/target -type f -name "api-gateway*.jar" | grep -v original) vm-deploy/api-gateway/api-gateway.jar | |
| cp $(find recommendation-service/target -type f -name "recommendation-service*.jar" | grep -v original) vm-deploy/recommendation-service/recommendation-service.jar | |
| cp $(find statistics-service/target -type f -name "statistics-service*.jar" | grep -v original) vm-deploy/statistics-service/statistics-service.jar | |
| cp $(find user-tracking-service/target -type f -name "user-tracking-service*.jar" | grep -v original) vm-deploy/user-tracking-service/user-tracking-service.jar | |
| # Use the simplified Dockerfiles in the vm-deploy directories | |
| cat > vm-deploy/eureka-server/Dockerfile << 'EOF' | |
| FROM openjdk:8-jre-slim | |
| WORKDIR /app | |
| COPY eureka-server.jar app.jar | |
| EXPOSE 8761 | |
| ENTRYPOINT ["java", "-jar", "app.jar"] | |
| EOF | |
| cat > vm-deploy/api-gateway/Dockerfile << 'EOF' | |
| FROM openjdk:8-jre-slim | |
| WORKDIR /app | |
| COPY api-gateway.jar app.jar | |
| EXPOSE 8080 | |
| ENTRYPOINT ["java", "-jar", "app.jar"] | |
| EOF | |
| cat > vm-deploy/recommendation-service/Dockerfile << 'EOF' | |
| FROM openjdk:8-jre-slim | |
| WORKDIR /app | |
| COPY recommendation-service.jar app.jar | |
| EXPOSE 8082 | |
| ENTRYPOINT ["java", "-jar", "app.jar"] | |
| EOF | |
| cat > vm-deploy/statistics-service/Dockerfile << 'EOF' | |
| FROM openjdk:8-jre-slim | |
| WORKDIR /app | |
| COPY statistics-service.jar app.jar | |
| EXPOSE 8083 | |
| ENTRYPOINT ["java", "-jar", "app.jar"] | |
| EOF | |
| cat > vm-deploy/user-tracking-service/Dockerfile << 'EOF' | |
| FROM openjdk:8-jre-slim | |
| WORKDIR /app | |
| COPY user-tracking-service.jar app.jar | |
| EXPOSE 8084 | |
| ENTRYPOINT ["java", "-jar", "app.jar"] | |
| EOF | |
| echo "Verifying copied files:" | |
| ls -la vm-deploy/*/ | |
| - name: Debug environment variables | |
| run: | | |
| echo "Checking environment variables (sensitive data masked):" | |
| echo "ORACLE_VM_IP is set: ${{ secrets.ORACLE_VM_IP != '' }}" | |
| echo "DOCKER_REGISTRY is set: ${{ secrets.OCI_REGISTRY != '' }}" | |
| echo "OCI_USERNAME is set: ${{ secrets.OCI_USERNAME != '' }}" | |
| echo "OCI_AUTH_TOKEN is set: ${{ secrets.OCI_AUTH_TOKEN != '' }}" | |
| - name: Set up SSH key | |
| run: | | |
| mkdir -p $HOME/.ssh | |
| chmod 700 $HOME/.ssh | |
| ls -la $HOME/.ssh || echo "Unable to list .ssh directory" | |
| if [ -z "${{ secrets.SSH_PRIVATE_KEY }}" ]; then | |
| echo "ERROR: SSH_PRIVATE_KEY secret is not set!" | |
| exit 1 | |
| fi | |
| echo "${{ secrets.SSH_PRIVATE_KEY }}" > $HOME/.ssh/id_rsa | |
| ls -la $HOME/.ssh/id_rsa || { echo "ERROR: Failed to create SSH key file!"; exit 1; } | |
| chmod 600 $HOME/.ssh/id_rsa || { echo "ERROR: Failed to set permissions on SSH key file!"; exit 1; } | |
| key_size=$(stat -c %s $HOME/.ssh/id_rsa) | |
| echo "SSH key file size: $key_size bytes" | |
| if [ -z "${{ secrets.ORACLE_VM_IP }}" ]; then | |
| echo "ERROR: ORACLE_VM_IP secret is not set!" | |
| exit 1 | |
| fi | |
| touch $HOME/.ssh/known_hosts | |
| ssh-keyscan -H ${{ secrets.ORACLE_VM_IP }} >> $HOME/.ssh/known_hosts | |
| echo "Testing SSH connection..." | |
| ssh -o BatchMode=yes -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa opc@${{ secrets.ORACLE_VM_IP }} "echo SSH connection successful" || { | |
| ls -la $HOME/.ssh/ | |
| head -1 $HOME/.ssh/id_rsa | |
| exit 1 | |
| } | |
| - name: Prepare environment file | |
| run: | | |
| cat > vm-deploy/.env << EOF | |
| DOCKER_REGISTRY=${{ secrets.OCI_REGISTRY }} | |
| OCI_USERNAME=${{ secrets.OCI_USERNAME }} | |
| OCI_AUTH_TOKEN=${{ secrets.OCI_AUTH_TOKEN }} | |
| EOF | |
| echo "Created .env file for docker-compose" | |
| echo "DOCKER_REGISTRY, OCI_USERNAME, OCI_AUTH_TOKEN are set" | |
| - name: Deploy to Oracle VM | |
| run: | | |
| # Create the base directory on the remote VM | |
| ssh -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa opc@${{ secrets.ORACLE_VM_IP }} "mkdir -p ~/music-analytics/vm-deploy" | |
| # Recursively copy each service directory to the remote VM with the destination path quoted | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa -r vm-deploy/eureka-server opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/eureka-server" | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa -r vm-deploy/api-gateway opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/api-gateway" | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa -r vm-deploy/recommendation-service opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/recommendation-service" | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa -r vm-deploy/statistics-service opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/statistics-service" | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa -r vm-deploy/user-tracking-service opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/user-tracking-service" | |
| # Copy the docker-compose file and environment file to the remote VM | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa cloud-deploy/docker-compose.direct.yml opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/docker-compose.yml" | |
| scp -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa vm-deploy/.env opc@${{ secrets.ORACLE_VM_IP }}:"~/music-analytics/vm-deploy/.env" | |
| # On the remote VM: log in to the Docker registry, build images for each service, and deploy containers | |
| ssh -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa opc@${{ secrets.ORACLE_VM_IP }} "cd ~/music-analytics/vm-deploy && \ | |
| echo 'Logging in to Docker registry...' && \ | |
| echo \"${{ secrets.OCI_AUTH_TOKEN }}\" | docker login ${{ secrets.OCI_REGISTRY }} -u ${{ secrets.OCI_USERNAME }} --password-stdin && \ | |
| echo 'Stopping and removing existing containers if any...' && \ | |
| docker ps -q | xargs -r docker stop && docker ps -aq | xargs -r docker rm && \ | |
| echo 'Modifying docker-compose.yml to use local Dockerfiles...' && \ | |
| sed -i '/^version:/d' docker-compose.yml && \ | |
| sed -i 's|build:\\n context: ./|build: ./|g' docker-compose.yml && \ | |
| echo 'Building Docker images locally...' && \ | |
| for service in eureka-server api-gateway recommendation-service statistics-service user-tracking-service; do \ | |
| cd \$service && \ | |
| docker build -t music-analytics/\$service . || exit 1; \ | |
| cd .. ; \ | |
| done && \ | |
| echo 'Starting new containers with docker-compose...' && \ | |
| docker-compose up -d && \ | |
| echo 'Container status:' && docker-compose ps" | |
| - name: Debug on failure | |
| if: failure() | |
| run: | | |
| if [ -f "$HOME/.ssh/id_rsa" ]; then | |
| ssh -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa opc@${{ secrets.ORACLE_VM_IP }} ' | |
| echo "==== ENVIRONMENT VARIABLES ====" && | |
| env | grep DOCKER || echo "No Docker environment variables found" && | |
| echo "==== DOCKER-COMPOSE FILE CONTENT ====" && | |
| cat ~/music-analytics/vm-deploy/docker-compose.yml || echo "No docker-compose file found" && | |
| echo "==== DIRECTORY CONTENT ====" && | |
| ls -la ~/music-analytics/vm-deploy/ && | |
| for service in eureka-server api-gateway recommendation-service statistics-service user-tracking-service; do | |
| echo "==== $service DIRECTORY CONTENT ====" && | |
| ls -la ~/music-analytics/vm-deploy/$service/ | |
| done && | |
| echo "==== EUREKA SERVER LOGS ====" && | |
| docker logs $(docker ps -q -f name=eureka-server) || echo "No eureka-server logs available" && | |
| echo "==== ALL CONTAINERS ====" && | |
| docker ps -a || echo "No containers found" | |
| ' | |
| else | |
| echo "SSH key file not found, cannot retrieve logs" | |
| fi |