Skip to content

Commit 92013e2

Browse files
committed
Merge branch 'add-deployment' into dev
2 parents 25a7b84 + dbfe2e3 commit 92013e2

File tree

12 files changed

+699
-2
lines changed

12 files changed

+699
-2
lines changed

deployment/Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ── Stage 1: build ────────────────────────────────────────────────────────────
2+
# Needs both Node.js (Docusaurus) and Python/uv (prebuild step builds the
3+
# sumstatlib wheel and stages the web validator into static/).
4+
FROM node:22-slim AS builder
5+
6+
RUN apt-get update \
7+
&& apt-get install -y --no-install-recommends python3 curl ca-certificates \
8+
&& apt-get clean \
9+
&& rm -rf /var/lib/apt/lists/*
10+
11+
# Install uv (required by the prebuild script)
12+
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
13+
ENV PATH="/root/.local/bin:$PATH"
14+
15+
WORKDIR /app
16+
17+
# Copy workspace configuration and Python source required by uv build
18+
COPY pyproject.toml ./
19+
COPY README.md ./
20+
COPY sumstatlib/ ./sumstatlib/
21+
COPY src/ ./src/
22+
23+
# Copy the Docusaurus site
24+
COPY docs/ ./docs/
25+
26+
# Install Node dependencies
27+
WORKDIR /app/docs
28+
RUN npm ci
29+
30+
# prebuild: builds the sumstatlib wheel and stages the web validator
31+
# build: runs Docusaurus; output lands in /app/docs/build/
32+
RUN npm run build
33+
34+
# ── Stage 2: serve ────────────────────────────────────────────────────────────
35+
FROM nginx:alpine AS server
36+
37+
# Place the built site under the production base path so asset URLs resolve
38+
COPY --from=builder /app/docs/build /usr/share/nginx/html/gwas/apps/beyond-snps
39+
40+
COPY deployment/nginx.conf /etc/nginx/conf.d/default.conf
41+
42+
EXPOSE 80

deployment/helm/Chart.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: v1
2+
appVersion: "1.0"
3+
description: A Helm chart for Kubernetes
4+
name: gwas-beyond-snps
5+
version: 0.1.0
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ .Values.service.name }}
5+
labels:
6+
app: {{ .Values.service.name }}
7+
spec:
8+
replicas: {{ .Values.replicaCount }}
9+
selector:
10+
matchLabels:
11+
app: {{ .Values.service.name }}
12+
template:
13+
metadata:
14+
labels:
15+
app: {{ .Values.service.name }}
16+
spec:
17+
containers:
18+
- name: {{ .Values.service.name }}
19+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
20+
imagePullPolicy: {{ .Values.image.pullPolicy }}
21+
ports:
22+
- containerPort: 80
23+
livenessProbe:
24+
httpGet:
25+
path: /
26+
port: 80
27+
readinessProbe:
28+
httpGet:
29+
path: /
30+
port: 80
31+
resources:
32+
requests:
33+
cpu: {{ .Values.resources.requests.cpu }}
34+
memory: {{ .Values.resources.requests.memory }}
35+
limits:
36+
cpu: {{ .Values.resources.limits.cpu }}
37+
memory: {{ .Values.resources.limits.memory }}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: extensions/v1beta1
2+
kind: Ingress
3+
metadata:
4+
name: {{.Values.ingress.name}}
5+
annotations:
6+
nginx.ingress.kubernetes.io/rewrite-target: /gwas/apps/beyond-snps/$2
7+
nginx.ingress.kubernetes.io/ssl-redirect: "false"
8+
spec:
9+
rules:
10+
- http:
11+
paths:
12+
- path: {{.Values.ingress.path}}
13+
backend:
14+
serviceName: {{.Values.service.name}}
15+
servicePort: {{.Values.service.port}}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: {{ .Values.service.name }}
5+
spec:
6+
type: ClusterIP
7+
selector:
8+
app: {{ .Values.service.name }}
9+
ports:
10+
- port: {{ .Values.service.port }}

deployment/helm/values.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
replicaCount: 1
3+
4+
image:
5+
repository: dockerhub.ebi.ac.uk/gwas/gwas-beyond-snps
6+
tag: dev
7+
pullPolicy: Always
8+
9+
service:
10+
name: gwas-beyond-snps
11+
port: 80
12+
13+
ingress:
14+
name: beyond-snp-ingress
15+
annotations: {}
16+
path: "/apps/beyond-snps(/|$)(.*)"
17+
18+
resources:
19+
limits:
20+
cpu: 250m
21+
memory: 128Mi
22+
requests:
23+
cpu: 100m
24+
memory: 64Mi

deployment/nginx.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
server {
2+
listen 80;
3+
server_name _;
4+
5+
root /usr/share/nginx/html;
6+
index index.html;
7+
8+
# Keep redirects as path-only so the port is preserved when running behind
9+
# a non-standard port (e.g. docker run -p 8000:80).
10+
absolute_redirect off;
11+
12+
# Redirect bare root to the site base path
13+
location = / {
14+
return 301 /gwas/apps/beyond-snps/;
15+
}
16+
17+
# Serve the Docusaurus site.
18+
# try_files order: exact file → directory index → .html extension → 404 page.
19+
location /gwas/apps/beyond-snps/ {
20+
try_files $uri $uri/ $uri.html /gwas/apps/beyond-snps/404.html;
21+
}
22+
}

noxfile.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# /// script
2+
# dependencies = ["nox"]
3+
# ///
4+
import os
5+
16
import nox
27

38
# Use uv for environment creation and package installation
@@ -77,3 +82,35 @@ def lint(session):
7782

7883
# Type checking
7984
session.run("ty", "check", "src", "sumstatlib/src")
85+
86+
87+
@nox.session(default=False)
88+
def build_docker(session):
89+
"""Build an image with a Docker V2 manifest (not OCI)"""
90+
try:
91+
tag = session.posargs[0]
92+
except IndexError:
93+
raise RuntimeError(
94+
"Tag must be provided as a command-line argument"
95+
" e.g. nox -s build_docker -- dev"
96+
)
97+
98+
os.environ["BUILDKIT_OCI_MEDIA_TYPES"] = "0"
99+
session.run(
100+
"docker",
101+
"build",
102+
"--platform",
103+
"linux/amd64",
104+
"--provenance=false",
105+
"--push",
106+
"-t",
107+
f"dockerhub.ebi.ac.uk/gwas/gwas-beyond-snps:{tag}",
108+
"-f",
109+
"deployment/Dockerfile",
110+
".",
111+
external=True,
112+
)
113+
114+
115+
if __name__ == "__main__":
116+
nox.main()

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ dependencies = [
2222
"gwascatalog.sumstatlib",
2323
]
2424

25+
[project.optional-dependencies]
26+
pydantic = [
27+
"gwascatalog.sumstatlib[pydantic]",
28+
]
29+
30+
[project.scripts]
31+
gwascatalog = "gwascatalog.sumstatapp.cli.__main__:main"
32+
2533
[tool.uv.workspace]
2634
members = [
2735
"sumstatlib",

0 commit comments

Comments
 (0)