name: Deploy Production on: push: branches: - main - master workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest # If using self-hosted runner, change to: # runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to Docker Registry (Optional) if: ${{ secrets.DOCKER_REGISTRY_URL != '' }} uses: docker/login-action@v2 with: registry: ${{ secrets.DOCKER_REGISTRY_URL }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker Image run: | docker build -t merchbay_admin:latest . - name: Save Docker Image run: | docker save merchbay_admin:latest | gzip > merchbay_admin.tar.gz - name: Deploy to Server via SSH uses: appleboy/scp-action@master with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} port: ${{ secrets.DEPLOY_PORT || 22 }} source: "merchbay_admin.tar.gz,docker-compose.yml" target: "/tmp/merchbay_admin_deploy" - name: Execute Production Deployment Script uses: appleboy/ssh-action@master with: host: ${{ secrets.PROD_DEPLOY_HOST }} username: ${{ secrets.PROD_DEPLOY_USER }} key: ${{ secrets.PROD_DEPLOY_SSH_KEY }} port: ${{ secrets.PROD_DEPLOY_PORT || 22 }} script: | # Set deployment directory for production DEPLOY_DIR="/var/www/merchbay_admin" # Create deployment directory if it doesn't exist mkdir -p $DEPLOY_DIR # Load the Docker image cd /tmp/merchbay_admin_deploy docker load < merchbay_admin.tar.gz # Copy docker-compose.yml to deployment directory cp docker-compose.yml $DEPLOY_DIR/ # Navigate to deployment directory cd $DEPLOY_DIR # Update environment file for production cat > .env << EOF APP_ENV=production APP_DEBUG=false APP_URL=https://merchbay.com DB_HOST=${{ secrets.PROD_DB_HOST }} DB_PORT=${{ secrets.PROD_DB_PORT || 3306 }} DB_DATABASE=${{ secrets.PROD_DB_DATABASE }} DB_USERNAME=${{ secrets.PROD_DB_USERNAME }} DB_PASSWORD=${{ secrets.PROD_DB_PASSWORD }} DOMAIN=merchbay.com EOF # Stop existing container (disconnect from Traefik network gracefully) docker compose down || true # Remove old image (optional, keeps only latest) docker image prune -f # Ensure Traefik network exists docker network inspect traefik-public >/dev/null 2>&1 || docker network create traefik-public # Update docker-compose for production export DOMAIN=merchbay.com export APP_URL=https://merchbay.com # Start the application (will auto-connect to Traefik with paid SSL) docker compose up -d # Wait for container to be ready sleep 10 # Run migrations docker compose exec -T app php artisan migrate --force # Clear and cache configuration docker compose exec -T app php artisan config:cache docker compose exec -T app php artisan route:cache docker compose exec -T app php artisan view:cache # Cleanup rm -rf /tmp/merchbay_admin_deploy echo "Production deployment completed successfully!" echo "Application available at: https://merchbay.com" - name: Health Check run: | sleep 10 curl -f https://merchbay.com || exit 1