feat: add Docker support and compile shared package to dist
- Add multi-stage Dockerfile for server containerization - Add .dockerignore to exclude unnecessary files from build context - Switch shared package from source to compiled CommonJS output (dist/) - Server dev/build scripts now build shared package first - Fix deep imports to use @calchat/shared barrel export - Update CLAUDE.md with Docker and shared package documentation
This commit is contained in:
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@@ -0,0 +1,8 @@
|
||||
node_modules
|
||||
*/node_modules
|
||||
*/*/node_modules
|
||||
**/dist
|
||||
apps/client
|
||||
.git
|
||||
.env
|
||||
*.md
|
||||
20
CLAUDE.md
20
CLAUDE.md
@@ -26,10 +26,15 @@ npm run lint -w @calchat/client # Run ESLint
|
||||
npm run build:apk -w @calchat/client # Build APK locally with EAS
|
||||
```
|
||||
|
||||
### Shared (packages/shared)
|
||||
```bash
|
||||
npm run build -w @calchat/shared # Compile shared types to dist/
|
||||
```
|
||||
|
||||
### Server (apps/server) - Express.js backend
|
||||
```bash
|
||||
npm run dev -w @calchat/server # Start dev server with hot reload (tsx watch)
|
||||
npm run build -w @calchat/server # Compile TypeScript
|
||||
npm run dev -w @calchat/server # Build shared + start dev server with hot reload (tsx watch)
|
||||
npm run build -w @calchat/server # Build shared + compile TypeScript
|
||||
npm run start -w @calchat/server # Run compiled server (port 3000)
|
||||
```
|
||||
|
||||
@@ -53,6 +58,7 @@ npm run start -w @calchat/server # Run compiled server (port 3000)
|
||||
| | react-native-logs | Client-side logging |
|
||||
| | tsdav | CalDAV client library |
|
||||
| | ical.js | iCalendar parsing/generation |
|
||||
| Deployment | Docker | Server containerization (multi-stage build) |
|
||||
| Planned | iCalendar | Event export/import |
|
||||
|
||||
## Architecture
|
||||
@@ -318,6 +324,8 @@ src/
|
||||
|
||||
### Shared Package (packages/shared)
|
||||
|
||||
The shared package is compiled to `dist/` (CommonJS). All imports must use `@calchat/shared` (NOT `@calchat/shared/src/...`). Server `dev` and `build` scripts automatically build shared first.
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.ts
|
||||
@@ -530,6 +538,14 @@ docker compose up -d # Start Radicale CalDAV server
|
||||
```
|
||||
- Radicale: `localhost:5232`
|
||||
|
||||
### Server Docker Image
|
||||
```bash
|
||||
# Build from repo root:
|
||||
docker build -f apps/server/docker/Dockerfile -t calchat-server .
|
||||
docker run -p 3000:3000 --env-file apps/server/.env calchat-server
|
||||
```
|
||||
Multi-stage build: compiles shared + server in build stage, copies only `dist/` and production dependencies to runtime stage. `.dockerignore` excludes `node_modules`, `dist`, `apps/client`, `.git`, `.env`, `*.md`.
|
||||
|
||||
### Environment Variables
|
||||
Server requires `.env` file in `apps/server/`:
|
||||
```
|
||||
|
||||
29
apps/server/docker/Dockerfile
Normal file
29
apps/server/docker/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
FROM node:alpine AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json tsconfig.json ./
|
||||
COPY packages/shared/ packages/shared/
|
||||
COPY apps/server/ apps/server/
|
||||
|
||||
RUN npm ci --workspace=@calchat/server --workspace=@calchat/shared --include-workspace-root
|
||||
|
||||
RUN npm run build --workspace=@calchat/shared && \
|
||||
npm run build --workspace=@calchat/server
|
||||
|
||||
FROM node:alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
COPY packages/shared/package.json packages/shared/
|
||||
COPY apps/server/package.json apps/server/
|
||||
|
||||
RUN npm ci --omit=dev --workspace=@calchat/server --workspace=@calchat/shared --include-workspace-root
|
||||
|
||||
COPY --from=build /app/packages/shared/dist/ packages/shared/dist/
|
||||
COPY --from=build /app/apps/server/dist/ apps/server/dist/
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "apps/server/dist/app.js"]
|
||||
@@ -3,8 +3,8 @@
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/app.ts",
|
||||
"build": "tsc",
|
||||
"dev": "npm run build --workspace=@calchat/shared && tsx watch src/app.ts",
|
||||
"build": "npm run build --workspace=@calchat/shared && tsc",
|
||||
"start": "node dist/app.js",
|
||||
"test": "jest"
|
||||
},
|
||||
|
||||
@@ -6,9 +6,10 @@ import { CaldavRepository } from "./interfaces/CaldavRepository";
|
||||
import {
|
||||
CalendarEvent,
|
||||
CreateEventDTO,
|
||||
} from "@calchat/shared/src/models/CalendarEvent";
|
||||
CaldavConfig,
|
||||
formatDateKey,
|
||||
} from "@calchat/shared";
|
||||
import { EventService } from "./EventService";
|
||||
import { CaldavConfig, formatDateKey } from "@calchat/shared";
|
||||
|
||||
const logger = createLogger("CaldavService");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CaldavConfig } from "@calchat/shared/src/models/CaldavConfig";
|
||||
import { CaldavConfig } from "@calchat/shared";
|
||||
|
||||
export interface CaldavRepository {
|
||||
findByUserId(userId: string): Promise<CaldavConfig | null>;
|
||||
|
||||
1
packages/shared/.gitignore
vendored
Normal file
1
packages/shared/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dist/
|
||||
@@ -2,11 +2,14 @@
|
||||
"name": "@calchat/shared",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*"
|
||||
".": "./dist/index.js",
|
||||
"./*": "./dist/*"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"rrule": "^2.8.1"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"module": "ESNext",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"module": "CommonJS",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "Node",
|
||||
"esModuleInterop": true,
|
||||
|
||||
Reference in New Issue
Block a user