You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- (or run pip install -r requirements.txt directly)
91
91
92
-
-**Run the App**
92
+
**2. Run the App**
93
93
```txt
94
94
make run
95
95
```
96
96
97
-
-**Flask app will start at:**
97
+
**3. Flask app will start at:**
98
98
```url
99
99
http://127.0.0.1:5000
100
100
```
@@ -104,7 +104,7 @@ With this we can able to:**
104
104
- /health → Health check
105
105
- /students → Manage students
106
106
107
-
-**Run all unit tests:**
107
+
**4. Run all unit tests:**
108
108
```txt
109
109
make test
110
110
```
@@ -123,9 +123,10 @@ With this we can able to:**
123
123
124
124
- Overall I managed to reduce the original `1.26GB` image to just `110MB`, achieving a `91.27%` size decrease while maintaining the same functionality and improving rebuild times by an average of 20 seconds.
125
125
126
-
#### Docker Commands
126
+
### Docker Commands
127
+
128
+
**1. Build the Docker Image:**
127
129
128
-
-**Build the Docker Image:**
129
130
- Built the image with semantic versioning tags:
130
131
```sh
131
132
make docker-build DOCKER_IMAGE_TAG=1.0.1
@@ -137,7 +138,7 @@ With this we can able to:**
137
138
```
138
139
- We can change the `DOCKER_IMAGE_TAG` to any version.
139
140
140
-
-**Run the Docker Container:**
141
+
**2. Run the Docker Container:**
141
142
- Run the container
142
143
```sh
143
144
make docker-run DOCKER_IMAGE_TAG=1.0.1
@@ -152,7 +153,7 @@ With this we can able to:**
152
153
http://localhost:5000
153
154
```
154
155
155
-
-**To Remove the Containers:**
156
+
**3. To Remove the Containers:**
156
157
- To remove the containers using make command
157
158
```sh
158
159
make docker-stop
@@ -165,7 +166,7 @@ With this we can able to:**
165
166
docker rm ${DOCKER_CONTAINER}
166
167
```
167
168
168
-
-**To Remove the unused images:**
169
+
**4. To Remove the unused images:**
169
170
- To remove the images using make command
170
171
```sh
171
172
make docker-clean
@@ -177,7 +178,7 @@ With this we can able to:**
177
178
docker rmi ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}
178
179
```
179
180
180
-
-**For Troubleshooting Container issue:**
181
+
**5. For Troubleshooting Container issue:**
181
182
- To check container logs using make command
182
183
```sh
183
184
make docker logs
@@ -190,11 +191,11 @@ With this we can able to:**
190
191
191
192
## One click local development setup
192
193
193
-
-Created docker-compose.yml file to containerise Flask (API) and Postgres (DB) together, with persistent volumes for one click local development setup.
194
+
**Created docker-compose.yml file to containerise Flask (API) and Postgres (DB) together, with persistent volumes for one click local development setup.**
194
195
195
196
### Docker Compose Commands
196
197
197
-
1. To start the service stack
198
+
**1. To start the service stack**
198
199
```sh
199
200
docker compose up -d --build
200
201
```
@@ -204,7 +205,7 @@ With this we can able to:**
204
205
make up
205
206
```
206
207
207
-
2. To stop and remove everything (including volumes)
208
+
**2. To stop and remove everything (including volumes)**
208
209
```sh
209
210
docker compose down -v
210
211
```
@@ -216,9 +217,9 @@ With this we can able to:**
216
217
```
217
218
218
219
### For Database Migration & Seeding
219
-
-After starting the containers, you need to run migrations (to create tables) and optionally seed data.
220
+
**After starting the containers, you need to run migrations (to create tables) and optionally seed data.**
220
221
221
-
1. Apply migrations inside the Flask container
222
+
**1. Apply migrations inside the Flask container**
222
223
```sh
223
224
docker exec -it flask-container flask db upgrade
224
225
```
@@ -229,7 +230,7 @@ With this we can able to:**
229
230
make migrate
230
231
```
231
232
232
-
2. To Seed the database with initial data
233
+
**2. To Seed the database with initial data**
233
234
```sh
234
235
docker exec -it flask-container python seed.py
235
236
```
@@ -240,7 +241,7 @@ With this we can able to:**
240
241
make seed
241
242
```
242
243
243
-
3. Verify Database
244
+
**3. Verify Database**
244
245
245
246
- To connect into the Postgres container
246
247
```sh
@@ -253,7 +254,7 @@ With this we can able to:**
253
254
SELECT*FROM students LIMIT5;
254
255
```
255
256
256
-
4. To Run API container (depends on DB + migrations + seed)
257
+
**4. To Run API container (depends on DB + migrations + seed)**
257
258
258
259
```txt
259
260
make run
@@ -266,3 +267,173 @@ With this we can able to:**
266
267
http://localhost:5000/students
267
268
268
269
http://localhost:5000/health
270
+
271
+
272
+
## Setup CI pipeline
273
+
274
+
**Automation for build, test, and publish of Docker images using GitHub Actions workflow for CI pipeline**
275
+
276
+
### pipeline stages
277
+
- Build API → make sure it compiles.
278
+
- Run tests → unit tests should pass.
279
+
- Lint → run flake8/pylint/eslint.
280
+
- Docker login → authenticate to registry (DockerHub/GHCR).
281
+
- Docker build & push → push tagged image.
282
+
283
+
### Triggering
284
+
285
+
- Automatically when changes are made inside /api/**.
286
+
- Manual trigger (workflow_dispatch).
287
+
288
+
### Self-hosted runner
289
+
- GitHub Actions running on our laptop/VM to simulate real-world self-hosted CI.
290
+
291
+
**At the end: "Every commit to main will test your code and publish a Docker image"**
292
+
293
+
## Deploy on Bare Metal
294
+
**To deploy on a “production-like” environment without Kubernetes — just Docker + Nginx on a Vagrant box.**
295
+
296
+
### Key Points
297
+
298
+
- Vagrantfile creates a VM (e.g., Ubuntu).
299
+
- A provisioning script installs Docker, Docker Compose, Nginx.
300
+
- docker-compose.yml deploys:
301
+
- 2 API containers (scale with replicas).
302
+
- 1 Postgres DB container.
303
+
- 1 Nginx container (load balances API replicas).
304
+
305
+
### Nginx config
306
+
307
+
```nginx
308
+
upstream api_backend {
309
+
server api1:5000;
310
+
server api2:5000;
311
+
}
312
+
server {
313
+
listen 8080;
314
+
location / {
315
+
proxy_pass http://api_backend;
316
+
}
317
+
}
318
+
```
319
+
-**Access API at http://localhost:8080/api/v1/students.**
320
+
-**At the end: "we’ll have a mini production setup with scaling + load balancing".**
321
+
322
+
## Setup Kubernetes Cluster
323
+
324
+
**Spin up a 3-node Kubernetes cluster with Minikube.**
325
+
326
+
### Key Points
327
+
328
+
-**Start minikube with 3 nodes:**
329
+
```sh
330
+
minikube start --nodes=3
331
+
```
332
+
333
+
-**Label nodes:**
334
+
- Node A → type=application
335
+
- Node B → type=database
336
+
- Node C → type=dependent_services
337
+
338
+
- This enforces workload isolation (apps on one node, DB on another, monitoring tools on another).
0 commit comments