Skip to content

Commit 66b4322

Browse files
committed
add docker build for server
1 parent 34af6d1 commit 66b4322

20 files changed

+357
-35
lines changed

.dockerignore

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This .dockerignore file only works with docker buildkit. Wildcard exclusion patterns are
2+
# utterly broken and misdocumented in vanilla docker.
3+
#
4+
# See: https://github.com/moby/moby/issues/43232
5+
#
6+
# This is an allow-list based .dockerignore file.
7+
#
8+
# - First of all, ignore everything.
9+
# - Then, allow only the files that are needed for the build.
10+
#
11+
# We add only the absolute minimal set of files needed for the build. For instance,
12+
# we can entirely skip any tsconfig because we use `tsup` for the server build.
13+
*
14+
15+
# Allow workspace root files.
16+
!package.json
17+
!tsconfig.json
18+
!tsconfig.base.json
19+
!tsconfig.build.json
20+
!pnpm-workspace.yaml
21+
!pnpm-lock.yaml
22+
!patches/*
23+
!scripts/*
24+
25+
# Server application.
26+
!apps/server/package.json
27+
!apps/server/tsup.config.ts
28+
!apps/server/src
29+
!apps/server/prisma
30+
31+
# Workspace package dependencies.
32+
!packages/hypergraph/package.json
33+
!packages/hypergraph/src
34+
!packages/hypergraph/tsconfig.json
35+
!packages/hypergraph/tsconfig.src.json
36+
!packages/hypergraph/tsconfig.build.json
37+
38+
!packages/hypergraph-react/package.json
39+
!packages/hypergraph-react/src
40+
!packages/hypergraph-react/tsconfig.json
41+
!packages/hypergraph-react/tsconfig.src.json
42+
!packages/hypergraph-react/tsconfig.build.json

Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# syntax=docker/dockerfile:1.4
2+
3+
# Installation stage.
4+
FROM node:22-alpine AS base
5+
WORKDIR /workspace
6+
RUN apk add --update --no-cache openssl python3 make g++
7+
# Install pnpm.
8+
ADD package.json .
9+
RUN corepack enable && corepack prepare --activate
10+
# Fetch all node modules purely based on the pnpm lock file.
11+
COPY pnpm-lock.yaml .
12+
RUN --mount=type=cache,id=workspace,target=/root/.local/share/pnpm/store pnpm fetch
13+
# Copy the entire workspace into the scope and perform the actual installation.
14+
COPY . .
15+
RUN --mount=type=cache,id=workspace,target=/root/.local/share/pnpm/store pnpm install
16+
17+
# Build stage for the server.
18+
FROM base AS build
19+
# TODO: Remove this when we switch to an actual database.
20+
ENV DATABASE_URL="file:./dev.db"
21+
RUN \
22+
# TODO: This initalizes the database. But we should probably remove this later.
23+
pnpm --filter server prisma migrate reset --force && \
24+
# Build the monorepo packages.
25+
pnpm build && \
26+
# Build the server.
27+
pnpm --filter server build && \
28+
# Create an isolated deployment for the server.
29+
pnpm --filter server deploy --prod deployment && \
30+
# Move the runtime build artifacts into a separate directory.
31+
mkdir -p deployment/out && mv deployment/dist deployment/prisma deployment/node_modules deployment/package.json deployment/out && \
32+
# Generate the prisma client
33+
(cd deployment/out && pnpx prisma generate)
34+
35+
# Slim runtime image.
36+
FROM node:22-alpine AS server
37+
WORKDIR /app
38+
COPY --from=build /workspace/deployment/out .
39+
# TODO: Remove this when we switch to an actual database.
40+
ENV DATABASE_URL="file:./dev.db"
41+
EXPOSE 3030
42+
CMD ["node", "dist/index.js"]

apps/server/.dockerignore

Lines changed: 0 additions & 5 deletions
This file was deleted.

apps/server/Dockerfile

Lines changed: 0 additions & 16 deletions
This file was deleted.

apps/server/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"dev": "bun run --watch ./src/index.ts"
7+
"dev": "bun run --watch ./src/index.ts",
8+
"prisma": "prisma",
9+
"build": "tsup"
810
},
911
"dependencies": {
1012
"@graphprotocol/hypergraph": "workspace:*",
1113
"@noble/ciphers": "^1.2.0",
12-
"@prisma/client": "6.2.1",
14+
"@prisma/client": "^6.2.1",
1315
"cors": "^2.8.5",
1416
"effect": "^3.12.4",
1517
"express": "^5.0.1",
@@ -24,6 +26,7 @@
2426
"@types/pg": "^8.11.6",
2527
"@types/ws": "^8.5.13",
2628
"prisma": "^6.2.1",
29+
"tsup": "^8.3.5",
2730
"typescript": "^5.7.3"
2831
}
2932
}

apps/server/prisma/schema.prisma

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// learn more about it in the docs: https://pris.ly/d/prisma-schema
33

44
generator client {
5+
// TODO: Using `pnpm deploy` with prisma is quite annoying. We should consider generating the prisma client into
6+
// a directory within the package here instead of generating it into node modules (default).
57
provider = "prisma-client-js"
68
}
79

apps/server/tsconfig.app.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"include": ["src", "tsup.config.ts"],
4+
"compilerOptions": {
5+
"target": "ES2022",
6+
"lib": ["ES2023"],
7+
"module": "ESNext",
8+
"skipLibCheck": true,
9+
10+
"composite": false,
11+
"incremental": false,
12+
"declaration": false,
13+
"declarationMap": false,
14+
15+
/* Bundler mode */
16+
"moduleResolution": "bundler",
17+
"allowImportingTsExtensions": true,
18+
"isolatedModules": true,
19+
"moduleDetection": "force",
20+
"noEmit": true,
21+
22+
/* Linting */
23+
"strict": true,
24+
"exactOptionalPropertyTypes": true,
25+
"noUnusedLocals": true,
26+
"noUnusedParameters": true,
27+
"noFallthroughCasesInSwitch": true
28+
}
29+
}

apps/server/tsconfig.json

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
11
{
22
"extends": "../../tsconfig.base.json",
3-
"include": ["src"],
3+
"include": ["src", "tsup.config.ts"],
44
"compilerOptions": {
5+
"target": "ES2022",
6+
"lib": ["ES2023"],
7+
"module": "ESNext",
8+
"skipLibCheck": true,
9+
510
"composite": false,
6-
"noEmit": true,
711
"incremental": false,
812
"declaration": false,
9-
"declarationMap": false
13+
"declarationMap": false,
14+
15+
/* Bundler mode */
16+
"moduleResolution": "bundler",
17+
"allowImportingTsExtensions": true,
18+
"isolatedModules": true,
19+
"moduleDetection": "force",
20+
"noEmit": true,
21+
22+
/* Linting */
23+
"strict": true,
24+
"exactOptionalPropertyTypes": true,
25+
"noUnusedLocals": true,
26+
"noUnusedParameters": true,
27+
"noFallthroughCasesInSwitch": true
1028
}
1129
}

apps/server/tsconfig.node.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"include": ["vite.config.ts"],
4+
"compilerOptions": {
5+
"target": "ES2022",
6+
"lib": ["ES2023"],
7+
"module": "ESNext",
8+
"skipLibCheck": true,
9+
10+
"composite": false,
11+
"incremental": false,
12+
"declaration": false,
13+
"declarationMap": false,
14+
15+
/* Bundler mode */
16+
"moduleResolution": "bundler",
17+
"allowImportingTsExtensions": true,
18+
"isolatedModules": true,
19+
"moduleDetection": "force",
20+
"noEmit": true,
21+
22+
/* Linting */
23+
"strict": true,
24+
"exactOptionalPropertyTypes": true,
25+
"noUnusedLocals": true,
26+
"noUnusedParameters": true,
27+
"noFallthroughCasesInSwitch": true
28+
}
29+
}

apps/server/tsup.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from 'tsup';
2+
3+
export default defineConfig(() => ({
4+
entry: ['src/index.ts'],
5+
format: ['esm'],
6+
clean: true,
7+
sourcemap: true,
8+
}));

0 commit comments

Comments
 (0)