diff --git a/app-running.jpg b/app-running.jpg new file mode 100644 index 000000000..7db4cbfef Binary files /dev/null and b/app-running.jpg differ diff --git a/exam-code/docker/be/Dockerfile b/exam-code/docker/be/Dockerfile index 437b49676..9becf475f 100644 --- a/exam-code/docker/be/Dockerfile +++ b/exam-code/docker/be/Dockerfile @@ -1,13 +1,13 @@ # Dockerfile for Backend Service FROM python:3.12-slim +WORKDIR /app - - +COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt +COPY src ./src +EXPOSE 5001 -CMD ["python", "main.py"] - -EXPOSE 5001 \ No newline at end of file +CMD ["python", "src/main.py"] \ No newline at end of file diff --git a/exam-code/docker/docker-compose.yaml b/exam-code/docker/docker-compose.yaml index b24a323d7..41cea6681 100644 --- a/exam-code/docker/docker-compose.yaml +++ b/exam-code/docker/docker-compose.yaml @@ -1,9 +1,36 @@ services: web: - + build: + context: ./fe + ports: + - "5002:5002" + depends_on: + - backend-service + networks: + - app-net backend-service: - + build: + context: ./be + ports: + - "5001:5001" + environment: + MYSQL_HOST: ${MYSQL_HOST} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + depends_on: + - mysqldb + networks: + - app-net mysqldb: - \ No newline at end of file + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + networks: + - app-net + +networks: + app-net: + driver: bridge \ No newline at end of file diff --git a/exam-code/docker/fe/Dockerfile b/exam-code/docker/fe/Dockerfile index f1bf7bc1d..e7e4671c2 100644 --- a/exam-code/docker/fe/Dockerfile +++ b/exam-code/docker/fe/Dockerfile @@ -1,12 +1,13 @@ # Dockerfile for Frontend Service FROM python:3.12-slim +WORKDIR /app - - +COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt +COPY src ./src +EXPOSE 5002 -CMD ["python", "main.py"] - +CMD ["python", "src/main.py"] diff --git a/exam-code/helm/backend/Chart.yaml b/exam-code/helm/backend/Chart.yaml new file mode 100644 index 000000000..e78604192 --- /dev/null +++ b/exam-code/helm/backend/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: backend +description: Helm chart for the backend service +type: application +version: 0.1.0 +appVersion: "1.0" diff --git a/exam-code/helm/backend/templates/_helpers.tpl b/exam-code/helm/backend/templates/_helpers.tpl new file mode 100644 index 000000000..adefb2627 --- /dev/null +++ b/exam-code/helm/backend/templates/_helpers.tpl @@ -0,0 +1,11 @@ +{{- define "backend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "backend.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name (include "backend.name" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/exam-code/helm/backend/templates/deployment.yaml b/exam-code/helm/backend/templates/deployment.yaml new file mode 100644 index 000000000..eae38630c --- /dev/null +++ b/exam-code/helm/backend/templates/deployment.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backend.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - name: backend + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.containerPort }} + env: + - name: MYSQL_HOST + value: {{ .Values.mysql.host | quote }} + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_USER + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_PASSWORD + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_DATABASE diff --git a/exam-code/helm/backend/templates/secret.yaml b/exam-code/helm/backend/templates/secret.yaml new file mode 100644 index 000000000..50cc7170b --- /dev/null +++ b/exam-code/helm/backend/templates/secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + labels: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +type: Opaque +stringData: + MYSQL_USER: {{ .Values.mysql.user | quote }} + MYSQL_PASSWORD: {{ .Values.mysql.password | quote }} + MYSQL_DATABASE: {{ .Values.mysql.database | quote }} diff --git a/exam-code/helm/backend/templates/service.yaml b/exam-code/helm/backend/templates/service.yaml new file mode 100644 index 000000000..0c51d4216 --- /dev/null +++ b/exam-code/helm/backend/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "backend.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + type: {{ .Values.service.type }} + selector: + app.kubernetes.io/name: {{ include "backend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.containerPort }} diff --git a/exam-code/helm/backend/values.yaml b/exam-code/helm/backend/values.yaml new file mode 100644 index 000000000..2c2417839 --- /dev/null +++ b/exam-code/helm/backend/values.yaml @@ -0,0 +1,24 @@ +# Number of backend replicas. +replicaCount: 2 + +image: + repository: be + tag: latest + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 5001 + +containerPort: 5001 + +# Database connection info and credentials for the backend secret. +mysql: + host: mysqldb + user: "CHANGE_ME" + password: "CHANGE_ME" + database: "CHANGE_ME" + +# Name of the secret created for backend DB credentials. +secret: + name: backend-secrets diff --git a/exam-code/helm/frontend/Chart.yaml b/exam-code/helm/frontend/Chart.yaml new file mode 100644 index 000000000..96077e4aa --- /dev/null +++ b/exam-code/helm/frontend/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: frontend +description: Helm chart for the frontend service +type: application +version: 0.1.0 +appVersion: "1.0" diff --git a/exam-code/helm/frontend/templates/_helpers.tpl b/exam-code/helm/frontend/templates/_helpers.tpl new file mode 100644 index 000000000..1b73490f6 --- /dev/null +++ b/exam-code/helm/frontend/templates/_helpers.tpl @@ -0,0 +1,11 @@ +{{- define "frontend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "frontend.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name (include "frontend.name" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/exam-code/helm/frontend/templates/deployment.yaml b/exam-code/helm/frontend/templates/deployment.yaml new file mode 100644 index 000000000..ddf2e59b5 --- /dev/null +++ b/exam-code/helm/frontend/templates/deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "frontend.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "frontend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "frontend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "frontend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - name: frontend + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.containerPort }} diff --git a/exam-code/helm/frontend/templates/service.yaml b/exam-code/helm/frontend/templates/service.yaml new file mode 100644 index 000000000..0b2510a25 --- /dev/null +++ b/exam-code/helm/frontend/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "frontend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + type: {{ .Values.service.type }} + selector: + app.kubernetes.io/name: {{ include "frontend.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.containerPort }} diff --git a/exam-code/helm/frontend/values.yaml b/exam-code/helm/frontend/values.yaml new file mode 100644 index 000000000..a8d92ee30 --- /dev/null +++ b/exam-code/helm/frontend/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 2 + +image: + repository: fe + tag: latest + pullPolicy: IfNotPresent + +service: + type: LoadBalancer + port: 5002 + +containerPort: 5002 diff --git a/exam-code/helm/mysql/Chart.yaml b/exam-code/helm/mysql/Chart.yaml new file mode 100644 index 000000000..bd8105759 --- /dev/null +++ b/exam-code/helm/mysql/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: mysql +description: Helm chart for the MySQL database +type: application +version: 0.1.0 +appVersion: "5.7" diff --git a/exam-code/helm/mysql/templates/_helpers.tpl b/exam-code/helm/mysql/templates/_helpers.tpl new file mode 100644 index 000000000..5a8c0744c --- /dev/null +++ b/exam-code/helm/mysql/templates/_helpers.tpl @@ -0,0 +1,11 @@ +{{- define "mysql.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "mysql.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name (include "mysql.name" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/exam-code/helm/mysql/templates/deployment.yaml b/exam-code/helm/mysql/templates/deployment.yaml new file mode 100644 index 000000000..b522d84fd --- /dev/null +++ b/exam-code/helm/mysql/templates/deployment.yaml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mysql.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - name: mysql + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.containerPort }} + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_ROOT_PASSWORD + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_DATABASE + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_USER + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.secret.name }} + key: MYSQL_PASSWORD diff --git a/exam-code/helm/mysql/templates/secret.yaml b/exam-code/helm/mysql/templates/secret.yaml new file mode 100644 index 000000000..463eccca2 --- /dev/null +++ b/exam-code/helm/mysql/templates/secret.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name }} + labels: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +type: Opaque +stringData: + MYSQL_ROOT_PASSWORD: {{ .Values.auth.rootPassword | quote }} + MYSQL_DATABASE: {{ .Values.auth.database | quote }} + MYSQL_USER: {{ .Values.auth.user | quote }} + MYSQL_PASSWORD: {{ .Values.auth.password | quote }} diff --git a/exam-code/helm/mysql/templates/service.yaml b/exam-code/helm/mysql/templates/service.yaml new file mode 100644 index 000000000..d579afba6 --- /dev/null +++ b/exam-code/helm/mysql/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mysql.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + type: {{ .Values.service.type }} + selector: + app.kubernetes.io/name: {{ include "mysql.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.containerPort }} diff --git a/exam-code/helm/mysql/values.yaml b/exam-code/helm/mysql/values.yaml new file mode 100644 index 000000000..528a233b9 --- /dev/null +++ b/exam-code/helm/mysql/values.yaml @@ -0,0 +1,24 @@ +# Number of mysql replicas. +replicaCount: 1 + +image: + repository: mysql + tag: "5.7" + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 3306 + +containerPort: 3306 + +# Database credentials for the mysql secret. +auth: + rootPassword: "CHANGE_ME" + database: "CHANGE_ME" + user: "CHANGE_ME" + password: "CHANGE_ME" + +# Name of the secret created for mysql credentials. +secret: + name: mysql-secrets diff --git a/exam-code/k8s/app.yaml b/exam-code/k8s/app.yaml new file mode 100644 index 000000000..0fc1c1c6b --- /dev/null +++ b/exam-code/k8s/app.yaml @@ -0,0 +1,121 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: frontend +spec: + replicas: 2 + selector: + matchLabels: + app: frontend + template: + metadata: + labels: + app: frontend + spec: + containers: + - name: frontend + image: fe:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5002 +--- +apiVersion: v1 +kind: Service +metadata: + name: frontend +spec: + type: LoadBalancer + selector: + app: frontend + ports: + - port: 5002 + targetPort: 5002 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-service +spec: + replicas: 2 + selector: + matchLabels: + app: backend-service + template: + metadata: + labels: + app: backend-service + spec: + containers: + - name: backend-service + image: be:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5001 + env: + - name: MYSQL_HOST + value: mysqldb + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: app-secrets + key: MYSQL_USER + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: app-secrets + key: MYSQL_PASSWORD +--- +apiVersion: v1 +kind: Service +metadata: + name: backend-service +spec: + type: ClusterIP + selector: + app: backend-service + ports: + - port: 5001 + targetPort: 5001 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysqldb +spec: + replicas: 1 + selector: + matchLabels: + app: mysqldb + template: + metadata: + labels: + app: mysqldb + spec: + containers: + - name: mysqldb + image: mysql:5.7 + ports: + - containerPort: 3306 + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: app-secrets + key: MYSQL_ROOT_PASSWORD + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: app-secrets + key: MYSQL_DATABASE +--- +apiVersion: v1 +kind: Service +metadata: + name: mysqldb +spec: + type: ClusterIP + selector: + app: mysqldb + ports: + - port: 3306 + targetPort: 3306 diff --git a/exam-code/k8s/secret.yaml b/exam-code/k8s/secret.yaml new file mode 100644 index 000000000..bf9849940 --- /dev/null +++ b/exam-code/k8s/secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: app-secrets +type: Opaque +stringData: + MYSQL_USER: "CHANGE_ME" + MYSQL_PASSWORD: "CHANGE_ME" + MYSQL_DATABASE: "CHANGE_ME" + MYSQL_ROOT_PASSWORD: "CHANGE_ME" diff --git a/pods-svc.jpg b/pods-svc.jpg new file mode 100644 index 000000000..6673f6f0d Binary files /dev/null and b/pods-svc.jpg differ