diff --git a/.gitea-ci.yml b/.gitea-ci.yml index 1821deb..45e7c15 100644 --- a/.gitea-ci.yml +++ b/.gitea-ci.yml @@ -1,12 +1,83 @@ -image: lachlanevenson/k8s-helm:latest +version: 1.0 -stages: - - deploy +workflow: + name: Deploy to Production + on: + push: + branches: + - main -variables: - KUBECONFIG: /root/.kube/config # Adjust if you're mounting a kubeconfig differently +jobs: + build-and-deploy: + name: Build and Deploy + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 -deploy: - stage: deploy - script: - - helm upgrade --install fusero ./chart -f ./chart/values-prod.yaml + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Registry + uses: docker/login-action@v2 + with: + registry: registry.liquidrinu.com + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build and Push Backend + uses: docker/build-push-action@v4 + with: + context: ./backend + push: true + tags: registry.liquidrinu.com/fusero-backend:latest + cache-from: type=registry,ref=registry.liquidrinu.com/fusero-backend:buildcache + cache-to: type=registry,ref=registry.liquidrinu.com/fusero-backend:buildcache,mode=max + + - name: Build and Push Frontend + uses: docker/build-push-action@v4 + with: + context: ./frontend + push: true + tags: registry.liquidrinu.com/fusero-frontend:latest + cache-from: type=registry,ref=registry.liquidrinu.com/fusero-frontend:buildcache + cache-to: type=registry,ref=registry.liquidrinu.com/fusero-frontend:buildcache,mode=max + + - name: Install kubectl + uses: azure/setup-kubectl@v3 + with: + version: "latest" + + - name: Setup kubeconfig + run: | + mkdir -p $HOME/.kube + echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config + chmod 600 $HOME/.kube/config + + - name: Create secrets file + run: | + cat > ./chart/secrets.prod.yml << EOF + backend: + env: + POSTGRES_PASSWORD: "${{ secrets.POSTGRES_PASSWORD }}" + DEFAULT_ADMIN_PASSWORD: "${{ secrets.DEFAULT_ADMIN_PASSWORD }}" + ENCRYPTION_KEY: "${{ secrets.ENCRYPTION_KEY }}" + JWT_SECRET: "${{ secrets.JWT_SECRET }}" + CHATGPT_API_KEY: "${{ secrets.CHATGPT_API_KEY }}" + CANVAS_API_KEY: "${{ secrets.CANVAS_API_KEY }}" + EOF + + - name: Deploy to Kubernetes + run: | + helm upgrade --install fusero ./chart \ + --namespace fusero-prod \ + --create-namespace \ + --values ./chart/values.prod.yml \ + --values ./chart/secrets.prod.yml \ + --set backend.image.repository=registry.liquidrinu.com/fusero-backend \ + --set frontend.image.repository=registry.liquidrinu.com/fusero-frontend + + - name: Verify Deployment + run: | + kubectl rollout status deployment/fusero-backend -n fusero-prod + kubectl rollout status deployment/fusero-frontend -n fusero-prod diff --git a/.gitignore b/.gitignore index 9e87c4d..be7a341 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,21 @@ secrets.yml values.dev.* values.prod.* +# Secrets +chart/secrets.prod.yml +chart/secrets.*.yml +*.env +.env.* + +# Development values with secrets +chart/values.dev.yml + +# Production secrets +chart/secrets.prod.yml +chart/secrets.*.yml + +# Keep templates and public configs +!chart/secrets.prod.template.yml +!chart/values.prod.template.yml +!chart/values.prod.public.yml + diff --git a/README.md b/README.md index 3598aa6..d378443 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,24 @@ A full-stack application boilerplate with a React frontend and Node.js backend - [📁 Project Structure](#-project-structure) - [⚙️ Prerequisites](#️-prerequisites) - [💻 Development Setup](#-development-setup) +- [To create a new migration:](#to-create-a-new-migration) +- [npm run migration:create](#npm-run-migrationcreate) +- [To apply migrations:](#to-apply-migrations) +- [To seed the database:](#to-seed-the-database) - [Alternate: Running Services in Separate Terminals](#alternate-running-services-in-separate-terminals) - [🛠️ Environment Setup](#️-environment-setup) -- [For Kubernetes, these are set in chart/values.yaml:](#for-kubernetes-these-are-set-in-chartvaluesyaml) +- [For Kubernetes, these are set in chart/values.yml:](#for-kubernetes-these-are-set-in-chartvaluesyml) - [POSTGRES\_NAME=fusero-boilerplate-db](#postgres_namefusero-boilerplate-db) - [POSTGRES\_HOSTNAME=postgres-service](#postgres_hostnamepostgres-service) - [POSTGRES\_PORT=19095](#postgres_port19095) - [POSTGRES\_USER=root](#postgres_userroot) - [POSTGRES\_PASSWORD=root123](#postgres_passwordroot123) - - [🚀 Production Deployment](#-production-deployment) + - [🐳 Docker Development](#-docker-development) +- [To create a new migration:](#to-create-a-new-migration-1) +- [npm run migration:create](#npm-run-migrationcreate-1) +- [To apply migrations:](#to-apply-migrations-1) +- [To seed the database:](#to-seed-the-database-1) + - [🚀 Kubernetes Deployment](#-kubernetes-deployment) - [🌐 Frontend Routing in Production](#-frontend-routing-in-production) - [🔐 HTTPS with Self-Signed Certificates](#-https-with-self-signed-certificates) - [🧠 Development Best Practices](#-development-best-practices) @@ -53,17 +62,66 @@ A full-stack application boilerplate with a React frontend and Node.js backend - [Debugging Frontend Pod Crashes: NGINX SSL Certificate Errors](#debugging-frontend-pod-crashes-nginx-ssl-certificate-errors) - [How to fix for Kubernetes (Recommended)](#how-to-fix-for-kubernetes-recommended) - [Connecting to the Database from Your Host (DBeaver, etc.)](#connecting-to-the-database-from-your-host-dbeaver-etc) + - [🎯 Kubernetes Namespace Management](#-kubernetes-namespace-management) + - [Development Namespace Setup](#development-namespace-setup) + - [Production Namespace Setup](#production-namespace-setup) + - [Namespace Management Commands](#namespace-management-commands) + - [Recommended Kubernetes GUI Tools](#recommended-kubernetes-gui-tools) + - [🆕 Namespaced Development Environment with Helm](#-namespaced-development-environment-with-helm) + - [What was changed:](#what-was-changed) + - [How to use:](#how-to-use) + - [Why use namespaces?](#why-use-namespaces) + - [🔒 Production Security \& Best Practices](#-production-security--best-practices) + - [Environment Variables \& Secrets](#environment-variables--secrets) + - [HTTPS \& Certificates](#https--certificates) + - [CORS \& Security Headers](#cors--security-headers) + - [Logging \& Monitoring](#logging--monitoring) + - [Database Backup](#database-backup) + - [CI/CD \& Automated Testing](#cicd--automated-testing) + - [Troubleshooting Production](#troubleshooting-production) --- ## 📁 Project Structure -fusero-app-boilerplate/ -├── frontend/ # React frontend application -├── backend/ # Node.js backend application -├── docker-compose.yml # Production Docker configuration -├── docker-compose.dev.yml # Development Docker configuration -└── chart/ # Helm chart for Kubernetes deployment +fusero-app-boilerplate/ +├── chart/ # Helm chart for Kubernetes +│ ├── Chart.yaml +│ ├── values.dev.yaml +│ ├── values.prod.yml +│ └── templates/ +├── config/ +├── coverage/ +├── dist/ +├── docs/ +├── frontend/ # React frontend app +│ ├── public/ +│ └── src/ +├── mikro-orm.config.ts +├── nginx/ +├── node_modules/ +├── package.json +├── package-lock.json +├── docker-compose.yml +├── docker-compose.dev.yml +├── .gitignore +├── .gitea-ci.yml +├── .prettierrc.json +├── .eslintrc.json +├── architecture.excalidraw +├── src/ # Node.js backend source +│ ├── apps/ +│ ├── constants/ +│ ├── database/ +│ ├── middleware/ +│ ├── plugins/ +│ ├── shared/ +│ ├── tests/ +│ ├── types/ +│ └── ... +├── test/ +├── utils/ +└── README.md --- @@ -81,14 +139,18 @@ fusero-app-boilerplate/ 🗃️ PostgreSQL must run in Docker for consistent behavior. Create volume and start the database: -docker volume create fusero-db-data +docker volume create fusero-dev-db-data docker-compose up -d db Backend setup: cd backend cp .env.example .env npm install +# To create a new migration: +# npm run migration:create +# To apply migrations: npm run migrate +# To seed the database: npm run seed npm run dev & cd .. @@ -130,7 +192,7 @@ POSTGRES_USER=root POSTGRES_PASSWORD=root123 JWT_SECRET=your_jwt_secret_key_here -# For Kubernetes, these are set in chart/values.yaml: +# For Kubernetes, these are set in chart/values.yml: # POSTGRES_NAME=fusero-boilerplate-db # POSTGRES_HOSTNAME=postgres-service # POSTGRES_PORT=19095 @@ -142,13 +204,47 @@ VITE_API_BASE_URL=http://localhost:14000/api/v1 --- -## 🚀 Production Deployment +## 🐳 Docker Development + +🗃️ PostgreSQL must run in Docker for consistent behavior. + +Create volume and start the database: +docker volume create fusero-dev-db-data +docker-compose up -d db + +Backend setup: +cd backend +cp .env.example .env +npm install +# To create a new migration: +# npm run migration:create +# To apply migrations: +npm run migrate +# To seed the database: +npm run seed +npm run dev & +cd .. + +Frontend setup: +cd frontend +cp .env.example .env +npm install +npm run dev & +cd .. + +App is running: +Frontend → http://localhost:3000 +Backend → http://localhost:14000 + +--- + +## 🚀 Kubernetes Deployment 1. Build and run with Docker: docker-compose up --build 2. Apply migrations and seed inside backend container: -docker exec -it fusero-app-backend npx mikro-orm migration:up +docker exec -it fusero-app-backend npm run migrate docker exec -it fusero-app-backend npm run seed 3. Ensure all required environment variables are configured. @@ -288,7 +384,7 @@ docker push /fusero-backend-dev:local ### 3. Upgrade the Helm release with the latest values ```bash -helm upgrade fusero ./chart -n fusero -f chart/values.dev.yaml +helm upgrade fusero ./chart -n fusero -f chart/values.dev.yml ``` ### 4. Restart the backend deployment to pick up new images and env vars @@ -334,7 +430,7 @@ docker push /fusero-frontend-dev:local ### 3. Upgrade the Helm release ```bash -helm upgrade fusero ./chart -n fusero -f chart/values.dev.yaml +helm upgrade fusero ./chart -n fusero -f chart/values.dev.yml ``` ### 4. Restart the frontend deployment @@ -386,7 +482,7 @@ Then rebuild and redeploy the frontend: ```bash docker build -t fusero-frontend-dev:local ./frontend # (push if needed) -helm upgrade fusero ./chart -n fusero -f chart/values.dev.yaml +helm upgrade fusero ./chart -n fusero -f chart/values.dev.yml kubectl rollout restart deployment/fusero-frontend -n fusero ``` @@ -450,7 +546,7 @@ This means NGINX is trying to load an SSL certificate that does not exist in the 3. (If using a remote registry) Push the image. 4. Redeploy with Helm: ```bash - helm upgrade fusero ./chart -n fusero -f chart/values.dev.yaml + helm upgrade fusero ./chart -n fusero -f chart/values.dev.yml ``` 5. Check pod status: ```bash @@ -484,3 +580,190 @@ To connect to the Postgres database running in Kubernetes from your local machin 4. **Test the connection.** --- + +## 🎯 Kubernetes Namespace Management + +### Development Namespace Setup +```bash +# Create development namespace +kubectl create namespace fusero-dev + +# Set current context to development namespace +kubectl config set-context --current --namespace=fusero-dev + +# Deploy to development namespace +helm upgrade --install fusero ./chart -n fusero-dev -f chart/values.dev.yml +``` + +### Production Namespace Setup +```bash +# Create production namespace +kubectl create namespace fusero-prod + +# Set current context to production namespace +kubectl config set-context --current --namespace=fusero-prod + +# Deploy to production namespace +helm upgrade --install fusero ./chart -n fusero-prod -f chart/values.prod.yml +``` + +### Namespace Management Commands +```bash +# List all namespaces +kubectl get namespaces + +# Switch between namespaces +kubectl config set-context --current --namespace= + +# View resources in current namespace +kubectl get all + +# Delete namespace (be careful!) +kubectl delete namespace +``` + +### Recommended Kubernetes GUI Tools +1. **Lens** - The most popular Kubernetes IDE + - Download: https://k8slens.dev/ + - Features: + - Real-time cluster monitoring + - Multi-cluster management + - Namespace isolation + - Resource visualization + - Log streaming + - Terminal access + +2. **K9s** - Terminal-based UI + - Install: `brew install k9s` (Mac) or `scoop install k9s` (Windows) + - Features: + - Fast navigation + - Resource management + - Log viewing + - Port forwarding + +3. **Octant** - Web-based UI + - Install: https://octant.dev/ + - Features: + - Resource visualization + - Configuration management + - Log viewing + - Port forwarding + +--- + +## 🆕 Namespaced Development Environment with Helm + +You have configured your Kubernetes development environment to use a dedicated namespace (`fusero-dev`) for all core services (backend, frontend, and database). This ensures resource isolation and easier management between development and production. + +### What was changed: +- All Kubernetes service templates (`backend-service.yml`, `frontend-service.yml`, `postgres-service.yml`) now use a namespace variable. +- The development values file (`chart/values.dev.yml`) sets `global.namespace: fusero-dev` and updates all internal service hostnames to use this namespace. +- Helm deployments now target the `fusero-dev` namespace for all dev resources. + +### How to use: +1. **Create the development namespace (if not already created):** + ```bash + kubectl create namespace fusero-dev + ``` + +2. **Deploy all services to the namespace:** + ```bash + helm upgrade --install fusero ./chart -n fusero-dev -f chart/values.dev.yml + ``` + +3. **Check running pods and services:** + ```bash + kubectl get all -n fusero-dev + ``` + +4. **If you update environment variables or service hostnames, repeat the Helm upgrade command.** + +5. **If you see errors about immutable fields (e.g., for Jobs), delete the old Job before redeploying:** + ```bash + kubectl delete job -n fusero-dev + helm upgrade --install fusero ./chart -n fusero-dev -f chart/values.dev.yml + ``` + +### Why use namespaces? +- Keeps dev and prod resources isolated +- Makes it easy to clean up or redeploy all dev resources +- Prevents accidental cross-environment access + +--- + +## 🔒 Production Security & Best Practices + +### Environment Variables & Secrets + +The application uses a secure secrets management approach: + +1. **Development Environment**: + - Use `.env` files locally (gitignored) + - Copy from `.env.example` as template + +2. **Production Environment**: + - Secrets are managed through Gitea CI/CD secrets + - Template file: `chart/secrets.prod.template.yml` + - Actual secrets are generated during deployment + - Never commit actual secrets to the repository + +3. **Required Secrets**: + - Database credentials + - Admin user credentials + - Security keys (encryption, JWT) + - API keys (ChatGPT, Canvas) + +4. **Secrets in CI/CD**: + - Secrets are stored in Gitea CI/CD settings + - Automatically injected during deployment + - Used to generate `secrets.prod.yml` at runtime + +5. **Security Best Practices**: + - All secrets files are gitignored + - Template files contain placeholder values + - Production secrets are never stored in the repository + - Regular rotation of secrets recommended + +### HTTPS & Certificates +- In production, use trusted certificates (e.g., Let's Encrypt). +- Configure NGINX to enforce HTTPS. + +### CORS & Security Headers +- Lock down CORS settings in production. +- Use security headers (e.g., HSTS, CSP). + +### Logging & Monitoring +- Configure logging for production (e.g., ELK stack, Datadog). +- Set up basic monitoring (e.g., Prometheus, Grafana). + +### Database Backup +- Regularly backup your production database. +- Example: Use `pg_dump` or a managed backup service. + +### CI/CD & Automated Testing +- Run tests before deploying to production. +- Example CI/CD workflow: + ```yaml + # .github/workflows/deploy.yml + name: Deploy to Production + on: + push: + branch: main + jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run Tests + run: npm test + - name: Deploy to Kubernetes + run: helm upgrade --install fusero ./chart -n fusero-prod -f chart/values.prod.yml + ``` + +### Troubleshooting Production +- Common issues: + - Database connection errors: Check secrets and network policies. + - Pod crashes: Check logs with `kubectl logs -n fusero-prod`. +- Rollback: Use `helm rollback fusero -n fusero-prod`. + +--- diff --git a/chart/Chart.yaml b/chart/Chart.yml similarity index 100% rename from chart/Chart.yaml rename to chart/Chart.yml diff --git a/chart/secrets.prod.template.yml b/chart/secrets.prod.template.yml new file mode 100644 index 0000000..1ecd2c3 --- /dev/null +++ b/chart/secrets.prod.template.yml @@ -0,0 +1,26 @@ +backend: + env: + # Database + POSTGRES_NAME: "fusero-boilerplate-db" + POSTGRES_HOSTNAME: "postgres-service.fusero-prod.svc.cluster.local" + POSTGRES_PORT: "5432" + POSTGRES_USER: "root" + POSTGRES_PASSWORD: "REPLACE_ME" + + # Admin User + DEFAULT_ADMIN_USERNAME: "admin" + DEFAULT_ADMIN_EMAIL: "admin@fusero.nl" + DEFAULT_ADMIN_PASSWORD: "REPLACE_ME" + + # Security + ENCRYPTION_KEY: "REPLACE_ME" + JWT_SECRET: "REPLACE_ME" + + # API Keys + CHATGPT_API_KEY: "REPLACE_ME" + CANVAS_API_KEY: "REPLACE_ME" + CANVAS_API_URL: "https://talnet.instructure.com/api/v1" + + # Server + FASTIFY_PORT: "14000" + NODE_ENV: "production" diff --git a/chart/templates/backend-deployment.yaml b/chart/templates/backend-deployment.yml similarity index 100% rename from chart/templates/backend-deployment.yaml rename to chart/templates/backend-deployment.yml diff --git a/chart/templates/backend-migration.job.yaml b/chart/templates/backend-migration.job.yml similarity index 100% rename from chart/templates/backend-migration.job.yaml rename to chart/templates/backend-migration.job.yml diff --git a/chart/templates/backend-secrets.yaml b/chart/templates/backend-secrets.yaml deleted file mode 100644 index 3db53f4..0000000 --- a/chart/templates/backend-secrets.yaml +++ /dev/null @@ -1,2 +0,0 @@ -# You can skip this if you manage secrets separately -# Included for completeness (values-dev.yaml handles them) diff --git a/chart/templates/backend-secrets.yml b/chart/templates/backend-secrets.yml new file mode 100644 index 0000000..75556fb --- /dev/null +++ b/chart/templates/backend-secrets.yml @@ -0,0 +1,16 @@ +# You can skip this if you manage secrets separately +# Included for completeness (values-dev.yaml handles them) + +apiVersion: v1 +kind: Secret +metadata: + name: fusero-backend-secrets + namespace: {{ .Values.global.namespace }} +type: Opaque +data: + POSTGRES_PASSWORD: {{ .Values.backend.env.POSTGRES_PASSWORD | b64enc }} + DEFAULT_ADMIN_PASSWORD: {{ .Values.backend.env.DEFAULT_ADMIN_PASSWORD | b64enc }} + ENCRYPTION_KEY: {{ .Values.backend.env.ENCRYPTION_KEY | b64enc }} + JWT_SECRET: {{ .Values.backend.env.JWT_SECRET | b64enc }} + CHATGPT_API_KEY: {{ .Values.backend.env.CHATGPT_API_KEY | b64enc }} + CANVAS_API_KEY: {{ .Values.backend.env.CANVAS_API_KEY | b64enc }} diff --git a/chart/templates/backend-service.yaml b/chart/templates/backend-service.yml similarity index 83% rename from chart/templates/backend-service.yaml rename to chart/templates/backend-service.yml index 98c4aad..5616dae 100644 --- a/chart/templates/backend-service.yaml +++ b/chart/templates/backend-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: fusero-backend-service + namespace: {{ .Values.global.namespace }} spec: selector: app: fusero-backend diff --git a/chart/templates/frontend-deployment.yaml b/chart/templates/frontend-deployment.yml similarity index 100% rename from chart/templates/frontend-deployment.yaml rename to chart/templates/frontend-deployment.yml diff --git a/chart/templates/frontend-service.yaml b/chart/templates/frontend-service.yml similarity index 82% rename from chart/templates/frontend-service.yaml rename to chart/templates/frontend-service.yml index 660e3bf..3f56cf0 100644 --- a/chart/templates/frontend-service.yaml +++ b/chart/templates/frontend-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: fusero-frontend-service + namespace: {{ .Values.global.namespace }} spec: selector: app: fusero-frontend diff --git a/chart/templates/postgres-deployment.yaml b/chart/templates/postgres-deployment.yml similarity index 100% rename from chart/templates/postgres-deployment.yaml rename to chart/templates/postgres-deployment.yml diff --git a/chart/templates/postgres-pvc.yaml b/chart/templates/postgres-pvc.yml similarity index 100% rename from chart/templates/postgres-pvc.yaml rename to chart/templates/postgres-pvc.yml diff --git a/chart/templates/postgres-service.yaml b/chart/templates/postgres-service.yml similarity index 76% rename from chart/templates/postgres-service.yaml rename to chart/templates/postgres-service.yml index ec5c270..0995e2a 100644 --- a/chart/templates/postgres-service.yaml +++ b/chart/templates/postgres-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: postgres-service + namespace: {{ .Values.global.namespace }} spec: selector: app: postgres diff --git a/chart/values.prod.public.yml b/chart/values.prod.public.yml new file mode 100644 index 0000000..b384b76 --- /dev/null +++ b/chart/values.prod.public.yml @@ -0,0 +1,53 @@ +global: + namespace: fusero-prod + security: + cors: + origin: "https://your-domain.com" + methods: "GET,POST,PUT,DELETE" + credentials: true + https: + enabled: true + certSecret: "fusero-tls-secret" + logging: + level: "info" + format: "json" + monitoring: + prometheus: + enabled: true + path: "/metrics" + +backend: + image: fusero-backend:latest + resources: + requests: + cpu: "200m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" + env: + # Non-sensitive values only + NODE_ENV: "production" + FASTIFY_PORT: "14000" + CANVAS_API_URL: "https://talnet.instructure.com/api/v1" + +frontend: + image: fusero-frontend:latest + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "300m" + memory: "256Mi" + +postgres: + image: postgres:15 + storage: 5Gi + resources: + requests: + cpu: "200m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" diff --git a/chart/values.prod.yml b/chart/values.prod.yml index 321ca39..00879e2 100644 --- a/chart/values.prod.yml +++ b/chart/values.prod.yml @@ -1,22 +1,64 @@ +global: + namespace: fusero-prod + security: + cors: + origin: "https://app.fusero.nl" + methods: "GET,POST,PUT,DELETE" + credentials: true + https: + enabled: true + certSecret: "fusero-tls-secret" + logging: + level: "info" + format: "json" + monitoring: + prometheus: + enabled: true + path: "/metrics" + backend: - image: fusero-backend:latest + image: registry.liquidrinu.com/fusero-backend:latest + resources: + requests: + cpu: "200m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" env: POSTGRES_HOST: postgres-service POSTGRES_PORT: "5432" POSTGRES_NAME: fusero-db POSTGRES_USER: prod_admin - POSTGRES_PASSWORD: REPLACE_ME + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} DEFAULT_ADMIN_USERNAME: admin DEFAULT_ADMIN_EMAIL: admin@fusero.nl - DEFAULT_ADMIN_PASSWORD: STRONG_REPLACE_ME - ENCRYPTION_KEY: PROD_REPLACE_ME_KEY - JWT_SECRET: PROD_REPLACE_ME_JWT - CHATGPT_API_KEY: PROD_REPLACE_ME_CHATGPT - CANVAS_API_KEY: PROD_REPLACE_ME_CANVAS + DEFAULT_ADMIN_PASSWORD: ${DEFAULT_ADMIN_PASSWORD} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} + JWT_SECRET: ${JWT_SECRET} + CHATGPT_API_KEY: ${CHATGPT_API_KEY} + CANVAS_API_KEY: ${CANVAS_API_KEY} + CANVAS_API_URL: https://talnet.instructure.com/api/v1 frontend: - image: fusero-frontend:latest + image: registry.liquidrinu.com/fusero-frontend:latest + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "300m" + memory: "256Mi" + env: + VITE_API_BASE_URL: https://app.fusero.nl postgres: image: postgres:15 storage: 5Gi + resources: + requests: + cpu: "200m" + memory: "256Mi" + limits: + cpu: "500m" + memory: "512Mi" diff --git a/package.json b/package.json index 1ca7dda..9095dd2 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,25 @@ "@": "src" }, "scripts": { - "fc": "fastify cli", + "build:ts": "rimraf dist && tsc", + "build:frontend:dev": "docker build -t fusero-frontend-dev:local -f frontend/Dockerfile.dev ./frontend", + "prebuild": "npm run lint", + "start": "npm run build:ts && fastify start -l info -r tsconfig-paths/register dist/src/app.js", + "dev": "npm run build:ts && concurrently -k -p '[{name}]' -n 'TypeScript,App,Watcher' -c 'teal.bold,orange.bold,purple.bold' 'npm:watch:ts' 'npm:dev:start' 'npm:watch:ts'", + "dev:start": "fastify start --ignore-watch=.ts$ -w -l info -P -r tsconfig-paths/register dist/src/app.js", + "watch:ts": "tsc -w", + "lint": "eslint src/**/*.{js,jsx,ts,tsx}", + "lint:fix": "eslint src/**/*.{js,jsx,ts,tsx} --fix", "test": "jest", "test:unit": "tap test/services/**/*.ts", "test:integration": "tap test/integration/**/*.ts", "test:watch": "jest --watch", "test:coverage": "jest --coverage", - "start": "npm run build:ts && fastify start -l info -r tsconfig-paths/register dist/src/app.js", - "prebuild": "npm run lint", - "build:ts": "rimraf dist && tsc", - "build:frontend:dev": "docker build -t fusero-frontend-dev:local -f frontend/Dockerfile.dev ./frontend", + "test:db": "ts-node -r tsconfig-paths/register src/database/test-connection.ts", + "migration:create": "npx mikro-orm migration:create", + "migrate": "npx mikro-orm migration:up", + "seed": "ts-node -r tsconfig-paths/register src/database/seeds/run-seed.ts", + "app:generate": "node ./utils/generate-app.js", "k8s:dev:apply": "kubectl apply -f k8s/frontend/deployment.dev.yml", "k8s:dev:delete": "kubectl delete deployment fusero-frontend-dev 2>/dev/null || true", "k8s:dev:run": "kubectl port-forward svc/fusero-frontend-service 3000:80", @@ -27,15 +36,6 @@ "k8s:dev:svc": "kubectl describe svc fusero-frontend-service", "k8s:dev:deployment": "kubectl describe deployment fusero-frontend-dev", "k8s:get": "kubectl get pods,svc,deployment", - "watch:ts": "tsc -w", - "dev": "npm run build:ts && concurrently -k -p \"[{name}]\" -n \"TypeScript,App\" -c \"yellow.bold,cyan.bold\" \"npm:watch:ts\" \"npm:dev:start\"", - "dev:start": "fastify start --ignore-watch=.ts$ -w -l info -P -r tsconfig-paths/register dist/src/app.js", - "app:generate": "node ./utils/generate-app.js", - "lint": "eslint src/**/*.{js,jsx,ts,tsx}", - "lint:fix": "eslint src/**/*.{js,jsx,ts,tsx} --fix", - "migration:create": "npx mikro-orm migration:create", - "seed": "ts-node -r tsconfig-paths/register src/database/seeds/run-seed.ts", - "test:db": "ts-node -r tsconfig-paths/register src/database/test-connection.ts", "k8s:exec": "kubectl exec -it $POD_NAME -- /bin/sh" }, "keywords": [], @@ -103,4 +103,4 @@ "git add" ] } -} +} \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index cb9569f..b3b03e3 100644 --- a/src/app.ts +++ b/src/app.ts @@ -129,6 +129,11 @@ const app: FastifyPluginAsync = async (app, opts): Promise => { export async function buildApp(): Promise { const server = fastify(); await server.register(app); + + // Set the port to 14000 + const port = process.env.PORT || 14000; + await server.listen({ port: Number(port), host: '0.0.0.0' }); + return server; }