feat: Добавлена инфраструктура k8s и Docker

Добавлены Dockerfile, .dockerignore и Helm чарт для web-app.
Изменены CORS и обработка ошибок логина.
This commit is contained in:
Андрей Дувакин 2025-06-06 18:53:49 +05:00
parent 5098b05003
commit 333a471f9d
11 changed files with 126 additions and 1 deletions

View File

@ -23,7 +23,7 @@ def start_app():
api_app.add_middleware(
CORSMiddleware,
allow_origins=['https://api.visus.numerum.team', 'http://localhost:5173'],
allow_origins=['https://api.visus.numerum.team', 'https://visus.numerum.team', 'http://localhost:5173'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],

6
web-app/.dockerignore Normal file
View File

@ -0,0 +1,6 @@
node_modules
npm-debug.log
build
.dockerignore
.git
k8s

25
web-app/Dockerfile Normal file
View File

@ -0,0 +1,25 @@
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
ARG VITE_BASE_URL
ENV VITE_BASE_URL=https://api.visus.numerum.team/api/v1/
RUN npm run build
FROM node:20-alpine
WORKDIR /app
RUN npm install -g serve
COPY --from=builder /dist /app
EXPOSE 3000
CMD ["serve", "-s", ".", "-l", "3000"]

View File

@ -0,0 +1,5 @@
apiVersion: v2
name: visus-web-app
description: Visus WEB project
version: 0.1.0
appVersion: "1.0"

View File

@ -0,0 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
resources:
{{- toYaml .Values.resources | nindent 12 }}

View File

@ -0,0 +1,23 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: visus-api-ingress
annotations:
cert-manager.io/cluster-issuer: lets-encrypt
spec:
tls:
- hosts:
- {{ .Values.ingress.domain }}
secretName: {{ .Values.ingress.secretTLSName }}
ingressClassName: public
rules:
- host: {{ .Values.ingress.domain }}
http:
paths:
- path: {{ .Values.ingress.path }}
pathType: {{ .Values.ingress.pathType }}
backend:
service:
name: {{ .Chart.Name }}-service
port:
number: {{ .Values.service.port }}

View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: visus-api-secret
type: Opaque
data:
SECRET_KEY:
DATABASE_URL:

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}-service
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.port }}
selector:
app: {{ .Chart.Name }}

View File

@ -0,0 +1,23 @@
replicaCount: 1
image:
repository: andreiduvakin/visus-web
tag: latest
pullPolicy: Always
service:
type: ClusterIP
port: 3000
resources:
limits:
memory: 512Mi
cpu: 500m
ingress:
secretTLSName: visus-web-tls-secret
domain: visus.numerum.team
path: /
pathType: Prefix

View File

@ -7,6 +7,7 @@ const {Title} = Typography;
const LoginPage = () => {
const {error} = useSelector((state) => state.auth);
const {onFinish, isLoading} = useLoginPage();
const {containerStyle, formContainerStyle, titleStyle, errorStyle, labels} = useLoginPageUI();

View File

@ -21,6 +21,7 @@ const useLoginPage = () => {
await dispatch(checkAuth()).unwrap();
} catch (error) {
const errorMessage = error?.data?.detail || "Не удалось войти";
console.error(error);
dispatch(setError(errorMessage));
notification.error({
message: "Ошибка при входе",