name: Build, Push and Deploy on: push: branches: - main jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 - name: Login to Container Registry uses: docker/login-action@v3 with: registry: ${{ vars.REGISTRY_URL }} username: ${{ secrets.CI_GITEA_USER }} password: ${{ secrets.CI_GITEA_TOKEN }} - name: Extract metadata for Docker id: meta run: | echo "image_tag=${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ github.sha }}" >> $GITHUB_OUTPUT echo "image_latest=${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:latest" >> $GITHUB_OUTPUT - name: Build and Push Docker Image uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: | ${{ steps.meta.outputs.image_tag }} ${{ steps.meta.outputs.image_latest }} - name: Deploy to Remote Server uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }} port: ${{ secrets.DEPLOY_SSH_PORT || '22' }} script: | set -e echo "=== Starting deployment ===" # Login to Container Registry echo "Logging in to registry..." echo "${{ secrets.CI_GITEA_TOKEN }}" | docker login ${{ vars.REGISTRY_URL }} -u ${{ secrets.CI_GITEA_USER }} --password-stdin # Pull new image echo "Pulling new image..." docker pull ${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ github.sha }} # Stop and remove old container (with retry logic) echo "Stopping old container..." if docker ps -a --format '{{.Names}}' | grep -q "^skamp-app$"; then docker stop skamp-app || true sleep 2 docker rm -f skamp-app || true sleep 1 fi # Start new container with environment variables echo "Starting new container..." docker run -d \ --name skamp-app \ --restart unless-stopped \ -p ${{ vars.APP_PORT }}:8080 \ -e SPRING_PROFILES_ACTIVE=${{ vars.SPRING_PROFILES_ACTIVE }} \ -e SPRING_DATASOURCE_URL=jdbc:postgresql://${{ secrets.POSTGRES_HOST }}:${{ secrets.POSTGRES_PORT }}/${{ secrets.POSTGRES_DB }} \ -e SPRING_DATASOURCE_USERNAME=${{ secrets.POSTGRES_USER }} \ -e SPRING_DATASOURCE_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} \ -e SPRING_JPA_HIBERNATE_DDL_AUTO=${{ vars.HIBERNATE_DDL_AUTO }} \ -e SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=${{ vars.KEYCLOAK_ISSUER_URI }} \ -e CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }} \ -e S3_ACCESS_KEY=${{ secrets.MINIO_ACCESS_KEY }} \ -e S3_SECRET_KEY=${{ secrets.MINIO_SECRET_KEY }} \ -e S3_ENDPOINT=${{ secrets.MINIO_ENDPOINT }} \ -e SERVER_PORT=8080 \ -e JAVA_OPTS="${{ vars.JAVA_OPTS }}" \ ${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ github.sha }} # Wait for container to start echo "Waiting for container to start..." sleep 3 # Check if container is running if docker ps --filter name=skamp-app --format '{{.Names}}' | grep -q "skamp-app"; then echo "✓ Container started successfully" docker ps --filter name=skamp-app else echo "✗ Container failed to start" docker logs skamp-app exit 1 fi # Clean up old images echo "Cleaning up old images..." docker image prune -af --filter "until=168h" || true echo "=== Deployment completed ==="