Skip to content

Commit 7bd9735

Browse files
committed
making the interview
1 parent 6e5ee41 commit 7bd9735

17 files changed

Lines changed: 1175 additions & 0 deletions

File tree

.github/workflows/docker-image.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: read
10+
packages: write
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Log in to GitHub Container Registry
20+
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
21+
22+
- name: Build and push image
23+
run: |
24+
IMAGE_ID=ghcr.io/${{ github.repository }}
25+
IMAGE_ID=$(echo "$IMAGE_ID" | tr '[:upper:]' '[:lower:]')
26+
docker build -t "$IMAGE_ID:latest" .
27+
docker push "$IMAGE_ID:latest"

Dockerfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM astral/uv:python3.12-trixie
2+
3+
ENV PYTHONDONTWRITEBYTECODE=1 \
4+
PYTHONUNBUFFERED=1
5+
6+
WORKDIR /app
7+
8+
COPY pyproject.toml uv.lock README.md ./
9+
COPY src ./src
10+
11+
RUN uv sync --frozen --no-dev
12+
13+
COPY entrypoints ./entrypoints
14+
RUN chmod +x entrypoints/*.sh
15+
16+
ENV VIRTUAL_ENV=/app/.venv
17+
ENV PATH=/app/.venv/bin:$PATH
18+
ENV PYTHONPATH=/app/src
19+
20+
ENTRYPOINT ["/app/entrypoints/docker-entrypoint.sh"]
21+
CMD ["api"]

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
provision:
3+
minkube start
4+
find manifests -name '*.yaml' -print0 | xargs -0 -n1 kubectl apply -f

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
11
# devops-interview
2+
3+
## Setup
4+
5+
To start up the development environment, you will run `make provision`.
6+
7+
## Assignment
8+
Using the provided Docker image, write a Helm chart that deploys both the FastAPI server and Celery
9+
worker. The chart should launch:
10+
11+
- An API workload that runs the container with the `api` entrypoint (equivalent to `docker run <image> api`).
12+
- A worker workload that runs the container with the `celery` entrypoint (`docker run <image> celery`).
13+
14+
Your Helm definitions should set any required environment variables (Redis/Postgres details, queue
15+
names, etc.) and expose the FastAPI service appropriately.

entrypoints/api.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
exec uvicorn interview.api:app --host 0.0.0.0 --port 5000 --workers 2 "$@"

entrypoints/celery.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
exec celery -A interview.worker worker --concurrency 1 --queues default "$@"

entrypoints/docker-entrypoint.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
if [ $# -eq 0 ]; then
5+
set -- api
6+
fi
7+
8+
command="$1"
9+
shift || true
10+
11+
case "$command" in
12+
api)
13+
exec /app/entrypoints/api.sh "$@"
14+
;;
15+
celery)
16+
exec /app/entrypoints/celery.sh "$@"
17+
;;
18+
*)
19+
exec "$command" "$@"
20+
;;
21+
esac

manifests/postgres-init.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: postgres-page-views-table
5+
spec:
6+
template:
7+
spec:
8+
restartPolicy: OnFailure
9+
containers:
10+
- name: create-table
11+
image: postgres:16
12+
env:
13+
- name: PGPASSWORD
14+
value: tagup
15+
command:
16+
- /bin/sh
17+
- -c
18+
- |
19+
set -euo pipefail
20+
for i in $(seq 1 60); do
21+
if pg_isready --host=postgres --username=tagup --dbname=postgres; then
22+
break
23+
fi
24+
echo "Waiting for Postgres..."
25+
sleep 2
26+
done
27+
pg_isready --host=postgres --username=tagup --dbname=postgres
28+
psql \
29+
--host=postgres \
30+
--username=tagup \
31+
--dbname=postgres \
32+
--command="CREATE TABLE IF NOT EXISTS page_views (id BIGSERIAL PRIMARY KEY, time TIMESTAMPTZ NOT NULL, count INTEGER NOT NULL);"

manifests/postgres.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: postgres
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: postgres
10+
template:
11+
metadata:
12+
labels:
13+
app: postgres
14+
spec:
15+
containers:
16+
- name: postgres
17+
image: postgres:16
18+
env:
19+
- name: POSTGRES_USER
20+
value: tagup
21+
- name: POSTGRES_PASSWORD
22+
value: tagup
23+
ports:
24+
- containerPort: 5432
25+
---
26+
apiVersion: v1
27+
kind: Service
28+
metadata:
29+
name: postgres
30+
spec:
31+
selector:
32+
app: postgres
33+
ports:
34+
- port: 5432
35+
targetPort: 5432

manifests/rabbitmq.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: rabbitmq
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: rabbitmq
10+
template:
11+
metadata:
12+
labels:
13+
app: rabbitmq
14+
spec:
15+
containers:
16+
- name: rabbitmq
17+
image: rabbitmq:3
18+
env:
19+
- name: RABBITMQ_DEFAULT_USER
20+
value: tagup
21+
- name: RABBITMQ_DEFAULT_PASS
22+
value: tagup
23+
ports:
24+
- containerPort: 5672
25+
- containerPort: 15672
26+
---
27+
apiVersion: v1
28+
kind: Service
29+
metadata:
30+
name: rabbitmq
31+
spec:
32+
selector:
33+
app: rabbitmq
34+
ports:
35+
- name: amqp
36+
port: 5672
37+
targetPort: 5672
38+
- name: management
39+
port: 15672
40+
targetPort: 15672

0 commit comments

Comments
 (0)