Skip to content

Commit cf6fbee

Browse files
committed
Add a jinja template
1 parent 47fe19a commit cf6fbee

3 files changed

Lines changed: 370 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# This is the name of your GitHub Actions workflow.
2+
name: Build and Push Docker Images
3+
4+
# This workflow triggers automatically whenever you push code to the 'main' branch.
5+
on:
6+
push:
7+
branches: [ "main" ]
8+
9+
# This section defines the jobs that will run.
10+
jobs:
11+
# --- JOB 1: Build and push the Backend Image ---
12+
build-and-push-backend:
13+
# This job runs on a fresh Ubuntu virtual machine provided by GitHub.
14+
runs-on: ubuntu-latest
15+
steps:
16+
# Step 1: Check out your repository's code so the workflow can access it.
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
# Step 2: Set up Docker Buildx for better build features.
21+
- name: Set up Docker Buildx
22+
uses: docker/setup-buildx-action@v3
23+
24+
# Step 3: Log in to Docker Hub using the secrets you created.
25+
- name: Login to Docker Hub
26+
uses: docker/login-action@v3
27+
with:
28+
username: ${{ secrets.DOCKERHUB_USERNAME }}
29+
password: ${{ secrets.DOCKERHUB_TOKEN }}
30+
31+
# Step 4: Extract metadata for the Docker image, including tags.
32+
# We will tag the image with the unique Git SHA and 'latest'.
33+
- name: Extract Docker metadata
34+
id: meta-backend
35+
uses: docker/metadata-action@v5
36+
with:
37+
images: ${{ secrets.DOCKERHUB_USERNAME }}/todo-backend
38+
39+
# Step 5: Build and push the Docker image to Docker Hub.
40+
- name: Build and push backend image
41+
uses: docker/build-push-action@v5
42+
with:
43+
context: ./go-todo-backend # The directory where the backend's Dockerfile is located
44+
push: true
45+
tags: ${{ steps.meta-backend.outputs.tags }}
46+
labels: ${{ steps.meta-backend.outputs.labels }}
47+
48+
# --- JOB 2: Build and push the Frontend Image ---
49+
build-and-push-frontend:
50+
# This job runs independently and in parallel with the backend job.
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Checkout repository
54+
uses: actions/checkout@v4
55+
56+
- name: Set up Docker Buildx
57+
uses: docker/setup-buildx-action@v3
58+
59+
- name: Login to Docker Hub
60+
uses: docker/login-action@v3
61+
with:
62+
username: ${{ secrets.DOCKERHUB_USERNAME }}
63+
password: ${{ secrets.DOCKERHUB_TOKEN }}
64+
65+
- name: Extract Docker metadata
66+
id: meta-frontend
67+
uses: docker/metadata-action@v5
68+
with:
69+
images: ${{ secrets.DOCKERHUB_USERNAME }}/todo-frontend
70+
71+
- name: Build and push frontend image
72+
uses: docker/build-push-action@v5
73+
with:
74+
context: ./go-todo-frontend # The directory for the frontend's Dockerfile
75+
push: true
76+
tags: ${{ steps.meta-frontend.outputs.tags }}
77+
labels: ${{ steps.meta-frontend.outputs.labels }}

kubernetes.yml

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# ==========================================================
2+
# FINAL RENDERED KUBERNETES MANIFEST
3+
# This file contains all the resources for the To-Do application.
4+
# You can apply this single file directly with kubectl.
5+
# ==========================================================
6+
7+
# --- Backend Service ---
8+
# This creates a stable internal DNS name 'todo-backend-service'
9+
# so the Ingress can find the backend pods.
10+
apiVersion: v1
11+
kind: Service
12+
metadata:
13+
name: todo-backend-service
14+
spec:
15+
selector:
16+
# This selector must match the labels on the backend pods
17+
app: todo-backend
18+
ports:
19+
- protocol: TCP
20+
port: 8080
21+
targetPort: 8080
22+
---
23+
# --- Backend Deployment ---
24+
# This manages the running pods for your Go backend application.
25+
apiVersion: apps/v1
26+
kind: Deployment
27+
metadata:
28+
name: todo-backend-deployment
29+
spec:
30+
replicas: 1
31+
selector:
32+
matchLabels:
33+
app: todo-backend
34+
template:
35+
metadata:
36+
# This label is used by the Service's selector to find this pod
37+
labels:
38+
app: todo-backend
39+
spec:
40+
containers:
41+
- name: todo-backend-container
42+
image: docker0y4sh/todo-backend:latest
43+
imagePullPolicy: Always
44+
ports:
45+
- containerPort: 8080
46+
---
47+
# --- Frontend Service ---
48+
# This creates a stable internal DNS name 'todo-frontend-service'
49+
# so the Ingress can find the frontend pods.
50+
apiVersion: v1
51+
kind: Service
52+
metadata:
53+
name: todo-frontend-service
54+
spec:
55+
selector:
56+
# This selector must match the labels on the frontend pods
57+
app: todo-frontend
58+
ports:
59+
- protocol: TCP
60+
port: 80
61+
targetPort: 80
62+
---
63+
# --- Frontend Deployment ---
64+
# This manages the running pods for your Svelte/Nginx frontend.
65+
apiVersion: apps/v1
66+
kind: Deployment
67+
metadata:
68+
name: todo-frontend-deployment
69+
spec:
70+
replicas: 1
71+
selector:
72+
matchLabels:
73+
app: todo-frontend
74+
template:
75+
metadata:
76+
# This label is used by the Service's selector to find this pod
77+
labels:
78+
app: todo-frontend
79+
spec:
80+
containers:
81+
- name: todo-frontend-container
82+
image: docker0y4sh/todo-frontend:latest
83+
imagePullPolicy: Always
84+
ports:
85+
- containerPort: 80
86+
---
87+
# --- Ingress ---
88+
# This is the main entry point. It directs traffic based on the URL path.
89+
# This version is configured for direct IP access (no domain name).
90+
apiVersion: networking.k8s.io/v1
91+
kind: Ingress
92+
metadata:
93+
name: todo-app-ingress
94+
spec:
95+
rules:
96+
- http:
97+
paths:
98+
# Rule 1: If the path starts with /api...
99+
- path: /api
100+
pathType: Prefix
101+
backend:
102+
service:
103+
# ...send traffic to the backend service on its port.
104+
name: todo-backend-service
105+
port:
106+
number: 8080
107+
# Rule 2: For all other paths (/)...
108+
- path: /
109+
pathType: Prefix
110+
backend:
111+
service:
112+
# ...send traffic to the frontend service on its port.
113+
name: todo-frontend-service
114+
port:
115+
number: 80

kubernetes/app.j2

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
{#
2+
=======================================================================
3+
MASTER TEMPLATE for Frontend + Backend Application
4+
=======================================================================
5+
This single file contains all Kubernetes resources for the application.
6+
7+
### HOW TO USE ###
8+
1. Edit the variables in the "CONFIGURATION" section below.
9+
2. Generate the final YAML with: j2 app.j2 > kubernetes.yml
10+
3. Deploy with: kubectl apply -f kubernetes.yml
11+
=======================================================================
12+
#}
13+
14+
{# --- CONFIGURATION SECTION --- #}
15+
{# Edit the values in this section to configure your deployment. #}
16+
17+
{% set backend = {
18+
"name": "todo-backend",
19+
"replicas": 1,
20+
"image": {
21+
"repository": "docker0y4sh/todo-backend",
22+
"tag": "latest"
23+
},
24+
"containerPort": 8080,
25+
"resources": {
26+
"requests": { "memory": "128Mi", "cpu": "100m" },
27+
"limits": { "memory": "256Mi", "cpu": "250m" }
28+
}
29+
} %}
30+
31+
{% set frontend = {
32+
"name": "todo-frontend",
33+
"replicas": 1,
34+
"image": {
35+
"repository": "docker0y4sh/todo-frontend",
36+
"tag": "latest"
37+
},
38+
"containerPort": 80,
39+
"resources": {
40+
"requests": { "memory": "32Mi", "cpu": "50m" },
41+
"limits": { "memory": "64Mi", "cpu": "100m" }
42+
}
43+
} %}
44+
45+
{# -- Shared Ingress Configuration -- #}
46+
{% set ingress = {
47+
"host": "toptodoapp.tech",
48+
"className": "nginx",
49+
"tlsSecretName": "toptodoapp-tls-secret",
50+
"issuerName": "letsencrypt-staging"
51+
} %}
52+
53+
{# --- END OF CONFIGURATION --- #}
54+
55+
56+
# ==========================================================
57+
# Kubernetes Resources (Generated from the config above)
58+
# ==========================================================
59+
60+
# --- Backend Service ---
61+
apiVersion: v1
62+
kind: Service
63+
metadata:
64+
name: {{ backend.name }}-service
65+
spec:
66+
selector:
67+
app: {{ backend.name }}
68+
ports:
69+
- protocol: TCP
70+
port: {{ backend.containerPort }}
71+
targetPort: {{ backend.containerPort }}
72+
---
73+
# --- Backend Deployment ---
74+
apiVersion: apps/v1
75+
kind: Deployment
76+
metadata:
77+
name: {{ backend.name }}-deployment
78+
spec:
79+
replicas: {{ backend.replicas }}
80+
selector:
81+
matchLabels:
82+
app: {{ backend.name }}
83+
template:
84+
metadata:
85+
labels:
86+
app: {{ backend.name }}
87+
spec:
88+
containers:
89+
- name: {{ backend.name }}-container
90+
image: "{{ backend.image.repository }}:{{ backend.image.tag }}"
91+
imagePullPolicy: Always
92+
ports:
93+
- containerPort: {{ backend.containerPort }}
94+
# Add env vars for database connection here if needed
95+
resources:
96+
requests:
97+
memory: "{{ backend.resources.requests.memory }}"
98+
cpu: "{{ backend.resources.requests.cpu }}"
99+
limits:
100+
memory: "{{ backend.resources.limits.memory }}"
101+
cpu: "{{ backend.resources.limits.cpu }}"
102+
---
103+
# --- Frontend Service ---
104+
apiVersion: v1
105+
kind: Service
106+
metadata:
107+
name: {{ frontend.name }}-service
108+
spec:
109+
selector:
110+
app: {{ frontend.name }}
111+
ports:
112+
- protocol: TCP
113+
port: {{ frontend.containerPort }}
114+
targetPort: {{ frontend.containerPort }}
115+
---
116+
# --- Frontend Deployment ---
117+
apiVersion: apps/v1
118+
kind: Deployment
119+
metadata:
120+
name: {{ frontend.name }}-deployment
121+
spec:
122+
replicas: {{ frontend.replicas }}
123+
selector:
124+
matchLabels:
125+
app: {{ frontend.name }}
126+
template:
127+
metadata:
128+
labels:
129+
app: {{ frontend.name }}
130+
spec:
131+
containers:
132+
- name: {{ frontend.name }}-container
133+
image: "{{ frontend.image.repository }}:{{ frontend.image.tag }}"
134+
imagePullPolicy: Always
135+
ports:
136+
- containerPort: {{ frontend.containerPort }}
137+
resources:
138+
requests:
139+
memory: "{{ frontend.resources.requests.memory }}"
140+
cpu: "{{ frontend.resources.requests.cpu }}"
141+
limits:
142+
memory: "{{ frontend.resources.limits.memory }}"
143+
cpu: "{{ frontend.resources.limits.cpu }}"
144+
---
145+
# --- Ingress ---
146+
# This single Ingress directs traffic to both services.
147+
apiVersion: networking.k8s.io/v1
148+
kind: Ingress
149+
metadata:
150+
name: toptodoapp-ingress
151+
annotations:
152+
cert-manager.io/cluster-issuer: {{ ingress.issuerName }}
153+
spec:
154+
ingressClassName: {{ ingress.className }}
155+
tls:
156+
- hosts:
157+
- {{ ingress.host }}
158+
secretName: {{ ingress.tlsSecretName }}
159+
rules:
160+
- host: {{ ingress.host }}
161+
http:
162+
paths:
163+
# Path for the API backend
164+
- path: /api
165+
pathType: Prefix
166+
backend:
167+
service:
168+
name: {{ backend.name }}-service
169+
port:
170+
number: {{ backend.containerPort }}
171+
# Default path for the frontend
172+
- path: /
173+
pathType: Prefix
174+
backend:
175+
service:
176+
name: {{ frontend.name }}-service
177+
port:
178+
number: {{ frontend.containerPort }}

0 commit comments

Comments
 (0)