Merge pull request #123 from HideyoshiSolutions/develop

develop - feature: new cluster structure configuration
This commit is contained in:
2025-11-07 18:00:24 -03:00
committed by GitHub
28 changed files with 311 additions and 1183 deletions

View File

@@ -1,49 +0,0 @@
KUBE_NAMESPACE=
MASTER_NODE_LABEL=
WORKER_NODE_LABEL=
# Certificates Secrets
KUBE_CERT_SERVER=
KUBE_DOMAIN_ORGANIZATION=
KUBE_DOMAIN_EMAIL=
KUBE_DOMAIN=
KUBE_API_DOMAIN=
# Backend Secrets
KUBE_BACKEND_TOKEN_SECRET=
KUBE_BACKEND_ACCESS_TOKEN_DURATION=
KUBE_BACKEND_REFRESH_TOKEN_DURATION=
KUBE_BACKEND_DEFAULT_USER_FULL_NAME=
KUBE_BACKEND_DEFAULT_USER_EMAIL=
KUBE_BACKEND_DEFAULT_USER_USERNAME=
KUBE_BACKEND_DEFAULT_USER_PASSWORD=
KUBE_BACKEND_GOOGLE_CLIENT_ID=
KUBE_BACKEND_GOOGLE_CLIENT_SECRET=
KUBE_BACKEND_GOOGLE_REDIRECT_URL=
KUBE_BACKEND_GITHUB_CLIENT_ID=
KUBE_BACKEND_GITHUB_CLIENT_SECRET=
KUBE_BACKEND_GITHUB_REDIRECT_URL=
# Frontend Secrets
KUBE_FRONTEND_URL=
KUBE_FRONTEND_BACKEND_URL=
KUBE_FRONTEND_OAUTH_URL=
KUBE_FRONTEND_GITHUB_USER=
# Database Secrets (Postgres)
KUBE_DATABASE_NAME=
KUBE_DATABASE_USER=
KUBE_DATABASE_PASSWORD=
# Redis Secrets
KUBE_REDIS_PASSWORD=
# Storage Secrets (AWS S3)
KUBE_STORAGE_TYPE=
KUBE_STORAGE_AWS_ACCESS_KEY_ID=
KUBE_STORAGE_AWS_SECRET_ACCESS_KEY=
KUBE_STORAGE_AWS_REGION=
KUBE_STORAGE_AWS_BUCKET=
KUBE_STORAGE_VIRUS_CHECKER_TYPE=
KUBE_STORAGE_VIRUS_CHECKER_API_KEY=

View File

@@ -2,11 +2,11 @@ name: remote ssh command
on: on:
repository_dispatch: repository_dispatch:
types: [deploy-prod] types:
- deploy
push: push:
branches: branches:
- main - main
- staging
jobs: jobs:
deploy: deploy:
@@ -14,17 +14,20 @@ jobs:
environment: ${{ github.ref_name == 'main' && 'prod' || 'staging' }} environment: ${{ github.ref_name == 'main' && 'prod' || 'staging' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 30 timeout-minutes: 30
env:
NAMESPACE: ${{ vars.NAMESPACE }}
steps: steps:
- uses: actions/checkout@v4
- name: Writing Env File
run: |
echo "${{ secrets.ENV_FILE }}" | base64 -d > .env
- name: Set Kubernetes Context - name: Set Kubernetes Context
uses: azure/k8s-set-context@v1 uses: azure/k8s-set-context@v1
with: with:
method: kubeconfig method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }} kubeconfig: ${{ secrets.PORTFOLIO_KUBECONFIG }}
- name: Configures GHCR credentials
run: |
echo ${{ secrets.GHCR_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Execute deploy - name: Execute deploy
run: | run: |
./deploy.sh -f .env ./deploy.sh

View File

@@ -1,36 +0,0 @@
name: workflow_02
on:
repository_dispatch:
types: [refresh-deployments]
jobs:
refresh_deployment:
name: Refresh Kubernetes Deployments
environment: prod
runs-on: ubuntu-latest
timeout-minutes: 30
env:
deployments: ${{ github.event.client_payload.deployments }}
steps:
- uses: actions/checkout@v4
- name: Writing Env File
run: |
echo "${{ secrets.ENV_FILE }}" | base64 -d > .env
- name: Set Kubernetes Context
uses: azure/k8s-set-context@v1
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Refresh Deployments
if: ${{ env.deployments == '' }}
run: |
./deploy.sh -f .env -r
- name: Refresh Specific Deployments
if: ${{ env.deployments != '' }}
run: |
./deploy.sh -f .env -r ${{ env.deployments }}

261
deploy.sh
View File

@@ -1,252 +1,39 @@
#!/bin/bash #!/bin/bash
validate_dependencies() { ### deploy flux operator ###
if ! command -v kubectl &> /dev/null; then helm upgrade --install flux-operator oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator \
echo "kubectl could not be found" --namespace flux-system \
exit 1 --create-namespace
fi
if ! command -v helm &> /dev/null; then
echo "helm could not be found"
exit 1
fi
if ! command -v envsubst &> /dev/null; then
echo "envsubst could not be found"
exit 1
fi
if [[ $environment == "local" ]]; then
if ! command -v minikube &> /dev/null; then
echo "minikube could not be found"
exit 1
fi
fi
echo "Dependencies validated"
}
read_env_file() { kubectl apply -f manifest/flux-instance.yml
if [ -f $1 ]; then
set -a && source $1 && set +a;
fi
}
build_secret_envs() { ### Additional components ###
for i in $(env | grep -E '^KUBE_[a-zA-Z_][a-zA-Z0-9_]*=' | cut -d= -f1); do # deploy descheduler
eval "export ${i}_B64=$(echo -n ${!i} | base64 -w0)" kubectl apply -f manifest/charts/descheduler
done
}
apply_template() { # deploy ingress-nginx
echo -e "\n\n----------------------------------------------------\n" kubectl create namespace ingress-nginx \
echo -e "Applying: $1\n" --dry-run=client -o yaml | kubectl apply -f -
echo -e "----------------------------------------------------\n\n\n" kubectl apply -f manifest/charts/nginx
envsubst < $1 | kubectl apply -f -
}
apply_resource() { # deploy cert-manager
resource_name=$1 kubectl create namespace cert-manager \
wait_condition=$2 --dry-run=client -o yaml | kubectl apply -f -
deployment_file=$3 kubectl apply -f manifest/charts/cert-manager
for file in $(find $deployment_file -type f); do
apply_template $file
done
kubectl wait --for=$wait_condition \
--timeout=600s \
${resource_name} \
-n ${KUBE_NAMESPACE}
}
configure_nginx_minikube() { ### configures docker registry secret ###
if [[ $setup_minikube == "true" ]]; then if [[ -f $HOME/.docker/config.json ]]; then
minikube start --driver kvm2 --cpus 8 --memory 8Gib kubectl create secret generic regcred \
fi --from-file=.dockerconfigjson=$HOME/.docker/config.json \
--type=kubernetes.io/dockerconfigjson \
minikube addons enable ingress-dns --namespace=$NAMESPACE \
minikube addons enable ingress --dry-run=client -o yaml | kubectl apply -f -
}
configure_descheduler() {
helm repo add descheduler https://kubernetes-sigs.github.io/descheduler
helm upgrade --install descheduler descheduler/descheduler \
--namespace kube-system \
--set schedule="*/2 * * * *" \
--set successfulJobsHistoryLimit=1 \
--set failedJobsHistoryLimit=1
}
configure_nginx_ingress() {
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
}
configure_cert_manager() {
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
helm upgrade --install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.2 \
--set installCRDs=true \
--timeout=600s || echo "Cert Manager already installed"
}
configure_postgres_cluster() {
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm upgrade --install cnpg \
--namespace ${KUBE_NAMESPACE} \
--create-namespace \
cnpg/cloudnative-pg
kubectl wait --for=condition=available \
--timeout=600s \
deployment.apps/cnpg-cloudnative-pg \
-n ${KUBE_NAMESPACE}
}
configure_ingress() {
apply_template "./template/nginx-ingress/nginx-ingress-root.template.yaml"
if [[ $environment == "local" ]]; then
apply_template "./template/cert-manager/cert-manager-issuer-dev.yaml"
else else
apply_template "./template/cert-manager/cert-manager-issuer.yaml" echo "Docker config file not found at $HOME/.docker/config.json. Skipping registry secret creation."
fi
apply_template "./template/cert-manager/cert-manager-certificate.template.yaml"
}
deploy_kubernetes() {
if [[ $environment == "local" ]]; then
configure_nginx_minikube
else
configure_nginx_ingress
fi
configure_descheduler
configure_cert_manager
configure_postgres_cluster
KUBE_FILES=(
"./template/portfolio-namespace.template.yaml"
"./template/portfolio-secret.template.yml"
)
for file in ${KUBE_FILES[@]}; do
apply_template $file
done
apply_resource "cluster/postgres-cn-cluster" "condition=Ready" "./template/postgres"
apply_resource "deployment.apps/redis-deployment" "condition=available" "./template/redis"
apply_resource "deployment.apps/storage-deployment" "condition=available" "./template/storage"
apply_resource "deployment.apps/backend-deployment" "condition=available" "./template/backend"
apply_resource "deployment.apps/frontend-deployment" "condition=available" "./template/frontend"
configure_ingress
if [[ $environment == "local" ]]; then
echo "Minikube IP: http://$(minikube ip)"
fi
}
main() {
build_secret_envs
deploy_kubernetes $@
}
refresh() {
deployments=$1
if [[ -z $1 ]]; then
deployments=(
"redis-deployment"
"storage-deployment"
"backend-deployment"
"frontend-deployment"
)
fi
for deployment in ${deployments[@]}; do
kubectl rollout restart deployment/${deployment} -n ${KUBE_NAMESPACE}
done
}
environment="remote"
setup_minikube="false"
execution_mode="deploy"
while getopts ":f:e:mrh" opt; do
case ${opt} in
f )
echo "Reading env file: ${OPTARG}"
read_env_file ${OPTARG}
;;
e )
[[ ${OPTARG} == "local" ]] && environment="local"
echo "Environment: ${OPTARG}"
;;
m )
setup_minikube="true"
echo "Setting up minikube"
;;
h )
echo "Usage: deploy.sh [-f <env_file>] [-e <environment>] [-m <minikube>]"
exit 0
;;
r )
echo "Executing Refresh"
execution_mode="refresh"
eval nextopt=\${$OPTIND}
if [[ -n $nextopt && $nextopt != -* ]]; then
OPTIND=$((OPTIND + 1))
refresh_deployments=($nextopt)
fi
;;
*)
echo "Invalid option: $OPTARG"
exit 1
;;
esac
done
validate_dependencies
if [[ $execution_mode == "deploy" ]]; then
main
elif [[ $execution_mode == "refresh" ]]; then
[[ -z $refresh_deployments ]] && refresh || refresh $refresh_deployments
else
echo "Invalid execution mode: $execution_mode"
exit 1
fi fi

View File

@@ -0,0 +1,51 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: cert-manager
namespace: cert-manager
spec:
interval: 10m
releaseName: cert-manager
chart:
spec:
chart: cert-manager
version: "v1.14.2"
sourceRef:
kind: HelmRepository
name: jetstack
namespace: flux-system
install:
createNamespace: true
crds: CreateReplace
values:
resources:
limits:
cpu: 50m
memory: 128Mi
requests:
cpu: 25m
memory: 64Mi
webhook:
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi
cainjector:
resources:
limits:
cpu: 50m
memory: 128Mi
requests:
cpu: 25m
memory: 64Mi
startupapicheck:
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi

View File

@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: jetstack
namespace: flux-system
spec:
interval: 10m
url: https://charts.jetstack.io

View File

@@ -0,0 +1,39 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: descheduler
namespace: kube-system
spec:
interval: 10m
releaseName: descheduler
chart:
spec:
chart: descheduler
version: "*"
sourceRef:
kind: HelmRepository
name: descheduler
namespace: flux-system
values:
schedule: "*/2 * * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
# Security context
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true

View File

@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: descheduler
namespace: flux-system
spec:
interval: 10m
url: https://kubernetes-sigs.github.io/descheduler

View File

@@ -0,0 +1,44 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
interval: 10m
releaseName: ingress-nginx
chart:
spec:
chart: ingress-nginx
sourceRef:
kind: HelmRepository
name: ingress-nginx
namespace: flux-system
install:
createNamespace: true
values:
controller:
resources:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 125m
memory: 128Mi
# Enable metrics for monitoring
metrics:
enabled: true
serviceMonitor:
enabled: false # Set to true if you have Prometheus
# Security context
podSecurityContext:
runAsNonRoot: true
runAsUser: 101
fsGroup: 65534
defaultBackend:
resources:
limits:
cpu: 25m
memory: 32Mi
requests:
cpu: 12m
memory: 16Mi

View File

@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: ingress-nginx
namespace: flux-system
spec:
interval: 10m
url: https://kubernetes.github.io/ingress-nginx

118
manifest/flux-instance.yaml Normal file
View File

@@ -0,0 +1,118 @@
apiVersion: fluxcd.controlplane.io/v1
kind: FluxInstance
metadata:
name: flux
namespace: flux-system
annotations:
fluxcd.controlplane.io/reconcileEvery: "1h"
fluxcd.controlplane.io/reconcileTimeout: "5m"
spec:
distribution:
version: "2.x"
registry: "ghcr.io/fluxcd"
artifact: "oci://ghcr.io/controlplaneio-fluxcd/flux-operator-manifests"
components:
- source-controller
- kustomize-controller
- helm-controller
- notification-controller
- image-reflector-controller
- image-automation-controller
cluster:
type: kubernetes
size: medium
multitenant: false
networkPolicy: true
domain: "cluster.local"
kustomize:
patches:
- target:
kind: Deployment
patch: |
- op: replace
path: /spec/template/spec/nodeSelector
value:
kubernetes.io/os: linux
- op: add
path: /spec/template/spec/tolerations
value:
- key: "CriticalAddonsOnly"
operator: "Exists"
- target:
kind: Deployment
name: source-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 25m
memory: 32Mi
- target:
kind: Deployment
name: kustomize-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 50m
memory: 64Mi
- target:
kind: Deployment
name: helm-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 50m
memory: 64Mi
- target:
kind: Deployment
name: notification-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi
- target:
kind: Deployment
name: image-reflector-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi
- target:
kind: Deployment
name: image-automation-controller
patch: |
- op: add
path: /spec/template/spec/containers/0/resources
value:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi

View File

@@ -1,9 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ${KUBE_NAMESPACE}
name: backend-config
data:
backend_url: backend-service
backend_port: "8070"
backend_db_name: ${KUBE_DATABASE_NAME}

View File

@@ -1,217 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${KUBE_NAMESPACE}
name: backend-deployment
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
nodeSelector:
${WORKER_NODE_LABEL}
initContainers:
- name: wait-storage-init
image: busybox:latest
args:
- /bin/sh
- -c
- >
set -x;
while [ $(curl -sw '%{http_code}' "storage-service:8070/health" -o /dev/null) -ne 200 ]; do
sleep 15;
done
containers:
- name: backend
image: yoshiunfriendly/backend-hideyoshi.com
imagePullPolicy: Always
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "1000m"
ports:
- containerPort: 8070
readinessProbe:
httpGet:
path: /health
port: 8070
initialDelaySeconds: 60
livenessProbe:
httpGet:
path: /health
port: 8070
initialDelaySeconds: 60
env:
- name: FRONTEND_PATH
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendUrl
- name: TOKEN_SECRET
valueFrom:
secretKeyRef:
name: backend-secret
key: backendTokenSecret
- name: ACCESS_TOKEN_DURATION
valueFrom:
secretKeyRef:
name: backend-secret
key: backendAccessTokenDuration
- name: REFRESH_TOKEN_DURATION
valueFrom:
secretKeyRef:
name: backend-secret
key: backendRefreshTokenDuration
- name: DEFAULT_USER_FULLNAME
valueFrom:
secretKeyRef:
name: backend-secret
key: backendDefaultUserFullName
- name: DEFAULT_USER_EMAIL
valueFrom:
secretKeyRef:
name: backend-secret
key: backendDefaultUserEmail
- name: DEFAULT_USER_USERNAME
valueFrom:
secretKeyRef:
name: backend-secret
key: backendDefaultUserUsername
- name: DEFAULT_USER_PASSWORD
valueFrom:
secretKeyRef:
name: backend-secret
key: backendDefaultUserPassword
- name: PORT
valueFrom:
configMapKeyRef:
name: backend-config
key: backend_port
- name: GOOGLE_CLIENT_ID
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGoogleClientId
- name: GOOGLE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGoogleClientSecret
- name: GOOGLE_REDIRECT_URL
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGoogleRedirectUrl
- name: GITHUB_CLIENT_ID
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGithubClientId
- name: GITHUB_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGithubClientSecret
- name: GITHUB_REDIRECT_URL
valueFrom:
secretKeyRef:
name: backend-secret
key: backendGithubRedirectUrl
- name: POSTGRES_URL
valueFrom:
secretKeyRef:
name: postgres-cn-cluster-app
key: host
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgres-cn-cluster-app
key: dbname
- name: DATABASE_URL
value: "postgresql://$(POSTGRES_URL):5432/$(POSTGRES_DB)"
- name: DATABASE_USERNAME
valueFrom:
secretKeyRef:
name: postgres-cn-cluster-app
key: user
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-cn-cluster-app
key: password
- name: REDIS_URL
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-url
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-port
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redisPassword
- name: STORAGE_SERVICE_URL
valueFrom:
configMapKeyRef:
name: storage-config
key: storage_url
- name: STORAGE_SERVICE_PORT
valueFrom:
configMapKeyRef:
name: storage-config
key: storage_port
- name: STORAGE_SERVICE_PATH
value: "http://$(STORAGE_SERVICE_URL):$(STORAGE_SERVICE_PORT)"
---
apiVersion: v1
kind: Service
metadata:
namespace: ${KUBE_NAMESPACE}
name: backend-service
spec:
selector:
app: backend
ports:
- port: 8070
protocol: TCP
targetPort: 8070
type: ClusterIP

View File

@@ -1,16 +0,0 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: letsencrypt-cluster-certificate
namespace: ${KUBE_NAMESPACE}
spec:
dnsNames:
- ${KUBE_DOMAIN}
- ${KUBE_API_DOMAIN}
secretName: letsencrypt-cluster-certificate-tls
issuerRef:
name: cluster-certificate-issuer
kind: ClusterIssuer
subject:
organizations:
- ${KUBE_DOMAIN_ORGANIZATION}

View File

@@ -1,6 +0,0 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: cluster-certificate-issuer
spec:
selfSigned: {}

View File

@@ -1,14 +0,0 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: cluster-certificate-issuer
spec:
acme:
server: ${KUBE_CERT_SERVER}
email: ${KUBE_DOMAIN_EMAIL}
privateKeySecretRef:
name: cluster-certificate-issuer
solvers:
- http01:
ingress:
class: nginx

View File

@@ -1,30 +0,0 @@
apiVersion: "descheduler/v1alpha2"
kind: "DeschedulerPolicy"
profiles:
- name: default
pluginConfig:
- name: "RemoveDuplicates"
- name: "RemovePodsViolatingInterPodAntiAffinity"
- name: "LowNodeUtilization"
args:
thresholds:
"cpu": 55
"memory": 55
"pods": 2
targetThresholds:
"cpu": 60
"memory": 60
"pods": 3
- name: "RemovePodsHavingTooManyRestarts"
args:
podRestartThreshold: 100
includingInitContainers: true
plugins:
deschedule:
enabled:
- "RemovePodsViolatingInterPodAntiAffinity"
- "RemovePodsHavingTooManyRestarts"
balance:
enabled:
- "RemoveDuplicates"
- "LowNodeUtilization"

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ${KUBE_NAMESPACE}
name: frontend-config
data:
frontend_url: frontend-service

View File

@@ -1,86 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${KUBE_NAMESPACE}
name: frontend-deployment
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
nodeSelector:
${WORKER_NODE_LABEL}
initContainers:
- name: wait-backend-init
image: busybox:latest
args:
- /bin/sh
- -c
- >
set -x;
while [ $(curl -sw '%{http_code}' "backend-service:8000/health" -o /dev/null) -ne 200 ]; do
sleep 15;
done
containers:
- name: frontend
image: yoshiunfriendly/frontend-hideyoshi.com:latest
imagePullPolicy: "Always"
resources:
requests:
memory: "128Mi"
cpu: "75m"
limits:
memory: "128Mi"
cpu: "256m"
ports:
- containerPort: 5000
readinessProbe:
httpGet:
path: /
port: 5000
initialDelaySeconds: 10
livenessProbe:
httpGet:
path: /
port: 5000
initialDelaySeconds: 10
env:
- name: PORT
value: "5000"
- name: BACKEND_URL
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendBackendUrl
- name: BACKEND_OAUTH_URL
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendOAuthUrl
- name: GITHUB_USER
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendGithubUser
---
apiVersion: v1
kind: Service
metadata:
namespace: ${KUBE_NAMESPACE}
name: frontend-service
spec:
selector:
app: frontend
ports:
- port: 5000
protocol: TCP
targetPort: 5000
type: ClusterIP

View File

@@ -1,45 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: ${KUBE_NAMESPACE}
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- ${KUBE_DOMAIN}
- ${KUBE_API_DOMAIN}
secretName: letsencrypt-cluster-certificate-tls
rules:
- host: ${KUBE_DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 5000
- host: ${KUBE_API_DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8070
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 5000

View File

@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: ${KUBE_NAMESPACE}

View File

@@ -1,77 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: backend-secret
namespace: ${KUBE_NAMESPACE}
type: Opaque
data:
backendTokenSecret: ${KUBE_BACKEND_TOKEN_SECRET_B64}
backendAccessTokenDuration: ${KUBE_BACKEND_ACCESS_TOKEN_DURATION_B64}
backendRefreshTokenDuration: ${KUBE_BACKEND_REFRESH_TOKEN_DURATION_B64}
backendDefaultUserFullName: ${KUBE_BACKEND_DEFAULT_USER_FULL_NAME_B64}
backendDefaultUserEmail: ${KUBE_BACKEND_DEFAULT_USER_EMAIL_B64}
backendDefaultUserUsername: ${KUBE_BACKEND_DEFAULT_USER_USERNAME_B64}
backendDefaultUserPassword: ${KUBE_BACKEND_DEFAULT_USER_PASSWORD_B64}
backendGoogleClientId: ${KUBE_BACKEND_GOOGLE_CLIENT_ID_B64}
backendGoogleClientSecret: ${KUBE_BACKEND_GOOGLE_CLIENT_SECRET_B64}
backendGoogleRedirectUrl: ${KUBE_BACKEND_GOOGLE_REDIRECT_URL_B64}
backendGithubClientId: ${KUBE_BACKEND_GITHUB_CLIENT_ID_B64}
backendGithubClientSecret: ${KUBE_BACKEND_GITHUB_CLIENT_SECRET_B64}
backendGithubRedirectUrl: ${KUBE_BACKEND_GITHUB_REDIRECT_URL_B64}
---
apiVersion: v1
kind: Secret
metadata:
name: frontend-secret
namespace: ${KUBE_NAMESPACE}
type: Opaque
data:
frontendUrl: ${KUBE_FRONTEND_URL_B64}
frontendBackendUrl: ${KUBE_FRONTEND_BACKEND_URL_B64}
frontendOAuthUrl: ${KUBE_FRONTEND_OAUTH_URL_B64}
frontendGithubUser: ${KUBE_FRONTEND_GITHUB_USER_B64}
---
apiVersion: v1
kind: Secret
metadata:
name: database-secret
namespace: ${KUBE_NAMESPACE}
type: Opaque
data:
databaseName: ${KUBE_DATABASE_NAME_B64}
databaseUser: ${KUBE_DATABASE_USER_B64}
databasePassword: ${KUBE_DATABASE_PASSWORD_B64}
---
apiVersion: v1
kind: Secret
metadata:
name: redis-secret
namespace: ${KUBE_NAMESPACE}
type: Opaque
data:
redisPassword: ${KUBE_REDIS_PASSWORD_B64}
---
apiVersion: v1
kind: Secret
metadata:
name: storage-secret
namespace: ${KUBE_NAMESPACE}
type: Opaque
data:
storageType: ${KUBE_STORAGE_TYPE_B64}
storageAwsAccessKeyId: ${KUBE_STORAGE_AWS_ACCESS_KEY_ID_B64}
storageAwsSecretAccessKey: ${KUBE_STORAGE_AWS_SECRET_ACCESS_KEY_B64}
storageAwsRegion: ${KUBE_STORAGE_AWS_REGION_B64}
storageAwsBucket: ${KUBE_STORAGE_AWS_BUCKET_B64}
storageVirusCheckerType: ${KUBE_STORAGE_VIRUS_CHECKER_TYPE_B64}
storageVirusCheckerApiKey: ${KUBE_STORAGE_VIRUS_CHECKER_API_KEY_B64}

View File

@@ -1,27 +0,0 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres-cn-cluster
namespace: ${KUBE_NAMESPACE}
spec:
instances: 3
primaryUpdateStrategy: unsupervised
imageName: ghcr.io/cloudnative-pg/postgresql:14.10-18
storage:
size: 5Gi
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "256m"
affinity:
nodeSelector:
${WORKER_NODE_LABEL}
monitoring:
enablePodMonitor: true

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ${KUBE_NAMESPACE}
name: redis-config
data:
redis-url: redis-service
redis-port: "6379"

View File

@@ -1,47 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${KUBE_NAMESPACE}
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: bitnami/valkey:8.0.2
imagePullPolicy: "IfNotPresent"
resources:
requests:
memory: "256Mi"
cpu: "75m"
limits:
memory: "256Mi"
cpu: "256m"
ports:
- containerPort: 6379
env:
- name: VALKEY_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redisPassword
---
apiVersion: v1
kind: Service
metadata:
namespace: ${KUBE_NAMESPACE}
name: redis-service
spec:
selector:
app: redis
ports:
- port: 6379
type: ClusterIP

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ${KUBE_NAMESPACE}
name: storage-config
data:
storage_url: storage-service
storage_port: "8000"

View File

@@ -1,119 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${KUBE_NAMESPACE}
name: storage-processor-deployment
spec:
replicas: 1
selector:
matchLabels:
app: storage-processor
template:
metadata:
labels:
app: storage-processor
spec:
nodeSelector:
${WORKER_NODE_LABEL}
containers:
- name: storage-processor
image: yoshiunfriendly/storage-hideyoshi.com:latest
args: ["-q"]
imagePullPolicy: "Always"
resources:
requests:
memory: "128Mi"
cpu: "75m"
limits:
memory: "128Mi"
cpu: "256m"
readinessProbe:
exec:
command:
- touch
- /tmp/healthy
initialDelaySeconds: 30
livenessProbe:
exec:
command:
- touch
- /tmp/healthy
initialDelaySeconds: 30
env:
- name: ALLOWED_ORIGINS
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendBackendUrl
- name: EXPIRES_IN
valueFrom:
secretKeyRef:
name: backend-secret
key: backendAccessTokenDuration
- name: SERVER_PORT
valueFrom:
configMapKeyRef:
name: storage-config
key: storage_port
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-url
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-port
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redisPassword
- name: STORAGE_TYPE
valueFrom:
secretKeyRef:
name: storage-secret
key: storageType
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsAccessKeyId
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsSecretAccessKey
- name: AWS_REGION_NAME
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsRegion
- name: AWS_BUCKET_NAME
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsBucket
- name: VIRUS_CHECKER_TYPE
valueFrom:
secretKeyRef:
name: storage-secret
key: storageVirusCheckerType
- name: VIRUS_CHECKER_API_KEY
valueFrom:
secretKeyRef:
name: storage-secret
key: storageVirusCheckerApiKey

View File

@@ -1,133 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${KUBE_NAMESPACE}
name: storage-deployment
spec:
replicas: 1
selector:
matchLabels:
app: storage
template:
metadata:
labels:
app: storage
spec:
nodeSelector:
${WORKER_NODE_LABEL}
containers:
- name: storage
image: yoshiunfriendly/storage-hideyoshi.com:latest
imagePullPolicy: "Always"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "256m"
ports:
- containerPort: 8000
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
env:
- name: ALLOWED_ORIGINS
valueFrom:
secretKeyRef:
name: frontend-secret
key: frontendBackendUrl
- name: EXPIRES_IN
valueFrom:
secretKeyRef:
name: backend-secret
key: backendAccessTokenDuration
- name: SERVER_PORT
valueFrom:
configMapKeyRef:
name: storage-config
key: storage_port
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-url
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: redis-port
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redisPassword
- name: STORAGE_TYPE
valueFrom:
secretKeyRef:
name: storage-secret
key: storageType
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsAccessKeyId
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsSecretAccessKey
- name: AWS_REGION_NAME
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsRegion
- name: AWS_BUCKET_NAME
valueFrom:
secretKeyRef:
name: storage-secret
key: storageAwsBucket
- name: VIRUS_CHECKER_TYPE
valueFrom:
secretKeyRef:
name: storage-secret
key: storageVirusCheckerType
- name: VIRUS_CHECKER_API_KEY
valueFrom:
secretKeyRef:
name: storage-secret
key: storageVirusCheckerApiKey
---
apiVersion: v1
kind: Service
metadata:
namespace: ${KUBE_NAMESPACE}
name: storage-service
spec:
selector:
app: storage
ports:
- port: 8000
protocol: TCP
targetPort: 8000
type: ClusterIP