From 1996e69e80676ad1709e7f9690a831380ca531d6 Mon Sep 17 00:00:00 2001 From: mfnefd Date: Mon, 9 Dec 2024 04:16:30 +0400 Subject: [PATCH] =?UTF-8?q?add:=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20=D0=B4=D0=BE=D0=BA=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 25 +++++ .env | 5 + .vscode/launch.json | 39 +++++++ .vscode/tasks.json | 101 ++++++++++++++++++ back/Controllers/Dockerfile | 24 +++++ .../Extensions/DatabaseSetupExt.cs | 1 + docker-compose.debug.yml | 41 +++++++ docker-compose.yml | 35 ++++++ front/.dockerignore | 24 +++++ front/Dockerfile | 18 ++++ front/components.d.ts | 8 -- front/nginx.conf | 55 ++++++++++ front/src/components/pages/SignUp.vue | 2 +- .../support/ChangeRecordManager.vue | 2 +- front/src/core/api/http-client.ts | 2 +- front/src/router.ts | 2 +- 16 files changed, 372 insertions(+), 12 deletions(-) create mode 100644 .dockerignore create mode 100644 .env create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 back/Controllers/Dockerfile create mode 100644 docker-compose.debug.yml create mode 100644 docker-compose.yml create mode 100644 front/.dockerignore create mode 100644 front/Dockerfile create mode 100644 front/nginx.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3dbbcf3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/.env b/.env new file mode 100644 index 0000000..ffcde48 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +POSTGRES_DB="dombudg" +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="postgres" + +CONNECTION_STRING="Host=database:5432;Database=${POSTGRES_DB};Username=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};" \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6e3c048 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,39 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/back/Controllers/bin/Debug/net8.0/Controllers.dll", + "args": [], + "cwd": "${workspaceFolder}/back/Controllers", + "stopAtEntry": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + }, + { + "name": "Docker .NET Launch", + "type": "docker", + "request": "launch", + "preLaunchTask": "docker-run: debug", + "netCore": { + "appProject": "${workspaceFolder}/back/Controllers/Controllers.csproj" + } + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ac38365 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,101 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/back/Api.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/back/Api.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/back/Api.sln" + ], + "problemMatcher": "$msCompile" + }, + { + "type": "docker-build", + "label": "docker-build: debug", + "dependsOn": [ + "build" + ], + "dockerBuild": { + "tag": "dombudg:dev", + "target": "base", + "dockerfile": "${workspaceFolder}/back/Controllers/Dockerfile", + "context": "${workspaceFolder}", + "pull": true + }, + "netCore": { + "appProject": "${workspaceFolder}/back/Controllers/Controllers.csproj" + } + }, + { + "type": "docker-build", + "label": "docker-build: release", + "dependsOn": [ + "build" + ], + "dockerBuild": { + "tag": "dombudg:latest", + "dockerfile": "${workspaceFolder}/back/Controllers/Dockerfile", + "context": "${workspaceFolder}", + "platform": { + "os": "linux", + "architecture": "amd64" + }, + "pull": true + }, + "netCore": { + "appProject": "${workspaceFolder}/back/Controllers/Controllers.csproj" + } + }, + { + "type": "docker-run", + "label": "docker-run: debug", + "dependsOn": [ + "docker-build: debug" + ], + "dockerRun": {}, + "netCore": { + "appProject": "${workspaceFolder}/back/Controllers/Controllers.csproj", + "enableDebugging": true + } + }, + { + "type": "docker-run", + "label": "docker-run: release", + "dependsOn": [ + "docker-build: release" + ], + "dockerRun": {}, + "netCore": { + "appProject": "${workspaceFolder}/back/Controllers/Controllers.csproj" + } + } + ] +} \ No newline at end of file diff --git a/back/Controllers/Dockerfile b/back/Controllers/Dockerfile new file mode 100644 index 0000000..29bf5f0 --- /dev/null +++ b/back/Controllers/Dockerfile @@ -0,0 +1,24 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +WORKDIR /app +EXPOSE 5125 + +ENV ASPNETCORE_URLS=http://+:5125 + +USER app +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG configuration=Release +WORKDIR /src +COPY ["back/Controllers/Controllers.csproj", "back/Controllers/"] +RUN dotnet restore "back/Controllers/Controllers.csproj" +COPY . . +WORKDIR "/src/back/Controllers" +RUN dotnet build "Controllers.csproj" -c $configuration -o /app/build + +FROM build AS publish +ARG configuration=Release +RUN dotnet publish "Controllers.csproj" -c $configuration -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Controllers.dll"] diff --git a/back/Controllers/Extensions/DatabaseSetupExt.cs b/back/Controllers/Extensions/DatabaseSetupExt.cs index 0f72055..20592af 100644 --- a/back/Controllers/Extensions/DatabaseSetupExt.cs +++ b/back/Controllers/Extensions/DatabaseSetupExt.cs @@ -9,6 +9,7 @@ public static class DatabaseSetupExtension { var connectionString = config.GetConnectionString("DefaultConnection") ?? throw new ArgumentException("Нет строки подключения"); + Console.WriteLine("Connection string: " + connectionString); services.AddDbContext(options => options.UseNpgsql(connectionString)); services.AddSingleton, DbContextFactory>(); } diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml new file mode 100644 index 0000000..02d8292 --- /dev/null +++ b/docker-compose.debug.yml @@ -0,0 +1,41 @@ +# Please refer https://aka.ms/HTTPSinContainer on how to setup an https developer certificate for your ASP.NET Core service. +services: + api: + image: api + build: + context: . + dockerfile: back/Controllers/Dockerfile + args: + - configuration=Debug + ports: + - 5125:5125 + environment: + - ConnectionStrings__DefaultConnection=${CONNECTION_STRING} + - ASPNETCORE_ENVIRONMENT=Development + volumes: + - ~/.vsdbg:/remote_debugger:rw + depends_on: + - database + dombudg: + image: dombudg + build: + context: front + dockerfile: ./Dockerfile + environment: + - VITE_API_URL=http://api:5125 + ports: + - 80:80 + depends_on: + - api + database: + image: postgres:14 + environment: + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: + driver: local diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..284a658 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +services: + api: + image: api + build: + context: . + dockerfile: back/Controllers/Dockerfile + ports: + - 5125:5125 + environment: + - ConnectionStrings__DefaultConnection=${CONNECTION_STRING} + depends_on: + - database + dombudg: + image: dombudg + build: + context: front + dockerfile: ./Dockerfile + environment: + - VITE_API_URL=http://api:5125 + ports: + - 80:80 + depends_on: + - api + database: + image: postgres:14 + environment: + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: + driver: local \ No newline at end of file diff --git a/front/.dockerignore b/front/.dockerignore new file mode 100644 index 0000000..809ba83 --- /dev/null +++ b/front/.dockerignore @@ -0,0 +1,24 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/front/Dockerfile b/front/Dockerfile new file mode 100644 index 0000000..89d6bcc --- /dev/null +++ b/front/Dockerfile @@ -0,0 +1,18 @@ +FROM node as vite-app + +ARG VITE_API_URL + +WORKDIR /app/client +COPY . . + +RUN ["npm", "i"] +RUN ["npm", "run", "build"] + +FROM nginx:alpine + +COPY nginx.conf /etc/nginx + +RUN rm -rf /usr/share/nginx/html/* +COPY --from=vite-app /app/client/dist /usr/share/nginx/html + +ENTRYPOINT ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/front/components.d.ts b/front/components.d.ts index ce64ae3..55d7595 100644 --- a/front/components.d.ts +++ b/front/components.d.ts @@ -8,9 +8,7 @@ export {} declare module 'vue' { export interface GlobalComponents { AButton: typeof import('ant-design-vue/es')['Button'] - ACol: typeof import('ant-design-vue/es')['Col'] ADatePicker: typeof import('ant-design-vue/es')['DatePicker'] - AFlex: typeof import('ant-design-vue/es')['Flex'] AForm: typeof import('ant-design-vue/es')['Form'] AFormItem: typeof import('ant-design-vue/es')['FormItem'] AInput: typeof import('ant-design-vue/es')['Input'] @@ -19,23 +17,17 @@ declare module 'vue' { ALayout: typeof import('ant-design-vue/es')['Layout'] ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] - AMenu: typeof import('ant-design-vue/es')['Menu'] - AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] APopconfirm: typeof import('ant-design-vue/es')['Popconfirm'] - ARow: typeof import('ant-design-vue/es')['Row'] ASelect: typeof import('ant-design-vue/es')['Select'] ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] ASpace: typeof import('ant-design-vue/es')['Space'] ASpin: typeof import('ant-design-vue/es')['Spin'] ATable: typeof import('ant-design-vue/es')['Table'] - ATypographyText: typeof import('ant-design-vue/es')['TypographyText'] ChangeRecordManager: typeof import('./src/components/support/ChangeRecordManager.vue')['default'] - ChangeRecordMenu: typeof import('./src/components/support/ChangeRecordMenu.vue')['default'] Groups: typeof import('./src/components/pages/Groups.vue')['default'] Header: typeof import('./src/components/main/Header.vue')['default'] Home: typeof import('./src/components/pages/Home.vue')['default'] Login: typeof import('./src/components/pages/Login.vue')['default'] - Manager: typeof import('./src/components/support/Manager.vue')['default'] PlanManager: typeof import('./src/components/support/PlanManager.vue')['default'] Plans: typeof import('./src/components/pages/Plans.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/front/nginx.conf b/front/nginx.conf new file mode 100644 index 0000000..e24cefe --- /dev/null +++ b/front/nginx.conf @@ -0,0 +1,55 @@ +# Запускать в качестве менее привилегированного пользователя по соображениям безопасности.. +user nginx; + +# Значение auto устанавливает число максимально доступных ядер CPU, +# чтобы обеспечить лучшую производительность. +worker_processes auto; + +events { worker_connections 1024; } + +http { + server { + # Hide nginx version information. + server_tokens off; + + listen 80; + root /usr/share/nginx/html; + include /etc/nginx/mime.types; + + location /api/ { + proxy_pass http://api:5125/api/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Prefix /test; + } + + location / { + try_files $uri $uri/ /index.html; + } + + gzip on; + gzip_vary on; + gzip_http_version 1.0; + gzip_comp_level 5; + gzip_types + application/atom+xml + application/javascript + application/json + application/rss+xml + application/vnd.ms-fontobject + application/x-font-ttf + application/x-web-app-manifest+json + application/xhtml+xml + application/xml + font/opentype + image/svg+xml + image/x-icon + text/css + text/plain + text/x-component; + gzip_proxied no-cache no-store private expired auth; + gzip_min_length 256; + gunzip on; + } +} \ No newline at end of file diff --git a/front/src/components/pages/SignUp.vue b/front/src/components/pages/SignUp.vue index 4e8ecc6..dbc03bc 100644 --- a/front/src/components/pages/SignUp.vue +++ b/front/src/components/pages/SignUp.vue @@ -60,7 +60,7 @@ const formState = reactive({ password: '', balance: 0 }); -const authService = inject(typeof(AuthService)) as AuthService; +const authService = inject(AuthService.name) as AuthService; // Логика формы const onFinish = async (values: any) => { diff --git a/front/src/components/support/ChangeRecordManager.vue b/front/src/components/support/ChangeRecordManager.vue index fd7f4f7..c0431f3 100644 --- a/front/src/components/support/ChangeRecordManager.vue +++ b/front/src/components/support/ChangeRecordManager.vue @@ -49,7 +49,7 @@