Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/deploy-api-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Publish API server image to GHCR and deploys to Kubernetes Cluster

on:
push:
branches: [main]
paths:
- 'api-server/**'
release:
types: [published]
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/exosphere-api-server

jobs:
publish-image:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Generate tags & labels
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=sha,format=short
type=ref,event=tag # v1.2.3 → v1.2.3

- name: Build and push
uses: docker/build-push-action@v5
with:
context: ./api-server
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
26 changes: 26 additions & 0 deletions api-server/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*.pyo
*.pyd
*.so

# C extensions
*.egg
*.egg-info
.eggs

# Virtual environments
.venv/

# Git, CI and editor config
.git/
.github/
.vscode/

# Logs and temp files
*.log

# Other
.env
Dockerfile
14 changes: 14 additions & 0 deletions api-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM python:3.12-slim-bookworm
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /api-server

COPY pyproject.toml uv.lock ./

RUN uv sync --locked

COPY . .

EXPOSE 8000

CMD ["uv", "run", "run.py", "--mode", "production", "--workers", "4"]
3 changes: 1 addition & 2 deletions api-server/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ async def lifespan(app: FastAPI):
app.add_middleware(UnhandledExceptionsMiddleware)



@app.get("/health-check")
@app.get("/health")
def health() -> dict:
return {"message": "OK"}

Expand Down
12 changes: 12 additions & 0 deletions api-server/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '3.8'

services:
api-server:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
env_file:
- .env
command: ["uv", "run", "run.py", "--mode", "production", "--workers", "2"]
41 changes: 41 additions & 0 deletions k8s/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: exosphere-api-server
spec:
replicas: 2
selector:
matchLabels:
app: exosphere-api-server
template:
metadata:
labels:
app: exosphere-api-server
spec:
containers:
- name: exosphere-api-server
image: ghcr.io/exospherehost/exosphere-api-server:latest
ports:
- containerPort: 8000
envFrom:
- secretRef:
name: exosphere-api-server-secrets
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
10 changes: 10 additions & 0 deletions k8s/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: exosphere-api-server
spec:
selector:
app: exosphere-api-server
ports:
- port: 8000
targetPort: 8000