-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.dev.yml
More file actions
143 lines (138 loc) · 5.08 KB
/
Copy pathdocker-compose.dev.yml
File metadata and controls
143 lines (138 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# ============================================================
# docker-compose.dev.yml — Development overlay
#
# Merges with docker-compose.yml:
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
#
# What this overlay provides:
# - Build configuration pointing at dev Dockerfiles
# - Bind mounts for hot reload (source code changes reflect immediately)
# - Anonymous volumes to prevent host node_modules from overriding
# the container's npm ci installed modules
# - Port forwarding for direct browser/tool access (optional)
# - Development environment variables
# - CHOKIDAR_USEPOLLING for Windows/WSL2 filesystem watching
#
# node_modules conflict prevention (critical for Windows):
# The anonymous volume trick works because Docker applies volumes
# in order: the bind mount (./frontend → /app) is applied first,
# then the anonymous volume (/app/node_modules) is overlaid on top.
# The anonymous volume contains the modules installed by the
# container's Dockerfile RUN npm ci — it hides whatever
# node_modules the host has (or doesn't have).
# Result: container always uses its own modules, never the host's.
# ============================================================
services:
backend:
image: dockerized-backend-dev
build:
context: ./backend
dockerfile: Dockerfile.dev
env_file:
- .env.development
environment:
# Polling (Windows/WSL2 filesystem event limitation)
CHOKIDAR_USEPOLLING: "true"
CHOKIDAR_INTERVAL: "1000"
NODE_ENV: development
ENABLE_SWAGGER: ${ENABLE_SWAGGER:-true}
DATABASE_TYPE: ${DATABASE_TYPE:-oracle}
DATABASE_HOST: ${DATABASE_HOST:-oracle-db}
DATABASE_PORT: ${DATABASE_PORT:-1521}
DATABASE_CONNECTION_STRING: ${DATABASE_CONNECTION_STRING:-oracle-db:1521/XEPDB1}
NODE_ORACLEDB_DRIVER_MODE: ${NODE_ORACLEDB_DRIVER_MODE:-thick}
NODE_ORACLEDB_CLIENT_LIB_DIR: ${NODE_ORACLEDB_CLIENT_LIB_DIR:-}
SCHEMA_1: ${SCHEMA_1:-APPUSER}
SCHEMA_2: ${SCHEMA_2:-APPUSER}
SCHEMA_3: ${SCHEMA_3:-APPUSER}
volumes:
# Bind mount: entire backend directory
- ./backend:/app
# Anonymous volume: overlays /app/node_modules with the
# container's own npm ci output. Prevents the bind mount
# from wiping container modules with host (possibly empty/stale) modules.
# This is the standard Docker pattern for node_modules isolation.
- /app/node_modules
ports:
# Expose backend directly for API testing (Postman, curl, etc.)
# Remove if you want all traffic to flow through NGINX only.
- "3000:3000"
seed-db:
# One-shot dev seeding service. Run explicitly via:
# docker compose --profile seed ... up seed-db
profiles: ["seed"]
image: dockerized-backend-dev
build:
context: ./backend
dockerfile: Dockerfile.dev
env_file:
- .env.development
environment:
NODE_ENV: development
DATABASE_TYPE: ${DATABASE_TYPE:-oracle}
DATABASE_HOST: ${DATABASE_HOST:-oracle-db}
DATABASE_PORT: ${DATABASE_PORT:-1521}
DATABASE_CONNECTION_STRING: ${DATABASE_CONNECTION_STRING:-oracle-db:1521/XEPDB1}
NODE_ORACLEDB_DRIVER_MODE: ${NODE_ORACLEDB_DRIVER_MODE:-thick}
NODE_ORACLEDB_CLIENT_LIB_DIR: ${NODE_ORACLEDB_CLIENT_LIB_DIR:-}
SCHEMA_1: ${SCHEMA_1:-APPUSER}
SCHEMA_2: ${SCHEMA_2:-APPUSER}
SCHEMA_3: ${SCHEMA_3:-APPUSER}
depends_on:
oracle-db:
condition: service_healthy
backend:
condition: service_started
networks:
- app-net
- db-net
volumes:
- ./backend:/app
- /app/node_modules
command: ["sh", "-c", "npm run migration:run && npm run seed -- --all"]
restart: "no"
frontend:
image: dockerized-frontend-dev
build:
context: ./frontend
dockerfile: Dockerfile.dev
env_file:
- .env.development
environment:
# Polling for Vite file watcher — same reason as backend
CHOKIDAR_USEPOLLING: "true"
CHOKIDAR_INTERVAL: "1000"
VITE_HMR_HOST: localhost
VITE_HMR_PORT: "5173"
NODE_ENV: development
volumes:
# Bind mount: entire frontend directory for hot reload
- ./frontend:/app
# Anonymous volume: prevent host node_modules conflict
- /app/node_modules
ports:
# Expose Vite dev server directly (bypass NGINX)
# Useful for testing Vite in isolation or if NGINX is not running
- "5173:5173"
# Override the base healthcheck for the Vite dev server port
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:5173',(r)=>process.exit(r.statusCode<500?0:1)).on('error',()=>process.exit(1));",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
nginx:
# In development, bind-mount the dev config over the default
# (which would otherwise be nginx.prod.conf baked into the image)
volumes:
- ./nginx/nginx.dev.conf:/etc/nginx/conf.d/default.conf:ro
- nginx-logs:/var/log/nginx
ports:
- "80:80"
# No SSL in development