diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..5aef689
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,19 @@
+# Dependency
+node_modules
+dist
+.svelte-kit
+build
+
+# Environment
+.env
+.env.*
+!.env.example
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Docker
+Dockerfile
+docker-compose.yml
+.dockerignore
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 30c6221..b152a8f 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,19 +4,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -137,7 +125,7 @@
1774643312599
-
+
@@ -267,7 +255,23 @@
1774714977147
-
+
+
+ 1774715653258
+
+
+
+ 1774715653258
+
+
+
+ 1774715728737
+
+
+
+ 1774715728737
+
+
@@ -292,6 +296,8 @@
-
+
+
+
\ No newline at end of file
diff --git a/DOCKER_SETUP.md b/DOCKER_SETUP.md
new file mode 100644
index 0000000..cf12479
--- /dev/null
+++ b/DOCKER_SETUP.md
@@ -0,0 +1,59 @@
+# Docker Setup Guide
+
+This guide describes how to deploy the application using Docker and Docker Compose.
+
+## Prerequisites
+- Docker (20.10+)
+- Docker Compose (v2.0+)
+
+## Environment Variables
+
+Create a `.env` file in the root directory. The following variables are supported (with their default values shown):
+
+| Variable | Description | Default |
+|----------|-------------|---------|
+| `DB_USER` | PostgreSQL username | `postgres` |
+| `DB_PASSWORD` | PostgreSQL password | `postgres` |
+| `DB_NAME` | PostgreSQL database name | `hotdesking` |
+| `DB_PORT_EXTERNAL` | External port for PostgreSQL | `5433` |
+| `API_PORT_EXTERNAL` | External port for the API | `3000` |
+| `WEB_PORT_EXTERNAL` | External port for the Web app | `5173` |
+| `JWT_SECRET` | Secret key for JWT signing | `super-secret-change-me` |
+| `WEB_ORIGIN` | The origin of the web app (required by SvelteKit) | `http://localhost:5173` |
+| `VITE_API_BASE_URL` | The URL of the API (for the web app) | `http://localhost:3000` |
+
+## Deployment Steps
+
+1. **Build and start the containers:**
+ ```bash
+ docker-compose up -d --build
+ ```
+
+2. **Run Database Migrations:**
+ Since the API uses Prisma, you need to run migrations to set up the database schema:
+ ```bash
+ docker exec -it hotdesking_api npx prisma migrate deploy
+ ```
+
+3. **(Optional) Seed the Database:**
+ If you have a seed script defined in `apps/api/prisma/seed.ts`:
+ ```bash
+ docker exec -it hotdesking_api npx prisma db seed
+ ```
+
+4. **Access the Applications:**
+ - Web App: [http://localhost:5173](http://localhost:5173)
+ - API: [http://localhost:3000](http://localhost:3000)
+ - pgAdmin: [http://localhost:5051](http://localhost:5051) (Login: `admin@local.dev` / `admin`)
+
+## Development with Docker
+
+To watch logs:
+```bash
+docker-compose logs -f
+```
+
+To stop the applications:
+```bash
+docker-compose down
+```
diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile
new file mode 100644
index 0000000..0a8594a
--- /dev/null
+++ b/apps/api/Dockerfile
@@ -0,0 +1,48 @@
+FROM node:20-alpine AS builder
+
+WORKDIR /app
+
+# Copy root configs
+COPY package*.json ./
+COPY tsconfig.json ./
+COPY tsconfig.base.json ./
+
+# Copy packages
+COPY apps/api/package*.json ./apps/api/
+COPY shared/package*.json ./shared/
+
+# Install dependencies (using npm ci for better builds)
+RUN npm ci
+
+# Copy source code
+COPY apps/api ./apps/api
+COPY shared ./shared
+
+# Generate Prisma client
+WORKDIR /app/apps/api
+RUN npx prisma generate
+
+# Build the app
+RUN npm run build
+
+# ---
+FROM node:20-alpine AS runner
+
+WORKDIR /app
+
+# Copy build artifacts and necessary files
+COPY --from=builder /app/node_modules ./node_modules
+COPY --from=builder /app/apps/api/node_modules ./apps/api/node_modules
+COPY --from=builder /app/apps/api/dist ./apps/api/dist
+COPY --from=builder /app/apps/api/package.json ./apps/api/package.json
+COPY --from=builder /app/apps/api/prisma ./apps/api/prisma
+COPY --from=builder /app/shared/dist ./shared/dist
+COPY --from=builder /app/shared/package.json ./shared/package.json
+
+EXPOSE 3000
+
+ENV PORT=3000
+ENV NODE_ENV=production
+
+WORKDIR /app/apps/api
+CMD ["node", "dist/main"]
diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile
new file mode 100644
index 0000000..d34e7d3
--- /dev/null
+++ b/apps/web/Dockerfile
@@ -0,0 +1,45 @@
+FROM node:20-alpine AS builder
+
+WORKDIR /app
+
+# Copy root configs
+COPY package*.json ./
+COPY tsconfig.json ./
+COPY tsconfig.base.json ./
+
+# Copy packages
+COPY apps/web/package*.json ./apps/web/
+COPY shared/package*.json ./shared/
+
+# Install dependencies
+RUN npm ci
+
+# Copy source code
+COPY apps/web ./apps/web
+COPY shared ./shared
+
+# Build the app
+WORKDIR /app/apps/web
+# We need VITE_API_BASE_URL at build time for SvelteKit static replacements if any,
+# but usually it's better to use dynamic env vars if possible.
+# For now, let's assume it can be provided during build or we use the default.
+RUN npm run build
+
+# ---
+FROM node:20-alpine AS runner
+
+WORKDIR /app
+
+# Copy build artifacts and necessary files
+COPY --from=builder /app/apps/web/build ./apps/web/build
+COPY --from=builder /app/apps/web/package.json ./apps/web/package.json
+# Node adapter needs dependencies to run
+COPY --from=builder /app/node_modules ./node_modules
+
+EXPOSE 5173
+
+ENV PORT=5173
+ENV NODE_ENV=production
+
+WORKDIR /app/apps/web
+CMD ["node", "build"]
diff --git a/apps/web/package.json b/apps/web/package.json
index f66af91..eba5610 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -10,7 +10,7 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
- "@sveltejs/adapter-auto": "^3.3.1",
+ "@sveltejs/adapter-node": "^5.2.11",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"autoprefixer": "^10.4.0",
diff --git a/apps/web/svelte.config.js b/apps/web/svelte.config.js
index b7d05fc..35f261e 100644
--- a/apps/web/svelte.config.js
+++ b/apps/web/svelte.config.js
@@ -1,4 +1,4 @@
-import adapter from '@sveltejs/adapter-auto';
+import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
diff --git a/docker-compose.yml b/docker-compose.yml
index 2c8bf50..27bfa2f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,19 +1,47 @@
-version: "3.9"
-
services:
postgres:
image: postgres:16
container_name: hotdesking_postgres
restart: unless-stopped
environment:
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_DB: hotdesking
+ POSTGRES_USER: ${DB_USER:-postgres}
+ POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
+ POSTGRES_DB: ${DB_NAME:-hotdesking}
ports:
- - "5433:5432"
+ - "${DB_PORT_EXTERNAL:-5433}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
+ api:
+ build:
+ context: .
+ dockerfile: apps/api/Dockerfile
+ container_name: hotdesking_api
+ restart: unless-stopped
+ ports:
+ - "${API_PORT_EXTERNAL:-3000}:3000"
+ environment:
+ DATABASE_URL: "postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@postgres:5432/${DB_NAME:-hotdesking}"
+ PORT: 3000
+ JWT_SECRET: ${JWT_SECRET:-super-secret-change-me}
+ depends_on:
+ - postgres
+
+ web:
+ build:
+ context: .
+ dockerfile: apps/web/Dockerfile
+ container_name: hotdesking_web
+ restart: unless-stopped
+ ports:
+ - "${WEB_PORT_EXTERNAL:-5173}:5173"
+ environment:
+ PORT: 5173
+ ORIGIN: ${WEB_ORIGIN:-http://localhost:5173}
+ VITE_API_BASE_URL: ${VITE_API_BASE_URL:-http://localhost:3000}
+ depends_on:
+ - api
+
pgadmin:
image: dpage/pgadmin4:8
container_name: hotdesking_pgadmin