Skip to content

Commit 6d4c1b7

Browse files
Merge pull request #20 from devlopersabbir/sabbir
Sabbir
2 parents 978230f + cafc7d3 commit 6d4c1b7

2 files changed

Lines changed: 146 additions & 65 deletions

File tree

Dockerfile

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
1-
# Use a slim Node.js image as base
2-
FROM node:20-alpine
1+
# ------------------------
2+
# Stage 1: Build Stage
3+
# ------------------------
4+
FROM node:20-alpine AS builder
35

4-
# Install docker CLI to execute docker command (for accessing host Docker)
5-
# Also install bash for better scripting capabilities inside the container if needed
6-
RUN apk add --no-cache docker-cli bash
7-
8-
# Set working directory inside the container
6+
# Set working directory
97
WORKDIR /app
108

11-
# Copy only package.json and package-lock.json to leverage Docker layer caching
12-
# This ensures npm install is re-run only if dependencies change
9+
# Copy only package files to install dependencies first (cache-friendly)
1310
COPY package*.json ./
1411

15-
# Install project dependencies
16-
RUN npm install
12+
# Install dependencies
13+
RUN npm ci --omit=dev
1714

18-
# Copy the rest of your application source code
15+
# Copy the rest of the app source code
1916
COPY . .
2017

21-
# Set environment variables
22-
ENV PORT=9091
18+
# ------------------------
19+
# Stage 2: Production Image
20+
# ------------------------
21+
FROM node:20-alpine AS production
22+
23+
# Set working directory
24+
WORKDIR /app
25+
26+
# Copy only the necessary files from builder
27+
COPY --from=builder /app/node_modules ./node_modules
28+
COPY --from=builder /app/package*.json ./
29+
COPY --from=builder /app/dist ./dist
30+
COPY --from=builder /app/temp ./temp
31+
COPY --from=builder /app/public ./public
32+
COPY --from=builder /app/*.js ./
2333

24-
# Create a temporary directory that will be used for mounting (if it doesn't exist on host)
25-
# This command ensures the directory exists within the image,
26-
# but the volume mount `./temp:/app/temp` will override it with the host's `./temp`
27-
# if `./temp` exists on the host. If `./temp` doesn't exist on the host, Docker will create it.
28-
RUN mkdir -p /app/temp
34+
# Set environment variables
35+
ENV NODE_ENV=production
36+
ENV PORT=5000
2937

30-
# Expose the port your Node.js application listens on
31-
EXPOSE 9091
38+
# Expose app port
39+
EXPOSE 5000
3240

33-
# Command to run your application when the container starts
34-
CMD ["npm", "start"]
41+
# Start the application
42+
CMD ["node", "index.js"]

docker-compose.yaml

Lines changed: 115 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,152 @@
11
services:
2+
app:
3+
profiles:
4+
- prod
5+
- dev
6+
build:
7+
context: .
8+
dockerfile: Dockerfile
9+
image: ${DOCKER_USERNAME}/${PACKAGE_NAME}:${PACKAGE_VERSION}
10+
container_name: ${PACKAGE_NAME}_api
11+
environment:
12+
- PORT=${PORT}
13+
- NODE_ENV=${NODE_ENV}
14+
- EMAIL=${EMAIL}
15+
- BASE_URL=${BASE_URL}
16+
- HOST_PROJECT_ROOT=${PWD}
17+
ports:
18+
- "5000:${PORT}"
19+
volumes:
20+
- /var/run/docker.sock:/var/run/docker.sock
21+
- ./temp:/app/temp
22+
networks:
23+
- default
24+
restart: unless-stopped
25+
26+
healthcheck:
27+
test: ["CMD", "curl", "-f", "http://localhost:${PORT}/"]
28+
interval: 30s # Check every 15 seconds (more frequent)
29+
timeout: 15s # 10 second timeout
30+
retries: 3 # 3 retries before marking unhealthy
31+
start_period: 30s # Wait 30 seconds before starting health checks
32+
33+
# Add logging configuration
34+
logging:
35+
driver: "json-file"
36+
options:
37+
max-size: "10m"
38+
max-file: "3"
39+
# Add labels for better container management
40+
labels:
41+
- "app.name=${PACKAGE_NAME}"
42+
- "app.version=${PACKAGE_VERSION}"
43+
- "deployment.type=zero-downtime"
44+
45+
nginx:
46+
profiles:
47+
- prod
48+
image: nginx:alpine
49+
container_name: ${PACKAGE_NAME}_nginx
50+
depends_on:
51+
- app
52+
volumes:
53+
- ./nginx/conf.d:/etc/nginx/conf.d
54+
- ./nginx/certbot/www:/var/www/certbot
55+
- ./nginx/certbot/conf:/etc/letsencrypt
56+
- ./nginx/selfsigned:/etc/nginx/selfsigned
57+
58+
ports:
59+
- "80:80"
60+
- "443:443"
61+
networks:
62+
- default
63+
restart: always
64+
65+
certbot:
66+
profiles:
67+
- prod
68+
image: certbot/certbot
69+
container_name: ${PACKAGE_NAME}_certbot
70+
volumes:
71+
- ./nginx/certbot/www:/var/www/certbot
72+
- ./nginx/certbot/conf:/etc/letsencrypt
73+
environment:
74+
- EMAIL=${EMAIL}
75+
- BASE_URL=${BASE_URL}
76+
entrypoint: >
77+
certbot certonly --webroot --webroot-path=/var/www/certbot
78+
--email ${EMAIL} --agree-tos --no-eff-email
79+
-d ${BASE_URL}
80+
depends_on:
81+
- nginx
82+
networks:
83+
- default
84+
restart: "no"
85+
86+
certbot-renew:
87+
profiles:
88+
- prod
89+
image: certbot/certbot
90+
container_name: ${PACKAGE_NAME}_certbot_renew
91+
volumes:
92+
- ./nginx/certbot/www:/var/www/certbot
93+
- ./nginx/certbot/conf:/etc/letsencrypt
94+
entrypoint: >
95+
sh -c "trap exit TERM;
96+
while :; do
97+
echo '🔄 Checking for SSL renewal...';
98+
certbot renew --webroot --webroot-path=/var/www/certbot --quiet --deploy-hook 'nginx -s reload';
99+
sleep 12h;
100+
done"
101+
depends_on:
102+
- nginx
103+
networks:
104+
- default
105+
restart: unless-stopped
106+
107+
# ====================== language image ====================== #
2108
nodejs-image:
3-
profile:
109+
profiles:
4110
- prod
5111
build:
6112
context: .
7113
dockerfile: docker/Dockerfile.nodejs
8114
image: executor-nodejs:latest
9115

10116
deno-image:
11-
profile:
117+
profiles:
12118
- prod
13119
build:
14120
context: .
15121
dockerfile: docker/Dockerfile.deno
16122
image: executor-deno:latest
17123

18124
python-image:
19-
profile:
125+
profiles:
20126
- prod
21127
build:
22128
context: .
23129
dockerfile: docker/Dockerfile.python
24130
image: executor-python:latest
25131

26132
java-image:
27-
profile:
133+
profiles:
28134
- prod
29135
build:
30136
context: .
31137
dockerfile: docker/Dockerfile.jvm
32138
image: executor-java:latest
33139

34140
kotlin-image:
35-
profile:
141+
profiles:
36142
- prod
37143
build:
38144
context: .
39145
dockerfile: docker/Dockerfile.kotlin
40146
image: executor-kotlin:latest
41147

42-
nodejs-server-image:
43-
profile:
44-
- prod
45-
- dev
46-
build:
47-
context: .
48-
dockerfile: Dockerfile
49-
image: nodejs-server-image:latest
50-
environment:
51-
- PORT=9091
52-
- HOST_PROJECT_ROOT=${PWD}
53-
ports:
54-
- "9091:9091"
55-
volumes:
56-
- /var/run/docker.sock:/var/run/docker.sock
57-
- ./temp:/app/temp
58-
networks:
59-
- app-network
60-
restart: unless-stopped
61-
62-
executeme-nginx:
63-
profile:
64-
- prod
65-
image: nginx:alpine
66-
ports:
67-
- "9292:9292"
68-
volumes:
69-
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
70-
- ./nginx/certs:/etc/nginx/certs:ro
71-
depends_on:
72-
- nodejs-server-image
73-
networks:
74-
- app-network
75-
restart: unless-stopped
76-
77148
networks:
78-
app-network:
79-
driver: bridge
149+
default:
150+
name: ${PACKAGE_NAME}_network
151+
labels:
152+
- "project=${PACKAGE_NAME}"

0 commit comments

Comments
 (0)