feat: nem build
Some checks failed
Deploy QR Rapido / test (push) Successful in 27s
Deploy QR Rapido / build-and-push (push) Successful in 1m40s
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Failing after 6s

This commit is contained in:
Ricardo Carneiro 2025-08-05 21:19:40 -03:00
parent afd1b53354
commit 95c8e7901b
2 changed files with 222 additions and 155 deletions

View File

@ -2,53 +2,38 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src WORKDIR /src
# Copy csproj and restore dependencies (better caching) # Copy csproj and restore as distinct layers
COPY ["QRRapidoApp.csproj", "./"] COPY *.csproj ./
RUN dotnet restore "QRRapidoApp.csproj" RUN dotnet restore --runtime linux-arm64
# Copy source code # Copy everything else and build
COPY . . COPY . .
RUN dotnet build "QRRapidoApp.csproj" -c Release --runtime linux-arm64 --no-restore
# Build optimized for production
RUN dotnet build "QRRapidoApp.csproj" -c Release -o /app/build --no-restore
# Publish stage # Publish stage
FROM build AS publish FROM build AS publish
RUN dotnet publish "QRRapidoApp.csproj" -c Release -o /app/publish --no-restore --no-build \ RUN dotnet publish "QRRapidoApp.csproj" -c Release -o /app/publish \
/p:PublishReadyToRun=true \ --runtime linux-arm64 \
/p:PublishSingleFile=false \ --no-restore \
/p:PublishTrimmed=false --no-build \
--self-contained false
# Runtime stage # Final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app WORKDIR /app
# Install dependencies for QR code generation # Install libgdiplus for System.Drawing (se necessário para QR codes)
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y libgdiplus && rm -rf /var/lib/apt/lists/*
libgdiplus \
libc6-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy application # Copy published app
COPY --from=publish /app/publish . COPY --from=publish /app/publish .
# Configure production environment # Expose port
ENV ASPNETCORE_ENVIRONMENT=Production EXPOSE 8080
ENV ASPNETCORE_URLS=http://+:80
ENV DOTNET_EnableDiagnostics=0
# Create non-root user for security # Create non-root user
RUN addgroup --system --gid 1001 qrrapido RUN adduser --disabled-password --gecos '' appuser && chown -R appuser /app
RUN adduser --system --uid 1001 qrrapido USER appuser
# Set ownership # Set entry point
RUN chown -R qrrapido:qrrapido /app
USER qrrapido
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/health || exit 1
EXPOSE 80
ENTRYPOINT ["dotnet", "QRRapidoApp.dll"] ENTRYPOINT ["dotnet", "QRRapidoApp.dll"]

View File

@ -1,120 +1,202 @@
{ name: Deploy QR Rapido
"App": { on:
"Name": "QR Rapido", push:
"BaseUrl": "https://qrrapido.site", branches: [ main, develop ]
"TaglinePT": "Gere QR codes em segundos!", pull_request:
"TaglineES": "¡Genera códigos QR en segundos!", branches: [ main ]
"TaglineEN": "Generate QR codes in seconds!",
"Version": "1.0.0" env:
}, REGISTRY: registry.redecarneir.us
"ConnectionStrings": { IMAGE_NAME: qrrapido
"MongoDB": "mongodb://localhost:27017/QrRapido"
}, jobs:
"Authentication": { test:
"Google": { runs-on: ubuntu-latest
"ClientId": "1080447252222-dqjsu999tvrpb69oj5iapckdh9g8rvha.apps.googleusercontent.com",
"ClientSecret": "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" steps:
}, - uses: actions/checkout@v4
"Microsoft": {
"ClientId": "9bec3835-acdb-4c5a-8668-6b90955c6ad2", - name: Setup .NET
"ClientSecret": "Oe38Q~FsZ3X5ouptAB6oYyX7MXaGUvxXcqT.aaT9" uses: actions/setup-dotnet@v4
} with:
}, dotnet-version: 8.0.x
"Stripe": {
"PublishableKey": "pk_test_51Rs42tBeR5IFYUsBooapyDwQTgh6CFuKbya5R3MVDTrdOUKmgiHQYipU0pgOdG5iKogH77RUYIKBJzbCt5BghUOY00xitV5KiN", - name: Cache dependencies
"SecretKey": "sk_test_51Rs42tBeR5IFYUsBtycRlJJcdwgoMbh8MfQIKIGelBPTQFwDcOn2iCCbw5uG6hnqlpgNAUuFgWRAUUMA8qkABKun00EIx4odDF", uses: actions/cache@v3
"WebhookSecret": "whsec_2e828803ceb48e7865458b0cf332b68535fdff8753d26d69b1c88ea55cb0e482", with:
"PriceId": "prod_SnfQTxwE3i8r5L" path: ~/.nuget/packages
}, key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
"AdSense": { restore-keys: |
"ClientId": "ca-pub-XXXXXXXXXX", ${{ runner.os }}-nuget-
"Enabled": true
}, - name: Restore dependencies
"Performance": { run: dotnet restore
"QRGenerationTimeoutMs": 2000,
"CacheExpirationMinutes": 60, - name: Build
"MaxConcurrentGenerations": 100 run: dotnet build --no-restore --configuration Release
},
"HistoryCleanup": { - name: Test
"GracePeriodDays": 7, run: dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage"
"CleanupIntervalHours": 6
}, - name: Upload coverage
"Premium": { uses: codecov/codecov-action@v3
"FreeQRLimit": 10, with:
"PremiumPrice": 12.90, files: coverage.cobertura.xml
"Features": {
"UnlimitedQR": true, build-and-push:
"DynamicQR": true, needs: test
"NoAds": true, runs-on: ubuntu-latest
"PrioritySupport": true, if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
"AdvancedAnalytics": true,
"SpeedBoost": true steps:
} - name: Checkout
}, uses: actions/checkout@v4
"SEO": {
"KeywordsPT": "qr rapido, gerador qr rapido, qr code rapido, codigo qr rapido, qr gratis rapido", - name: Set up Docker Buildx
"KeywordsES": "qr rapido, generador qr rapido, codigo qr rapido, qr gratis rapido", uses: docker/setup-buildx-action@v3
"KeywordsEN": "fast qr, quick qr generator, rapid qr code, qr code generator"
}, - name: Build and push to registry
"ApplicationName": "QRRapido", run: |
"Environment": "Personal", # Determina a tag baseada na branch
"Serilog": { if [ "${{ github.ref }}" = "refs/heads/main" ]; then
"SeqUrl": "http://localhost:5341", TAG="latest"
"ApiKey": "", else
"MinimumLevel": { TAG="develop"
"Default": "Information", fi
"Override": {
"Microsoft": "Warning", # Build da imagem para ARM64 (servidores Ampere OCI)
"Microsoft.AspNetCore": "Warning", docker buildx build \
"Microsoft.Hosting.Lifetime": "Information", --platform linux/arm64 \
"System": "Warning" --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$TAG \
} --push \
} .
},
"ResourceMonitoring": { echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV
"Enabled": true,
"IntervalSeconds": 30, deploy-staging:
"CpuThresholdPercent": 80, needs: build-and-push
"MemoryThresholdMB": 512, runs-on: ubuntu-latest
"ConsecutiveAlertsBeforeError": 4, if: github.ref == 'refs/heads/develop'
"GcCollectionThreshold": 10
}, steps:
"MongoDbMonitoring": { - name: Deploy to Staging Servers
"Enabled": true, run: |
"IntervalMinutes": 5, # Configura SSH known_hosts
"DatabaseSizeWarningMB": 1024, mkdir -p ~/.ssh
"DatabaseSizeErrorMB": 5120, ssh-keyscan -H 141.148.162.114 >> ~/.ssh/known_hosts
"GrowthRateWarningMBPerHour": 100, ssh-keyscan -H 129.146.116.218 >> ~/.ssh/known_hosts
"IncludeCollectionStats": true,
"CollectionsToMonitor": [ "Users", "QRCodeHistory", "AdFreeSessions" ] # Deploy no Servidor 1
}, ssh ubuntu@141.148.162.114 << 'EOF'
"HealthChecks": { # Para o container atual se existir
"MongoDB": { docker stop qrrapido-staging || true
"TimeoutSeconds": 5, docker rm qrrapido-staging || true
"IncludeDatabaseSize": true,
"TestQuery": true # Remove imagem antiga
}, docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop || true
"Seq": {
"TimeoutSeconds": 3, # Puxa nova imagem
"TestLogMessage": "QRRapido health check test" docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
},
"Resources": { # Executa novo container
"CpuThresholdPercent": 85, docker run -d \
"MemoryThresholdMB": 600, --name qrrapido-staging \
"GcPressureThreshold": 15 --restart unless-stopped \
}, -p 5000:8080 \
"ExternalServices": { -e ASPNETCORE_ENVIRONMENT=Staging \
"TimeoutSeconds": 10, ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
"TestStripeConnection": true, EOF
"TestGoogleAuth": false,
"TestMicrosoftAuth": false # Deploy no Servidor 2
} ssh ubuntu@129.146.116.218 << 'EOF'
}, # Para o container atual se existir
"Logging": { docker stop qrrapido-staging || true
"LogLevel": { docker rm qrrapido-staging || true
"Default": "Information",
"Microsoft.AspNetCore": "Warning" # Remove imagem antiga
} docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop || true
},
"AllowedHosts": "*" # Puxa nova imagem
} docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
# Executa novo container
docker run -d \
--name qrrapido-staging \
--restart unless-stopped \
-p 5000:8080 \
-e ASPNETCORE_ENVIRONMENT=Staging \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop
EOF
deploy-production:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- name: Deploy to Production Servers
run: |
# Configura SSH known_hosts
mkdir -p ~/.ssh
ssh-keyscan -H 141.148.162.114 >> ~/.ssh/known_hosts
ssh-keyscan -H 129.146.116.218 >> ~/.ssh/known_hosts
# Deploy no Servidor 1 (com NGINX)
ssh ubuntu@141.148.162.114 << 'EOF'
# Para o container atual se existir
docker stop qrrapido-prod || true
docker rm qrrapido-prod || true
# Remove imagem antiga
docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest || true
# Puxa nova imagem
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# Executa novo container
docker run -d \
--name qrrapido-prod \
--restart unless-stopped \
-p 5001:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e ASPNETCORE_URLS=http://+:8080 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# Recarrega NGINX para garantir que está apontando para o novo container
sudo nginx -t && sudo systemctl reload nginx
EOF
# Deploy no Servidor 2
ssh ubuntu@129.146.116.218 << 'EOF'
# Para o container atual se existir
docker stop qrrapido-prod || true
docker rm qrrapido-prod || true
# Remove imagem antiga
docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest || true
# Puxa nova imagem
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# Executa novo container
docker run -d \
--name qrrapido-prod \
--restart unless-stopped \
-p 5001:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e ASPNETCORE_URLS=http://+:8080 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
EOF
- name: Health Check
run: |
# Aguarda um pouco para os containers subirem
sleep 30
# Verifica se os serviços estão respondendo
echo "Verificando Servidor 1..."
ssh ubuntu@141.148.162.114 'curl -f http://localhost:5001/health || echo "Servidor 1 pode não estar respondendo"'
echo "Verificando Servidor 2..."
ssh ubuntu@129.146.116.218 'curl -f http://localhost:5001/health || echo "Servidor 2 pode não estar respondendo"'