diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ab0818f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,63 @@ +# Build artifacts +**/bin/ +**/obj/ +**/out/ +**/publish/ + +# IDE and editor files +**/.vs/ +**/.vscode/ +**/.idea/ +**/.DS_Store +**/*.user +**/*.suo +**/*.userosscache +**/*.sln.docstates +**/*.userprefs +**/.fleet/ + +# Database files +**/*.dbmdl +**/*.jfm +**/*.mdf +**/*.ldf + +# Temp and swap files +**/*.swp +**/*.swo +**/*~ +**/*.tmp +**/*.temp + +# Logs +**/*.log + +# Node modules (if any frontend dependencies) +**/node_modules/ + +# Git files +.git/ +.gitignore +.gitattributes +.git-crypt/ + +# Documentation +README.md +**/*.md +LICENSE + +# Docker files +docker-compose.yml +docker-compose.*.yml +**/Dockerfile +**/.dockerignore + +# Development databases +docker/ + +# Test results +**/TestResults/ +**/*.trx + +# macOS +.DS_Store \ No newline at end of file diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..3d03aab --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,53 @@ +name: Build Docker Images + +on: + push: + branches: + - main + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: https://github.com/actions/checkout@v4 + + - name: Set up Docker Buildx + uses: https://github.com/docker/setup-buildx-action@v3 + + - name: Log in to Gitea Container Registry + run: | + echo "${{ secrets.REGISTRY_TOKEN }}" | docker login code.bim-it.pl -u "${{ secrets.REGISTRY_USER }}" --password-stdin + + - name: Build and push API image (build artifacts) + run: | + docker buildx build \ + --platform linux/amd64 \ + -f BimAI.API/Dockerfile \ + -t code.bim-it.pl/bimai/bimai-api:build-${{ github.run_id }} \ + --push \ + . + + - name: Build and push UI image (build artifacts) + run: | + docker buildx build \ + --platform linux/amd64 \ + -f BimAI.UI.Web/Dockerfile \ + -t code.bim-it.pl/bimai/bimai-ui:build-${{ github.run_id }} \ + --push \ + . + + - name: Output build info + run: | + echo "## 🏗️ Docker Images Built" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Build ID:** ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Images pushed with tag: \`build-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Use **Release** workflow to tokenize and tag as \`:prod\`" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 1f61a82..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Build Bimix - -on: - push: - branches: - - main - -jobs: - build: - name: Build WebAPI and WebUI - runs-on: ubuntu-latest - - env: - DOTNET_VERSION: '8.0.x' - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - - name: Restore WebAPI - run: dotnet restore Bimix.API/Bimix.API.csproj - - - name: Restore WebUI - run: dotnet restore Bimix.UI.Web/Bimix.UI.Web.csproj - - - name: Build WebAPI - run: dotnet build Bimix.API/Bimix.API.csproj --configuration Release --no-restore - - - name: Build WebUI - run: dotnet build Bimix.UI.Web/Bimix.UI.Web.csproj --configuration Release --no-restore - - - name: Publish WebAPI - run: | - dotnet publish Bimix.API/Bimix.API.csproj \ - --configuration Release \ - --output ./publish/Bimix-WebAPI - - - name: Publish Web (Blazor Server) - run: | - dotnet publish Bimix.UI.Web/Bimix.UI.Web.csproj \ - --configuration Release \ - --output ./publish/Bimix-Web - - - name: Upload publish artifact - uses: actions/upload-artifact@v4 - with: - name: bimix-artifacts - path: ./publish diff --git a/BimAI.API/Dockerfile b/BimAI.API/Dockerfile new file mode 100644 index 0000000..2733730 --- /dev/null +++ b/BimAI.API/Dockerfile @@ -0,0 +1,45 @@ +# Stage 1: Build +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src + +# Copy solution and all project files for restore +COPY BimAI.sln ./ +COPY BimAI.API/BimAI.API.csproj BimAI.API/ +COPY BimAI.Domain/BimAI.Domain.csproj BimAI.Domain/ +COPY BimAI.Application/BimAI.Application.csproj BimAI.Application/ +COPY BimAI.Infrastructure/BimAI.Infrastructure.csproj BimAI.Infrastructure/ + +# Restore dependencies +RUN dotnet restore BimAI.API/BimAI.API.csproj + +# Copy all source code +COPY . . + +# Build and publish +WORKDIR /src/BimAI.API +RUN dotnet publish -c Release -o /app/publish --no-restore + +# Stage 2: Runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime +WORKDIR /app + +# Set timezone +ENV TZ=Europe/Warsaw +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Copy published files +COPY --from=build /app/publish . + +# Set environment variables +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://0.0.0.0:7142 + +# Expose port +EXPOSE 7142 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:7142/health || exit 1 + +# Run the application +ENTRYPOINT ["dotnet", "BimAI.API.dll"] \ No newline at end of file diff --git a/BimAI.API/Program.cs b/BimAI.API/Program.cs index 1c72fed..a5ad58a 100644 --- a/BimAI.API/Program.cs +++ b/BimAI.API/Program.cs @@ -100,13 +100,19 @@ app.UseAuthorization(); app.UseAuthorization(); app.MapControllers(); +app.MapGet("/health", () => Results.Ok(new { status = "OK", timestamp = DateTime.UtcNow })) + .AllowAnonymous(); + RecurringJob.AddOrUpdate( "product-sync", job => job.ExecuteAsync(), Cron.Daily(2, 0), // Every day at 2:00 AM new RecurringJobOptions { - TimeZone = TimeZoneInfo.Local + TimeZone = TimeZoneInfo.Local, + MisfireHandling = app.Environment.IsDevelopment() + ? MisfireHandlingMode.Relaxed + : MisfireHandlingMode.Strict }); app.Run(); \ No newline at end of file diff --git a/BimAI.API/appsettings.Development.json b/BimAI.API/appsettings.Development.json index 4030be7..fedb42c 100644 Binary files a/BimAI.API/appsettings.Development.json and b/BimAI.API/appsettings.Development.json differ diff --git a/BimAI.API/appsettings.Production.json b/BimAI.API/appsettings.Production.json new file mode 100644 index 0000000..25a1fd0 --- /dev/null +++ b/BimAI.API/appsettings.Production.json @@ -0,0 +1,38 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "DefaultConnection": "#{db-connection-string}#", + "HangfireConnection": "#{hangfire-connection-string}#" + }, + "E5_CRM": { + "ApiKey": "#{e5-crm-api-key}#" + }, + "GoogleAuth": { + "ClientId": "#{google-auth-client-id}#" + }, + "JwtSettings": { + "SecretKey": "#{jwt-secret-key}#", + "Issuer": "#{jwt-issuer}#", + "Audience": "#{jwt-audience}#", + "ExpiryDays": 7 + }, + "Hangfire": { + "ServerName": "#{hangfire-server-name}#", + "WorkerCount": 5, + "DashboardPath": "/hangfire" + }, + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://0.0.0.0:7142" + } + } + } +} \ No newline at end of file diff --git a/BimAI.API/appsettings.json b/BimAI.API/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/BimAI.API/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/BimAI.UI.Web/Dockerfile b/BimAI.UI.Web/Dockerfile new file mode 100644 index 0000000..24a0ca4 --- /dev/null +++ b/BimAI.UI.Web/Dockerfile @@ -0,0 +1,45 @@ +# Stage 1: Build +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src + +# Copy solution and all project files for restore +COPY BimAI.sln ./ +COPY BimAI.UI.Web/BimAI.UI.Web.csproj BimAI.UI.Web/ +COPY BimAI.UI.Shared/BimAI.UI.Shared.csproj BimAI.UI.Shared/ +COPY BimAI.Domain/BimAI.Domain.csproj BimAI.Domain/ +COPY BimAI.Application/BimAI.Application.csproj BimAI.Application/ + +# Restore dependencies +RUN dotnet restore BimAI.UI.Web/BimAI.UI.Web.csproj + +# Copy all source code +COPY . . + +# Build and publish +WORKDIR /src/BimAI.UI.Web +RUN dotnet publish -c Release -o /app/publish --no-restore + +# Stage 2: Runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime +WORKDIR /app + +# Set timezone +ENV TZ=Europe/Warsaw +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Copy published files +COPY --from=build /app/publish . + +# Set environment variables +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://0.0.0.0:7143 + +# Expose port +EXPOSE 7143 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:7143/health || exit 1 + +# Run the application +ENTRYPOINT ["dotnet", "BimAI.UI.Web.dll"] \ No newline at end of file diff --git a/BimAI.UI.Web/Program.cs b/BimAI.UI.Web/Program.cs index 8174e38..75501c4 100644 --- a/BimAI.UI.Web/Program.cs +++ b/BimAI.UI.Web/Program.cs @@ -30,6 +30,8 @@ app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); +app.MapGet("/health", () => Results.Ok(new { status = "OK", timestamp = DateTime.UtcNow })); + app.MapRazorComponents() .AddInteractiveServerRenderMode() .AddAdditionalAssemblies(typeof(MainLayout).Assembly); diff --git a/BimAI.UI.Web/appsettings.Production.json b/BimAI.UI.Web/appsettings.Production.json new file mode 100644 index 0000000..b2c34ee --- /dev/null +++ b/BimAI.UI.Web/appsettings.Production.json @@ -0,0 +1,22 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ApiSettings": { + "BaseUrl": "#{api-base-url}#" + }, + "GoogleAuth": { + "ClientId": "#{google-auth-client-id}#" + }, + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://0.0.0.0:7143" + } + } + } +} \ No newline at end of file diff --git a/BimAI.UI.Web/appsettings.json b/BimAI.UI.Web/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/BimAI.UI.Web/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -}