Skip to content

Commit a2c0e4b

Browse files
committed
feat: Dockerized the app
1 parent ace7a32 commit a2c0e4b

File tree

8 files changed

+201
-91
lines changed

8 files changed

+201
-91
lines changed

.dockerignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Dependencies
2+
node_modules
3+
npm-debug.log*
4+
yarn-debug.log*
5+
yarn-error.log*
6+
pnpm-debug.log*
7+
8+
# Build output
9+
dist
10+
coverage
11+
12+
# Environment and config
13+
.env*
14+
.git
15+
.gitignore
16+
.dockerignore
17+
.eslintrc*
18+
.prettierrc*
19+
.eslintignore
20+
.prettierignore
21+
22+
# Docker
23+
Dockerfile
24+
docker-compose.yml
25+
26+
# IDE
27+
.vscode
28+
.idea
29+
*.suo
30+
*.ntvs*
31+
*.njsproj
32+
*.sln
33+
*.sw?

Dockerfile

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
1-
# Build stage
2-
FROM node:20-alpine as builder
1+
# Base stage for shared configuration
2+
FROM node:20-alpine as base
33

44
WORKDIR /app
55

66
# Install pnpm
77
RUN corepack enable && corepack prepare pnpm@latest --activate
88

9+
# Development stage for hot reloading
10+
FROM base as dev
11+
912
# Copy package files
1013
COPY package.json pnpm-lock.yaml ./
1114

12-
# Install dependencies
13-
RUN pnpm install --frozen-lockfile
15+
# Install all dependencies including devDependencies
16+
ENV SKIP_HUSKY=1
17+
RUN pnpm install --ignore-scripts
18+
19+
# The source code will be mounted as a volume in docker-compose
20+
21+
# Build stage for production build
22+
FROM base as builder
23+
24+
# Copy package files first
25+
COPY package.json pnpm-lock.yaml ./
1426

1527
# Copy source code
1628
COPY . .
1729

18-
# Build the application
19-
RUN pnpm build
30+
# Install dependencies and build
31+
ENV SKIP_HUSKY=1
32+
RUN pnpm install --frozen-lockfile --ignore-scripts && \
33+
NODE_ENV=production pnpm build && \
34+
rm -rf src/test && \
35+
pnpm prune --prod && \
36+
rm -rf node_modules/.cache
2037

21-
# Production stage
22-
FROM nginx:alpine
38+
# Production stage with nginx
39+
FROM nginx:alpine as production
2340

2441
# Copy built assets from builder stage
2542
COPY --from=builder /app/dist /usr/share/nginx/html

README.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ You can run this application using Docker in both development and production mod
121121
- Docker
122122
- Docker Compose
123123

124-
### Development
124+
### Development (Default)
125125

126126
1. Copy the environment file:
127127
```bash
@@ -132,19 +132,33 @@ You can run this application using Docker in both development and production mod
132132

133133
3. Start the development container:
134134
```bash
135-
docker compose up dev
135+
docker compose up
136136
```
137137

138-
The development server will be available at http://localhost:3000
138+
The development server will be available at http://localhost:5173
139139

140140
### Production
141141

142142
1. Build and start the production container:
143143
```bash
144-
docker compose up prod -d
144+
docker compose --profile prod up -d
145145
```
146146

147-
The production build will be available at http://localhost:80
147+
The production build will be available at http://localhost:5080
148+
149+
### Docker Profiles
150+
151+
The project uses Docker Compose profiles to separate development and production configurations:
152+
153+
- Development (default): `docker compose up`
154+
- Hot reloading enabled
155+
- Source code mounted as volume
156+
- Runs on port 5173
157+
158+
- Production: `docker compose --profile prod up`
159+
- Optimized production build
160+
- Served via Nginx
161+
- Runs on port 5080
148162

149163
### Environment Variables
150164

docker-compose.yml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1+
name: terminal-portfolio
2+
13
services:
2-
# Development service
4+
# Development service (default profile)
35
dev:
46
build:
57
context: .
6-
target: builder
8+
target: dev
79
command: pnpm dev
810
ports:
9-
- "3000:3000"
11+
- "5173:5173" # Vite's default port
1012
volumes:
1113
- .:/app
1214
- /app/node_modules
1315
environment:
1416
- NODE_ENV=development
1517
- VITE_CONFIG_GIST_URL=${VITE_CONFIG_GIST_URL}
18+
profiles: ["dev"]
19+
# Enable hot reload
20+
develop:
21+
watch:
22+
- path: ./package.json
23+
action: rebuild
24+
- path: ./pnpm-lock.yaml
25+
action: rebuild
1626

1727
# Production service
1828
prod:
19-
build: .
29+
build:
30+
context: .
31+
target: production
2032
ports:
21-
- "80:80"
33+
- "5080:80"
2234
environment:
2335
- NODE_ENV=production
2436
- VITE_CONFIG_GIST_URL=${VITE_CONFIG_GIST_URL}
37+
profiles: ["prod"]
38+
restart: unless-stopped
39+
40+
# Set default profile to dev
41+
x-profiles:
42+
dev: true

nginx.conf

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,24 @@ server {
99
gzip_vary on;
1010
gzip_min_length 10240;
1111
gzip_proxied expired no-cache no-store private auth;
12-
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
12+
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript;
1313
gzip_disable "MSIE [1-6]\.";
1414

15-
# Serve static files
15+
# SPA configuration
1616
location / {
1717
try_files $uri $uri/ /index.html;
18-
add_header Cache-Control "public, no-cache";
18+
add_header Cache-Control "no-cache";
1919
}
2020

21-
# Cache static assets
22-
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
21+
# Static assets
22+
location /assets {
2323
expires 1y;
24-
add_header Cache-Control "public, no-transform";
24+
add_header Cache-Control "public, immutable";
25+
}
26+
27+
# Health check
28+
location /health {
29+
access_log off;
30+
return 200 'healthy\n';
2531
}
2632
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"test:once": "NODE_OPTIONS='--no-deprecation' vitest run",
1010
"test": "vitest",
1111
"coverage": "vitest run --coverage",
12-
"prepare": "husky install",
12+
"prepare": "[ -n \"$SKIP_HUSKY\" ] || husky install",
1313
"lint": "eslint .",
1414
"format:check": "prettier --check .",
1515
"format": "prettier --write ."
@@ -59,5 +59,6 @@
5959
"*.{json,yml,yaml,md}": [
6060
"prettier --write"
6161
]
62-
}
62+
},
63+
"packageManager": "[email protected]+sha512.93e57b0126f0df74ce6bff29680394c0ba54ec47246b9cf321f0121d8d9bb03f750a705f24edc3c1180853afd7c2c3b94196d0a3d53d3e069d9e2793ef11f321"
6364
}

0 commit comments

Comments
 (0)