Rename Screenshot (107).png to EC2 Instance.png #24
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: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| jobs: | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: . | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ secrets.DOCKER_USERNAME }}/nodejs-app:latest,${{ secrets.DOCKER_USERNAME }}/nodejs-app:${{ github.sha }} | |
| cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/nodejs-app:buildcache | |
| cache-to: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/nodejs-app:buildcache,mode=max | |
| - name: Deploy to AWS EC2 | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| env: | |
| DOCKER_IMAGE: ${{ secrets.DOCKER_USERNAME }}/nodejs-app:${{ github.sha }} | |
| DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }} | |
| run: | | |
| # Setup SSH directory | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| # Write the private key file | |
| echo "${{ secrets.AWS_SSH_KEY }}" > ~/.ssh/deploy_key | |
| chmod 600 ~/.ssh/deploy_key | |
| # Setup SSH config | |
| cat > ~/.ssh/config << EOF | |
| Host * | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile=/dev/null | |
| IdentityFile ~/.ssh/deploy_key | |
| EOF | |
| chmod 600 ~/.ssh/config | |
| # For debugging (optional) | |
| echo "Testing SSH connection..." | |
| ssh -v -i ~/.ssh/deploy_key ec2-user@${{ secrets.AWS_HOST }} "echo 'SSH connection successful'" | |
| # Deploy | |
| ssh -i ~/.ssh/deploy_key ec2-user@${{ secrets.AWS_HOST }} "\ | |
| set -e && \ | |
| echo 'Pulling Docker image...' && \ | |
| docker pull ${DOCKER_IMAGE} && \ | |
| echo 'Stopping existing container...' && \ | |
| if docker ps -a | grep -q 'nodejs-app'; then \ | |
| docker stop nodejs-app || true && \ | |
| docker rm nodejs-app || true; \ | |
| fi && \ | |
| echo 'Starting new container...' && \ | |
| docker run -d \ | |
| --name nodejs-app \ | |
| --restart unless-stopped \ | |
| -p ${DEPLOY_PORT}:3000 \ | |
| --health-cmd='curl -f http://localhost:3000/health || exit 1' \ | |
| --health-interval=30s \ | |
| --health-timeout=10s \ | |
| --health-retries=3 \ | |
| ${DOCKER_IMAGE} && \ | |
| echo 'Verifying deployment...' && \ | |
| if ! docker ps | grep -q 'nodejs-app'; then \ | |
| echo 'Container failed to start' && \ | |
| exit 1; \ | |
| fi && \ | |
| echo 'Cleaning up old images...' && \ | |
| docker image prune -f" | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| rm -rf ~/.ssh/deploy_key ~/.ssh/config |