Skip to content

Commit 3b5ab17

Browse files
Shaun Mahonyclaude
andcommitted
Add Next.js web platform for STAMP
Replace the legacy PHP/Perl web interface with a modern Next.js 14 app featuring anonymous job submission, real-time status via SSE, interactive D3.js phylogenetic trees, canvas sequence logos, and a password-protected admin dashboard with JASPAR database sync. Stack: Next.js 14 (App Router), MongoDB, BullMQ/Redis, Docker Compose. Supports TRANSFAC, MEME, JASPAR, and TF-MoDISco input formats. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 4d76010 commit 3b5ab17

62 files changed

Lines changed: 14990 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
stamp
1+
/stamp
22
outFile*

web/.env.example

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# MongoDB
2+
MONGODB_URI=mongodb://localhost:27017/stamp
3+
4+
# Redis (for BullMQ job queue)
5+
REDIS_URL=redis://localhost:6379
6+
7+
# Admin
8+
ADMIN_PASSWORD=change-me-in-production
9+
10+
# STAMP binary
11+
STAMP_BINARY=/usr/local/bin/stamp
12+
SCORE_DISTS_DIR=/path/to/ScoreDists
13+
14+
# Job settings
15+
JOB_TIMEOUT_MS=300000
16+
JOB_RETENTION_DAYS=7
17+
JOBS_DATA_DIR=/tmp/stamp-jobs
18+
19+
# Rate limiting
20+
RATE_LIMIT_JOBS_PER_HOUR=20
21+
22+
# Email notifications (optional)
23+
SMTP_HOST=
24+
SMTP_PORT=587
25+
SMTP_USER=
26+
SMTP_PASS=
27+
28+
29+
# Public URL (for email links)
30+
PUBLIC_URL=http://localhost:3000

web/.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# dependencies
2+
/node_modules
3+
/.pnp
4+
.pnp.js
5+
6+
# testing
7+
/coverage
8+
9+
# next.js
10+
/.next/
11+
/out/
12+
13+
# production
14+
/build
15+
16+
# misc
17+
.DS_Store
18+
*.pem
19+
20+
# debug
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
# local env files
26+
.env*.local
27+
.env
28+
29+
# vercel
30+
.vercel
31+
32+
# typescript
33+
*.tsbuildinfo
34+
next-env.d.ts

web/docker/Dockerfile

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Stage 1: Compile STAMP binary
2+
FROM ubuntu:22.04 AS stamp-builder
3+
4+
RUN apt-get update && \
5+
apt-get install -y g++ libgsl-dev && \
6+
rm -rf /var/lib/apt/lists/*
7+
8+
WORKDIR /build
9+
COPY src/ ./src/
10+
11+
WORKDIR /build/src
12+
RUN g++ -O3 -o /build/stamp \
13+
Motif.cpp Alignment.cpp ColumnComp.cpp \
14+
PlatformSupport.cpp PlatformTesting.cpp Tree.cpp \
15+
NeuralTree.cpp MultipleAlignment.cpp RandPSSMGen.cpp \
16+
ProteinDomains.cpp main.cpp \
17+
-lm -lgsl -lgslcblas
18+
19+
# Stage 2: Build Next.js application
20+
FROM node:22-alpine AS app-builder
21+
22+
WORKDIR /app
23+
COPY web/package.json web/package-lock.json* ./
24+
RUN npm install
25+
COPY web/ ./
26+
RUN npm run build
27+
28+
# Stage 3: Production image
29+
FROM node:22-slim
30+
31+
RUN apt-get update && \
32+
apt-get install -y libgsl27 && \
33+
rm -rf /var/lib/apt/lists/*
34+
35+
WORKDIR /app
36+
37+
# Copy STAMP binary and score distributions
38+
COPY --from=stamp-builder /build/stamp /app/stamp
39+
COPY ScoreDists/ /app/ScoreDists/
40+
41+
# Copy Next.js standalone build
42+
COPY --from=app-builder /app/.next/standalone ./
43+
COPY --from=app-builder /app/.next/static ./.next/static
44+
COPY --from=app-builder /app/public ./public
45+
46+
# Create data directory
47+
RUN mkdir -p /app/data/jobs
48+
49+
ENV NODE_ENV=production
50+
ENV PORT=3000
51+
ENV HOSTNAME=0.0.0.0
52+
53+
EXPOSE 3000
54+
55+
CMD ["node", "server.js"]

web/docker/Dockerfile.worker

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Stage 1: Compile STAMP binary
2+
FROM ubuntu:22.04 AS stamp-builder
3+
4+
RUN apt-get update && \
5+
apt-get install -y g++ libgsl-dev && \
6+
rm -rf /var/lib/apt/lists/*
7+
8+
WORKDIR /build
9+
COPY src/ ./src/
10+
11+
WORKDIR /build/src
12+
RUN g++ -O3 -o /build/stamp \
13+
Motif.cpp Alignment.cpp ColumnComp.cpp \
14+
PlatformSupport.cpp PlatformTesting.cpp Tree.cpp \
15+
NeuralTree.cpp MultipleAlignment.cpp RandPSSMGen.cpp \
16+
ProteinDomains.cpp main.cpp \
17+
-lm -lgsl -lgslcblas
18+
19+
# Stage 2: Build worker
20+
FROM node:22-slim
21+
22+
RUN apt-get update && \
23+
apt-get install -y libgsl27 && \
24+
rm -rf /var/lib/apt/lists/*
25+
26+
WORKDIR /app
27+
28+
# Copy STAMP binary and score distributions
29+
COPY --from=stamp-builder /build/stamp /app/stamp
30+
COPY ScoreDists/ /app/ScoreDists/
31+
32+
# Install dependencies
33+
COPY web/package.json web/package-lock.json* ./
34+
RUN npm install --omit=dev && npm install tsx
35+
36+
# Copy worker and library source
37+
COPY web/worker/ ./worker/
38+
COPY web/src/lib/ ./src/lib/
39+
COPY web/src/types/ ./src/types/
40+
COPY web/tsconfig.json ./
41+
42+
# Create data directory
43+
RUN mkdir -p /app/data/jobs
44+
45+
ENV NODE_ENV=production
46+
47+
CMD ["npx", "tsx", "worker/index.ts"]

web/docker/docker-compose.dev.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Development compose file - only runs MongoDB and Redis
2+
# Run the Next.js app and worker locally with `npm run dev` and `npm run worker:dev`
3+
services:
4+
mongodb:
5+
image: mongo:7
6+
ports:
7+
- "27017:27017"
8+
volumes:
9+
- mongo-data:/data/db
10+
11+
redis:
12+
image: redis:7-alpine
13+
ports:
14+
- "6379:6379"
15+
volumes:
16+
- redis-data:/data
17+
18+
volumes:
19+
mongo-data:
20+
redis-data:

web/docker/docker-compose.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
services:
2+
app:
3+
build:
4+
context: ../..
5+
dockerfile: web/docker/Dockerfile
6+
ports:
7+
- "3000:3000"
8+
environment:
9+
- MONGODB_URI=mongodb://mongodb:27017/stamp
10+
- REDIS_URL=redis://redis:6379
11+
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-changeme}
12+
- STAMP_BINARY=/app/stamp
13+
- SCORE_DISTS_DIR=/app/ScoreDists
14+
- JOBS_DATA_DIR=/app/data/jobs
15+
- NODE_ENV=production
16+
- SMTP_HOST=${SMTP_HOST:-}
17+
- SMTP_PORT=${SMTP_PORT:-587}
18+
- SMTP_USER=${SMTP_USER:-}
19+
- SMTP_PASS=${SMTP_PASS:-}
20+
- SMTP_FROM=${SMTP_FROM:[email protected]}
21+
- PUBLIC_URL=${PUBLIC_URL:-http://localhost:3000}
22+
depends_on:
23+
mongodb:
24+
condition: service_started
25+
redis:
26+
condition: service_started
27+
volumes:
28+
- job-data:/app/data/jobs
29+
restart: unless-stopped
30+
31+
worker:
32+
build:
33+
context: ../..
34+
dockerfile: web/docker/Dockerfile.worker
35+
environment:
36+
- MONGODB_URI=mongodb://mongodb:27017/stamp
37+
- REDIS_URL=redis://redis:6379
38+
- STAMP_BINARY=/app/stamp
39+
- SCORE_DISTS_DIR=/app/ScoreDists
40+
- JOBS_DATA_DIR=/app/data/jobs
41+
- SMTP_HOST=${SMTP_HOST:-}
42+
- SMTP_PORT=${SMTP_PORT:-587}
43+
- SMTP_USER=${SMTP_USER:-}
44+
- SMTP_PASS=${SMTP_PASS:-}
45+
- SMTP_FROM=${SMTP_FROM:[email protected]}
46+
- PUBLIC_URL=${PUBLIC_URL:-http://localhost:3000}
47+
depends_on:
48+
mongodb:
49+
condition: service_started
50+
redis:
51+
condition: service_started
52+
volumes:
53+
- job-data:/app/data/jobs
54+
deploy:
55+
replicas: 2
56+
restart: unless-stopped
57+
58+
mongodb:
59+
image: mongo:7
60+
volumes:
61+
- mongo-data:/data/db
62+
restart: unless-stopped
63+
64+
redis:
65+
image: redis:7-alpine
66+
volumes:
67+
- redis-data:/data
68+
restart: unless-stopped
69+
70+
volumes:
71+
mongo-data:
72+
redis-data:
73+
job-data:

web/next.config.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/** @type {import('next').NextConfig} */
2+
const nextConfig = {
3+
output: "standalone",
4+
experimental: {
5+
serverComponentsExternalPackages: ["mongoose", "bullmq", "ioredis", "archiver", "nodemailer"],
6+
},
7+
};
8+
9+
export default nextConfig;

0 commit comments

Comments
 (0)