Add cuisine subcategory filter, fix remap logic, and add OKE deployment manifests
- Add 파인다이닝/코스 cuisine type to 한식/일식/중식/양식 categories - Change cuisine filter from flat list to grouped optgroup with subcategories - Fix remap-foods/remap-cuisine: add jdbcType=CLOB, fix CLOB LISTAGG, improve retry logic (3 attempts, batch size 5), add error logging - Add OKE deployment: Dockerfiles, K8s manifests, deploy.sh, deployment guide - Add Next.js standalone output for Docker builds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
70
k8s/backend-deployment.yaml
Normal file
70
k8s/backend-deployment.yaml
Normal file
@@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backend
|
||||
namespace: tasteby
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: backend
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: ocir-secret
|
||||
containers:
|
||||
- name: backend
|
||||
image: icn.ocir.io/idyhsdamac8c/tasteby/backend:latest
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: tasteby-config
|
||||
- secretRef:
|
||||
name: tasteby-secrets
|
||||
volumeMounts:
|
||||
- name: oracle-wallet
|
||||
mountPath: /etc/oracle/wallet
|
||||
readOnly: true
|
||||
- name: oci-config
|
||||
mountPath: /root/.oci
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 768Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 1536Mi
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: 8000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: 8000
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
volumes:
|
||||
- name: oracle-wallet
|
||||
secret:
|
||||
secretName: oracle-wallet
|
||||
- name: oci-config
|
||||
secret:
|
||||
secretName: oci-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: backend
|
||||
namespace: tasteby
|
||||
spec:
|
||||
selector:
|
||||
app: backend
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
14
k8s/cert-manager/cluster-issuer.yaml
Normal file
14
k8s/cert-manager/cluster-issuer.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: joungmin@tasteby.net
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod-key
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
14
k8s/configmap.yaml
Normal file
14
k8s/configmap.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tasteby-config
|
||||
namespace: tasteby
|
||||
data:
|
||||
REDIS_HOST: "redis"
|
||||
REDIS_PORT: "6379"
|
||||
REDIS_DB: "0"
|
||||
ORACLE_WALLET: "/etc/oracle/wallet"
|
||||
OCI_CHAT_ENDPOINT: "https://inference.generativeai.us-ashburn-1.oci.oraclecloud.com"
|
||||
OCI_GENAI_ENDPOINT: "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com"
|
||||
OCI_EMBED_MODEL_ID: "cohere.embed-v4.0"
|
||||
GOOGLE_CLIENT_ID: "635551099330-2l003d3ernjmkqavd4f6s78r8r405iml.apps.googleusercontent.com"
|
||||
53
k8s/frontend-deployment.yaml
Normal file
53
k8s/frontend-deployment.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend
|
||||
namespace: tasteby
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: frontend
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: ocir-secret
|
||||
containers:
|
||||
- name: frontend
|
||||
image: icn.ocir.io/idyhsdamac8c/tasteby/frontend:latest
|
||||
ports:
|
||||
- containerPort: 3001
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3001
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3001
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 30
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend
|
||||
namespace: tasteby
|
||||
spec:
|
||||
selector:
|
||||
app: frontend
|
||||
ports:
|
||||
- port: 3001
|
||||
targetPort: 3001
|
||||
48
k8s/ingress.yaml
Normal file
48
k8s/ingress.yaml
Normal file
@@ -0,0 +1,48 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: tasteby-ingress
|
||||
namespace: tasteby
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
# Redirect tasteby.net → www.tasteby.net
|
||||
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- www.tasteby.net
|
||||
- tasteby.net
|
||||
secretName: tasteby-tls
|
||||
rules:
|
||||
- host: www.tasteby.net
|
||||
http:
|
||||
paths:
|
||||
- path: /api/
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: backend
|
||||
port:
|
||||
number: 8000
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: frontend
|
||||
port:
|
||||
number: 3001
|
||||
- host: tasteby.net
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: frontend
|
||||
port:
|
||||
number: 3001
|
||||
4
k8s/namespace.yaml
Normal file
4
k8s/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: tasteby
|
||||
39
k8s/redis-deployment.yaml
Normal file
39
k8s/redis-deployment.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: tasteby
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: tasteby
|
||||
spec:
|
||||
selector:
|
||||
app: redis
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
17
k8s/secrets.yaml.template
Normal file
17
k8s/secrets.yaml.template
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copy this to secrets.yaml and fill in real values.
|
||||
# DO NOT commit secrets.yaml to git!
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: tasteby-secrets
|
||||
namespace: tasteby
|
||||
type: Opaque
|
||||
stringData:
|
||||
ORACLE_USER: "<oracle-username>"
|
||||
ORACLE_PASSWORD: "<oracle-password>"
|
||||
ORACLE_DSN: "<tns-alias>_high?TNS_ADMIN=/etc/oracle/wallet"
|
||||
JWT_SECRET: "<jwt-secret>"
|
||||
OCI_COMPARTMENT_ID: "<oci-compartment-id>"
|
||||
OCI_CHAT_MODEL_ID: "<oci-chat-model-id>"
|
||||
GOOGLE_MAPS_API_KEY: "<google-maps-api-key>"
|
||||
YOUTUBE_DATA_API_KEY: "<youtube-data-api-key>"
|
||||
Reference in New Issue
Block a user