This commit is contained in:
parent
6630045f67
commit
8d67d17e82
121
.woodpecker.yaml
Normal file
121
.woodpecker.yaml
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
steps:
|
||||||
|
build-frontend:
|
||||||
|
name: Build & Push Frontend
|
||||||
|
image: woodpeckerci/plugin-kaniko
|
||||||
|
when:
|
||||||
|
branch: [ master, develop ]
|
||||||
|
event: [ push, pull_request, tag ]
|
||||||
|
path:
|
||||||
|
include: [ frontend/** ]
|
||||||
|
settings:
|
||||||
|
registry: harbor.dvirlabs.com
|
||||||
|
repo: my-apps/${CI_REPO_NAME}-frontend
|
||||||
|
dockerfile: frontend/Dockerfile
|
||||||
|
context: frontend
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
- ${CI_COMMIT_TAG:-${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}}
|
||||||
|
username:
|
||||||
|
from_secret: DOCKER_USERNAME
|
||||||
|
password:
|
||||||
|
from_secret: DOCKER_PASSWORD
|
||||||
|
|
||||||
|
build-backend:
|
||||||
|
name: Build & Push Backend
|
||||||
|
image: woodpeckerci/plugin-kaniko
|
||||||
|
when:
|
||||||
|
branch: [ master, develop ]
|
||||||
|
event: [ push, pull_request, tag ]
|
||||||
|
path:
|
||||||
|
include: [ backend/** ]
|
||||||
|
settings:
|
||||||
|
registry: harbor-core.dev-tools.svc.cluster.local
|
||||||
|
repo: my-apps/${CI_REPO_NAME}-backend
|
||||||
|
dockerfile: backend/Dockerfile
|
||||||
|
context: backend
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
- ${CI_COMMIT_TAG:-${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}}
|
||||||
|
username:
|
||||||
|
from_secret: DOCKER_USERNAME
|
||||||
|
password:
|
||||||
|
from_secret: DOCKER_PASSWORD
|
||||||
|
|
||||||
|
update-values-frontend:
|
||||||
|
name: Update frontend tag in values.yaml
|
||||||
|
image: alpine:3.19
|
||||||
|
when:
|
||||||
|
branch: [ master, develop ]
|
||||||
|
event: [ push ]
|
||||||
|
path:
|
||||||
|
include: [ frontend/** ]
|
||||||
|
environment:
|
||||||
|
GIT_USERNAME:
|
||||||
|
from_secret: GIT_USERNAME
|
||||||
|
GIT_TOKEN:
|
||||||
|
from_secret: GIT_TOKEN
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache git yq
|
||||||
|
- git config --global user.name "woodpecker-bot"
|
||||||
|
- git config --global user.email "ci@dvirlabs.com"
|
||||||
|
- git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/my-apps.git"
|
||||||
|
- cd my-apps
|
||||||
|
- |
|
||||||
|
TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}"
|
||||||
|
echo "💡 Setting frontend tag to: $TAG"
|
||||||
|
yq -i ".frontend.image.tag = \"$TAG\"" manifests/${CI_REPO_NAME}/values.yaml
|
||||||
|
git add manifests/${CI_REPO_NAME}/values.yaml
|
||||||
|
git commit -m "frontend: update tag to $TAG" || echo "No changes"
|
||||||
|
git push origin HEAD
|
||||||
|
|
||||||
|
update-values-backend:
|
||||||
|
name: Update backend tag in values.yaml
|
||||||
|
image: alpine:3.19
|
||||||
|
when:
|
||||||
|
branch: [ master, develop ]
|
||||||
|
event: [ push ]
|
||||||
|
path:
|
||||||
|
include: [ backend/** ]
|
||||||
|
environment:
|
||||||
|
GIT_USERNAME:
|
||||||
|
from_secret: GIT_USERNAME
|
||||||
|
GIT_TOKEN:
|
||||||
|
from_secret: GIT_TOKEN
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache git yq
|
||||||
|
- git config --global user.name "woodpecker-bot"
|
||||||
|
- git config --global user.email "ci@dvirlabs.com"
|
||||||
|
- |
|
||||||
|
if [ ! -d "my-apps" ]; then
|
||||||
|
git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/my-apps.git"
|
||||||
|
fi
|
||||||
|
- cd my-apps
|
||||||
|
- |
|
||||||
|
TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}"
|
||||||
|
echo "💡 Setting backend tag to: $TAG"
|
||||||
|
yq -i ".backend.image.tag = \"$TAG\"" manifests/${CI_REPO_NAME}/values.yaml
|
||||||
|
git add manifests/${CI_REPO_NAME}/values.yaml
|
||||||
|
git commit -m "backend: update tag to $TAG" || echo "No changes"
|
||||||
|
git push origin HEAD
|
||||||
|
|
||||||
|
|
||||||
|
trigger-gitops-via-push:
|
||||||
|
when:
|
||||||
|
branch: [ master, develop ]
|
||||||
|
event: [ push ]
|
||||||
|
name: Trigger apps-gitops via Git push
|
||||||
|
image: alpine/git
|
||||||
|
environment:
|
||||||
|
GIT_USERNAME:
|
||||||
|
from_secret: GIT_USERNAME
|
||||||
|
GIT_TOKEN:
|
||||||
|
from_secret: GIT_TOKEN
|
||||||
|
commands: |
|
||||||
|
git config --global user.name "woodpecker-bot"
|
||||||
|
git config --global user.email "ci@dvirlabs.com"
|
||||||
|
git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/apps-gitops.git"
|
||||||
|
cd apps-gitops
|
||||||
|
echo "# trigger at $(date) by $${CI_REPO_NAME}" >> .trigger
|
||||||
|
git add .trigger
|
||||||
|
git commit -m "ci: trigger apps-gitops build" || echo "no changes"
|
||||||
|
git push origin HEAD
|
||||||
26
backend/.dockerignore
Normal file
26
backend/.dockerignore
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.Python
|
||||||
|
*.so
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env/
|
||||||
|
.pytest_cache
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
uploads/
|
||||||
|
migrations/
|
||||||
32
backend/Dockerfile
Normal file
32
backend/Dockerfile
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Use Python 3.11 slim image as base
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
postgresql-client \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy requirements file
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Create uploads directory for product images
|
||||||
|
RUN mkdir -p /app/uploads/products
|
||||||
|
|
||||||
|
# Expose port 8000
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
Binary file not shown.
Binary file not shown.
13
brand-master-chart/Chart.yaml
Normal file
13
brand-master-chart/Chart.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: brand-master
|
||||||
|
description: A Helm chart for Brand Master - E-commerce Fashion & Shoe Store
|
||||||
|
type: application
|
||||||
|
version: 1.0.0
|
||||||
|
appVersion: "1.0.0"
|
||||||
|
keywords:
|
||||||
|
- brand-master
|
||||||
|
- ecommerce
|
||||||
|
- fashion
|
||||||
|
- shoes
|
||||||
|
maintainers:
|
||||||
|
- name: dvir
|
||||||
158
brand-master-chart/README.md
Normal file
158
brand-master-chart/README.md
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
# Brand Master Helm Chart
|
||||||
|
|
||||||
|
This Helm chart deploys the Brand Master e-commerce application on Kubernetes.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
- **Frontend**: React-based UI served by Nginx
|
||||||
|
- **Backend**: FastAPI application
|
||||||
|
- **Database**: PostgreSQL 16
|
||||||
|
- **Storage**: 15GB PVC for product images
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Kubernetes 1.19+
|
||||||
|
- Helm 3.0+
|
||||||
|
- cert-manager (for TLS certificates)
|
||||||
|
- Storage class configured (nfs-client by default)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Update values.yaml
|
||||||
|
|
||||||
|
Edit `values.yaml` and configure:
|
||||||
|
|
||||||
|
- Image repositories (if using private registry)
|
||||||
|
- Domain names for ingress
|
||||||
|
- JWT secret key (IMPORTANT!)
|
||||||
|
- Database credentials
|
||||||
|
- Storage class name
|
||||||
|
|
||||||
|
### 2. Install the chart
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install in the my-apps namespace
|
||||||
|
helm install brand-master ./brand-master-chart -n my-apps --create-namespace
|
||||||
|
|
||||||
|
# Or with custom values
|
||||||
|
helm install brand-master ./brand-master-chart -n my-apps \
|
||||||
|
--set backend.jwtSecretKey=your-super-secret-key \
|
||||||
|
--set postgres.password=secure-password
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Upgrade the chart
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm upgrade brand-master ./brand-master-chart -n my-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Uninstall
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm uninstall brand-master -n my-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Key Configuration Options
|
||||||
|
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `backend.image.repository` | Backend Docker image | `harbor.dvirlabs.com/my-apps/brand-master-backend` |
|
||||||
|
| `backend.image.tag` | Backend image tag | `latest` |
|
||||||
|
| `backend.jwtSecretKey` | JWT secret for authentication | `your-secret-key-change-this-in-production` |
|
||||||
|
| `backend.persistence.enabled` | Enable persistent storage for images | `true` |
|
||||||
|
| `backend.persistence.size` | Size of uploads PVC | `15Gi` |
|
||||||
|
| `frontend.image.repository` | Frontend Docker image | `harbor.dvirlabs.com/my-apps/brand-master-frontend` |
|
||||||
|
| `frontend.image.tag` | Frontend image tag | `latest` |
|
||||||
|
| `postgres.user` | PostgreSQL username | `brand_master_user` |
|
||||||
|
| `postgres.password` | PostgreSQL password | `brand_master_password` |
|
||||||
|
| `postgres.database` | PostgreSQL database name | `brand_master_db` |
|
||||||
|
| `postgres.persistence.size` | Size of database PVC | `10Gi` |
|
||||||
|
|
||||||
|
## Building Docker Images
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
docker build -t harbor.dvirlabs.com/my-apps/brand-master-backend:latest .
|
||||||
|
docker push harbor.dvirlabs.com/my-apps/brand-master-backend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
docker build -t harbor.dvirlabs.com/my-apps/brand-master-frontend:latest \
|
||||||
|
--build-arg VITE_API_URL=https://api-brand-master.dvirlabs.com .
|
||||||
|
docker push harbor.dvirlabs.com/my-apps/brand-master-frontend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Storage
|
||||||
|
|
||||||
|
The chart creates two PVCs:
|
||||||
|
|
||||||
|
1. **Database PVC**: 10GB for PostgreSQL data
|
||||||
|
2. **Uploads PVC**: 15GB for product images at `/app/uploads`
|
||||||
|
|
||||||
|
Both use the `nfs-client` storage class by default. Update this in `values.yaml` if needed.
|
||||||
|
|
||||||
|
## Ingress
|
||||||
|
|
||||||
|
The chart creates two ingress resources:
|
||||||
|
|
||||||
|
- **Frontend**: `brand-master.dvirlabs.com`
|
||||||
|
- **Backend API**: `api-brand-master.dvirlabs.com`
|
||||||
|
|
||||||
|
TLS is enabled by default using Let's Encrypt via cert-manager.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check pod status
|
||||||
|
```bash
|
||||||
|
kubectl get pods -n my-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
### View logs
|
||||||
|
```bash
|
||||||
|
# Backend logs
|
||||||
|
kubectl logs -n my-apps -l app.kubernetes.io/component=backend
|
||||||
|
|
||||||
|
# Frontend logs
|
||||||
|
kubectl logs -n my-apps -l app.kubernetes.io/component=frontend
|
||||||
|
|
||||||
|
# Database logs
|
||||||
|
kubectl logs -n my-apps -l app.kubernetes.io/component=database
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access services locally
|
||||||
|
```bash
|
||||||
|
# Frontend
|
||||||
|
kubectl port-forward -n my-apps svc/brand-master-frontend 8080:80
|
||||||
|
|
||||||
|
# Backend
|
||||||
|
kubectl port-forward -n my-apps svc/brand-master-backend 8000:8000
|
||||||
|
|
||||||
|
# Database
|
||||||
|
kubectl port-forward -n my-apps svc/brand-master-db 5432:5432
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check PVC status
|
||||||
|
```bash
|
||||||
|
kubectl get pvc -n my-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
1. **Change the JWT secret** in production
|
||||||
|
2. **Update database credentials**
|
||||||
|
3. **Use strong passwords**
|
||||||
|
4. **Configure proper CORS settings**
|
||||||
|
5. **Review and adjust resource limits**
|
||||||
|
6. **Enable network policies** if needed
|
||||||
|
7. **Use image pull secrets** for private registries
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues or questions, refer to the main repository documentation.
|
||||||
48
brand-master-chart/templates/NOTES.txt
Normal file
48
brand-master-chart/templates/NOTES.txt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
1. Get the application URL by running these commands:
|
||||||
|
{{- if .Values.frontend.ingress.enabled }}
|
||||||
|
{{- range $host := .Values.frontend.ingress.hosts }}
|
||||||
|
{{- range .paths }}
|
||||||
|
Frontend: http{{ if $.Values.frontend.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.backend.ingress.enabled }}
|
||||||
|
{{- range $host := .Values.backend.ingress.hosts }}
|
||||||
|
{{- range .paths }}
|
||||||
|
Backend API: http{{ if $.Values.backend.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
2. Database Connection:
|
||||||
|
Host: {{ include "brand-master.fullname" . }}-db
|
||||||
|
Port: {{ .Values.postgres.port }}
|
||||||
|
Database: {{ .Values.postgres.database }}
|
||||||
|
User: {{ .Values.postgres.user }}
|
||||||
|
|
||||||
|
3. Product Images Storage:
|
||||||
|
{{- if .Values.backend.persistence.enabled }}
|
||||||
|
PVC: {{ include "brand-master.fullname" . }}-uploads-pvc
|
||||||
|
Size: {{ .Values.backend.persistence.size }}
|
||||||
|
Mount Path: {{ .Values.backend.persistence.mountPath }}
|
||||||
|
{{- else }}
|
||||||
|
Warning: Persistence is disabled. Product images will be lost on pod restart!
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
4. IMPORTANT Security Notes:
|
||||||
|
- Change the JWT secret key in values.yaml before deploying to production
|
||||||
|
- Update the database password in values.yaml
|
||||||
|
- Configure your domain names in the ingress sections
|
||||||
|
- Ensure cert-manager is installed for TLS certificates
|
||||||
|
|
||||||
|
5. To access the application locally without ingress:
|
||||||
|
kubectl port-forward svc/{{ include "brand-master.fullname" . }}-frontend 8080:80
|
||||||
|
kubectl port-forward svc/{{ include "brand-master.fullname" . }}-backend 8000:8000
|
||||||
|
|
||||||
|
6. To check pod status:
|
||||||
|
kubectl get pods -l app.kubernetes.io/instance={{ .Release.Name }}
|
||||||
|
|
||||||
|
7. To view logs:
|
||||||
|
kubectl logs -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=backend
|
||||||
|
kubectl logs -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=frontend
|
||||||
60
brand-master-chart/templates/_helpers.tpl
Normal file
60
brand-master-chart/templates/_helpers.tpl
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "brand-master.chart" . }}
|
||||||
|
{{ include "brand-master.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "brand-master.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "brand-master.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "brand-master.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
106
brand-master-chart/templates/backend-deployment.yaml
Normal file
106
brand-master-chart/templates/backend-deployment.yaml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-backend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.backend.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 6 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 8 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
spec:
|
||||||
|
{{- with .Values.global.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "brand-master.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
initContainers:
|
||||||
|
- name: wait-for-postgres
|
||||||
|
image: busybox:1.35
|
||||||
|
command: ['sh', '-c', 'until nc -z {{ include "brand-master.fullname" . }}-db-headless {{ .Values.postgres.port | default 5432 }}; do echo waiting for postgres; sleep 2; done;']
|
||||||
|
containers:
|
||||||
|
- name: backend
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.backend.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: database-url
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: jwt-secret-key
|
||||||
|
- name: ALGORITHM
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: jwt-algorithm
|
||||||
|
- name: ACCESS_TOKEN_EXPIRE_MINUTES
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: jwt-expire-minutes
|
||||||
|
{{- range $key, $value := .Values.backend.env }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
{{- if .Values.backend.persistence.enabled }}
|
||||||
|
- name: uploads
|
||||||
|
mountPath: {{ .Values.backend.persistence.mountPath }}
|
||||||
|
{{- end }}
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.backend.resources | nindent 12 }}
|
||||||
|
volumes:
|
||||||
|
{{- if .Values.backend.persistence.enabled }}
|
||||||
|
- name: uploads
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: {{ include "brand-master.fullname" . }}-uploads-pvc
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
42
brand-master-chart/templates/backend-ingress.yaml
Normal file
42
brand-master-chart/templates/backend-ingress.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{{- if .Values.backend.ingress.enabled -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-backend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
{{- with .Values.backend.ingress.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if .Values.backend.ingress.className }}
|
||||||
|
ingressClassName: {{ .Values.backend.ingress.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.backend.ingress.tls }}
|
||||||
|
tls:
|
||||||
|
{{- range .Values.backend.ingress.tls }}
|
||||||
|
- hosts:
|
||||||
|
{{- range .hosts }}
|
||||||
|
- {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
secretName: {{ .secretName }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
{{- range .Values.backend.ingress.hosts }}
|
||||||
|
- host: {{ .host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
{{- range .paths }}
|
||||||
|
- path: {{ .path }}
|
||||||
|
pathType: {{ .pathType }}
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ include "brand-master.fullname" $ }}-backend
|
||||||
|
port:
|
||||||
|
number: {{ $.Values.backend.service.port }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
18
brand-master-chart/templates/backend-pvc.yaml
Normal file
18
brand-master-chart/templates/backend-pvc.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{{- if .Values.backend.persistence.enabled }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-uploads-pvc
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- {{ .Values.backend.persistence.accessMode }}
|
||||||
|
{{- if .Values.backend.persistence.storageClass }}
|
||||||
|
storageClassName: {{ .Values.backend.persistence.storageClass }}
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.backend.persistence.size }}
|
||||||
|
{{- end }}
|
||||||
17
brand-master-chart/templates/backend-service.yaml
Normal file
17
brand-master-chart/templates/backend-service.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-backend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.backend.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.backend.service.port }}
|
||||||
|
targetPort: {{ .Values.backend.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: backend
|
||||||
36
brand-master-chart/templates/db-service.yaml
Normal file
36
brand-master-chart/templates/db-service.yaml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-db
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.postgres.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.postgres.service.port }}
|
||||||
|
targetPort: {{ .Values.postgres.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
name: postgres
|
||||||
|
selector:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-db-headless
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
clusterIP: None
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.postgres.service.port }}
|
||||||
|
targetPort: {{ .Values.postgres.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
name: postgres
|
||||||
|
selector:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
124
brand-master-chart/templates/db-statefulset.yaml
Normal file
124
brand-master-chart/templates/db-statefulset.yaml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-db
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
serviceName: {{ include "brand-master.fullname" . }}-db-headless
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 6 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 8 }}
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 999
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
chown -R 999:999 /var/lib/postgresql/data || true
|
||||||
|
chmod 700 /var/lib/postgresql/data || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: postgres-data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 0
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 999
|
||||||
|
runAsNonRoot: true
|
||||||
|
image: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.postgres.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: postgres
|
||||||
|
containerPort: {{ .Values.postgres.port }}
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: postgres-user
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: postgres-password
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
key: postgres-database
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
volumeMounts:
|
||||||
|
- name: postgres-data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
- name: postgres-run
|
||||||
|
mountPath: /var/run/postgresql
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.postgres.resources | nindent 12 }}
|
||||||
|
startupProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB"
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 30
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB"
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB"
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
volumes:
|
||||||
|
- name: postgres-run
|
||||||
|
emptyDir: {}
|
||||||
|
{{- if .Values.postgres.persistence.enabled }}
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: postgres-data
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- {{ .Values.postgres.persistence.accessMode }}
|
||||||
|
{{- if .Values.postgres.persistence.storageClass }}
|
||||||
|
storageClassName: {{ .Values.postgres.persistence.storageClass }}
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.postgres.persistence.size }}
|
||||||
|
{{- else }}
|
||||||
|
- name: postgres-data
|
||||||
|
emptyDir: {}
|
||||||
|
{{- end }}
|
||||||
73
brand-master-chart/templates/frontend-deployment.yaml
Normal file
73
brand-master-chart/templates/frontend-deployment.yaml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-frontend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.frontend.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 6 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 8 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
|
spec:
|
||||||
|
{{- with .Values.global.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "brand-master.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: frontend
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.frontend.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
{{- if .Values.frontend.env }}
|
||||||
|
env:
|
||||||
|
{{- range $key, $value := .Values.frontend.env }}
|
||||||
|
- name: {{ $key }}
|
||||||
|
value: {{ $value | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 5
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
42
brand-master-chart/templates/frontend-ingress.yaml
Normal file
42
brand-master-chart/templates/frontend-ingress.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{{- if .Values.frontend.ingress.enabled -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-frontend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
|
{{- with .Values.frontend.ingress.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if .Values.frontend.ingress.className }}
|
||||||
|
ingressClassName: {{ .Values.frontend.ingress.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.frontend.ingress.tls }}
|
||||||
|
tls:
|
||||||
|
{{- range .Values.frontend.ingress.tls }}
|
||||||
|
- hosts:
|
||||||
|
{{- range .hosts }}
|
||||||
|
- {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
secretName: {{ .secretName }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
{{- range .Values.frontend.ingress.hosts }}
|
||||||
|
- host: {{ .host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
{{- range .paths }}
|
||||||
|
- path: {{ .path }}
|
||||||
|
pathType: {{ .pathType }}
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ include "brand-master.fullname" $ }}-frontend
|
||||||
|
port:
|
||||||
|
number: {{ $.Values.frontend.service.port }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
17
brand-master-chart/templates/frontend-service.yaml
Normal file
17
brand-master-chart/templates/frontend-service.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-frontend
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.frontend.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.frontend.service.port }}
|
||||||
|
targetPort: {{ .Values.frontend.service.targetPort }}
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "brand-master.selectorLabels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: frontend
|
||||||
15
brand-master-chart/templates/secret.yaml
Normal file
15
brand-master-chart/templates/secret.yaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.fullname" . }}-secrets
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
postgres-user: {{ .Values.postgres.user | quote }}
|
||||||
|
postgres-password: {{ .Values.postgres.password | quote }}
|
||||||
|
postgres-database: {{ .Values.postgres.database | quote }}
|
||||||
|
database-url: "postgresql://{{ .Values.postgres.user }}:{{ .Values.postgres.password }}@{{ include "brand-master.fullname" . }}-db:{{ .Values.postgres.port }}/{{ .Values.postgres.database }}"
|
||||||
|
jwt-secret-key: {{ .Values.backend.jwtSecretKey | quote }}
|
||||||
|
jwt-algorithm: {{ .Values.backend.jwtAlgorithm | quote }}
|
||||||
|
jwt-expire-minutes: {{ .Values.backend.jwtExpireMinutes | quote }}
|
||||||
12
brand-master-chart/templates/serviceaccount.yaml
Normal file
12
brand-master-chart/templates/serviceaccount.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "brand-master.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "brand-master.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
165
brand-master-chart/values.yaml
Normal file
165
brand-master-chart/values.yaml
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
global:
|
||||||
|
namespace: my-apps
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
# Backend configuration
|
||||||
|
backend:
|
||||||
|
name: backend
|
||||||
|
replicaCount: 1
|
||||||
|
image:
|
||||||
|
repository: harbor.dvirlabs.com/my-apps/brand-master-backend
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: "latest"
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8000
|
||||||
|
targetPort: 8000
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 1Gi
|
||||||
|
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: "1"
|
||||||
|
BACKEND_URL: "https://api-brand-master.dvirlabs.com"
|
||||||
|
FRONTEND_URL: "https://brand-master.dvirlabs.com"
|
||||||
|
|
||||||
|
# JWT Secret Key (IMPORTANT: Change this in production!)
|
||||||
|
jwtSecretKey: "your-secret-key-change-this-in-production"
|
||||||
|
jwtAlgorithm: "HS256"
|
||||||
|
jwtExpireMinutes: "30"
|
||||||
|
|
||||||
|
# Persistent storage for product images
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
storageClass: "nfs-client"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
size: 15Gi
|
||||||
|
mountPath: /app/uploads
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: "traefik"
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
hosts:
|
||||||
|
- host: api-brand-master.dvirlabs.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: api-brand-master-tls
|
||||||
|
hosts:
|
||||||
|
- api-brand-master.dvirlabs.com
|
||||||
|
|
||||||
|
# Frontend configuration
|
||||||
|
frontend:
|
||||||
|
name: frontend
|
||||||
|
replicaCount: 1
|
||||||
|
image:
|
||||||
|
repository: harbor.dvirlabs.com/my-apps/brand-master-frontend
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
tag: "latest"
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
|
||||||
|
env:
|
||||||
|
VITE_API_URL: "https://api-brand-master.dvirlabs.com"
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: "traefik"
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
hosts:
|
||||||
|
- host: brand-master.dvirlabs.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: brand-master-tls
|
||||||
|
hosts:
|
||||||
|
- brand-master.dvirlabs.com
|
||||||
|
|
||||||
|
# PostgreSQL configuration
|
||||||
|
postgres:
|
||||||
|
name: db
|
||||||
|
image:
|
||||||
|
repository: postgres
|
||||||
|
tag: "16-alpine"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
user: brand_master_user
|
||||||
|
password: brand_master_password
|
||||||
|
database: brand_master_db
|
||||||
|
port: 5432
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
storageClass: "nfs-client"
|
||||||
|
size: 10Gi
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 1Gi
|
||||||
|
|
||||||
|
# Service Account
|
||||||
|
serviceAccount:
|
||||||
|
create: true
|
||||||
|
annotations: {}
|
||||||
|
name: ""
|
||||||
|
|
||||||
|
# Pod annotations
|
||||||
|
podAnnotations: {}
|
||||||
|
|
||||||
|
# Pod security context
|
||||||
|
podSecurityContext: {}
|
||||||
|
# fsGroup: 2000
|
||||||
|
|
||||||
|
# Container security context
|
||||||
|
securityContext: {}
|
||||||
|
# capabilities:
|
||||||
|
# drop:
|
||||||
|
# - ALL
|
||||||
|
# readOnlyRootFilesystem: true
|
||||||
|
# runAsNonRoot: true
|
||||||
|
# runAsUser: 1000
|
||||||
|
|
||||||
|
# Node selector
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
# Tolerations
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
# Affinity
|
||||||
|
affinity: {}
|
||||||
19
frontend/.dockerignore
Normal file
19
frontend/.dockerignore
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
60
frontend/Dockerfile
Normal file
60
frontend/Dockerfile
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM node:18-alpine AS build
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json package-lock.json* ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build argument for API URL (can be overridden at build time)
|
||||||
|
ARG VITE_API_URL
|
||||||
|
ENV VITE_API_URL=${VITE_API_URL}
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
# Remove default nginx config
|
||||||
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Create custom nginx config
|
||||||
|
RUN echo 'server {' > /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' listen 80;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' server_name _;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' root /usr/share/nginx/html;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' index index.html;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo '' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' # Enable gzip compression' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' gzip on;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' gzip_vary on;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' gzip_min_length 1024;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo '' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' location / {' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' try_files $uri $uri/ /index.html;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' }' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo '' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' # Cache static assets' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|webp)$ {' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' expires 1y;' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' add_header Cache-Control "public, immutable";' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo ' }' >> /etc/nginx/conf.d/default.conf && \
|
||||||
|
echo '}' >> /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Copy built files from build stage
|
||||||
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Expose port 80
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Start nginx
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
Loading…
x
Reference in New Issue
Block a user