docker file & compose setup

This commit is contained in:
Mathieu Lussier 2024-07-05 15:34:48 -04:00
parent 748cc21b95
commit 934809a651
Signed by: mathieulussier
GPG Key ID: EF8AC4E6BA8BCAB3
15 changed files with 1741 additions and 96 deletions

View File

@ -18,4 +18,6 @@ data
build build
dist
samples samples

View File

@ -4,10 +4,10 @@ NODE_ENV=development
WEBHOOK_SHARED_KEY=mykey WEBHOOK_SHARED_KEY=mykey
# JWT # JWT
JWT_TOKEN_SECRET=JWT_TOKEN_SECRET JWT_TOKEN_SECRET=jwtSecret
JWT_ACCESS_TOKEN_EXPIRES_IN=5m JWT_ACCESS_TOKEN_EXPIRES_IN=5m
JWT_REFRESH_TOKEN_EXPIRES_IN=30d JWT_REFRESH_TOKEN_EXPIRES_IN=30d
# Redis # Redis
REDIS_HOST=localhost REDIS_HOST=redis
REDIS_PORT=6379 REDIS_PORT=6379

View File

@ -1,21 +1,17 @@
FROM node:20-alpine FROM node:18.20.2-buster
WORKDIR /app WORKDIR /app
ENV PATH /app/bin:$PATH
COPY package.json . COPY package*.json .
COPY package-lock.json .
RUN npm install --silent RUN npm install --silent
COPY src ./src COPY . .
COPY public ./public
COPY db ./db
COPY configs ./configs
COPY bin ./bin
COPY tsconfig.json .
COPY .env.development .
COPY .sequelizerc .
EXPOSE 3000 EXPOSE 3000
CMD ["npm", "run", "dev"] RUN chmod +x /app/bin/start_server.sh
RUN chmod +x /app/bin/www
CMD ["start_server.sh", "--env", "development"]

View File

@ -1,25 +1,38 @@
FROM node:20-alpine FROM node:18.20.2-buster as build
WORKDIR /app WORKDIR /src
COPY package.json . COPY package*.json .
COPY package-lock.json .
RUN npm install --silent RUN npm install --silent
COPY src ./src COPY . .
COPY public ./public
COPY db ./db
COPY configs ./configs
COPY bin ./bin
COPY tsconfig.json .
COPY .env.production .
COPY .sequelizerc .
RUN npm run build RUN npm run build
FROM node:18.20.2-buster as production
WORKDIR /app
ENV PATH /app/bin:$PATH
COPY --from=build /src/dist /app/dist
COPY --from=build /src/package*.json /app/
COPY --from=build /src/bin /app/bin
COPY --from=build /src/configs /app/configs
COPY --from=build /src/db /app/db
COPY --from=build /src/private /app/private
COPY --from=build /src/public /app//public
COPY --from=build /src/scripts /app/scripts
COPY --from=build /src/.sequelizerc /app/.sequelizerc
COPY --from=build /src/.env.production /app/.env.production
RUN rm -rf /app/dist/__test__
RUN npm ci --omit=dev
EXPOSE 3000 EXPOSE 3000
RUN chmod +x ./bin/start_server.sh RUN chmod +x /app/bin/start_server.sh
RUN chmod +x /app/bin/www
CMD ["sh", "./bin/start_server.sh"] CMD ["start_server.sh", "--env", "production"]

View File

@ -10,7 +10,7 @@ Todo
Application: Application:
- [ ] Create an error handler wrapper for all the routes. - [ ] Create an error handler wrapper for all the routes.
- [ ] On 1.0.0 release, finish the docker file and docker-compose file. - [x] Create docker file and docker-compose file.
- [ ] Create tests using samples data - [ ] Create tests using samples data
- [ ] Create seed data - [ ] Create seed data

31
bin/start_server.sh Normal file → Executable file
View File

@ -1,4 +1,31 @@
#!/bin/sh #!/bin/sh
npx sequelize db:migrate --env production # check if argument --env is passed and set variable to the value of --env else set variable to development
node --trace-deprecation -r ts-node/register/transpile-only -r tsconfig-paths/register bin/node-api-template if [ "$1" = "--env" ]; then
ENV=$2
else
ENV="development"
fi
# check if the value of --env is either development or production
if [ "$ENV" != "development" ] && [ "$ENV" != "production" ]; then
echo "Invalid environment. Please use either development or production"
exit 1
fi
# check if the value of --env is production
if [ "$ENV" = "production" ]; then
npx sequelize db:create --env $ENV
npx sequelize db:migrate --env $ENV
npx sequelize db:seed:all --env $ENV
www
exit 0
fi
# check if the value of --env is development
if [ "$ENV" = "development" ]; then
npx sequelize db:create --env $ENV
npx sequelize db:migrate --env $ENV
npm run dev
exit 0
fi

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
require('@configs/env.config')('production'); require('../configs/env.config')('production');
const logger = require('../dist/utils/logger.util').default; const logger = require('../dist/utils/logger.util').default;
const App = require('../dist/app').default; const App = require('../dist/app').default;
const app = new App().app; const app = new App().app;

View File

@ -1,6 +1,6 @@
{ {
"development": { "development": {
"username": "root", "username": "postgres",
"password": "", "password": "",
"database": "node_api_template_development", "database": "node_api_template_development",
"host": "127.0.0.1", "host": "127.0.0.1",
@ -8,7 +8,7 @@
"dialect": "postgres" "dialect": "postgres"
}, },
"test": { "test": {
"username": "root", "username": "postgres",
"password": "", "password": "",
"database": "node_api_template_test", "database": "node_api_template_test",
"host": "127.0.0.1", "host": "127.0.0.1",
@ -16,7 +16,7 @@
"dialect": "postgres" "dialect": "postgres"
}, },
"production": { "production": {
"username": "root", "username": "postgres",
"password": "", "password": "",
"database": "node_api_template_production", "database": "node_api_template_production",
"host": "127.0.0.1", "host": "127.0.0.1",

View File

@ -23,12 +23,12 @@ http {
server_name localhost; server_name localhost;
location / { location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://api-server; proxy_pass http://api-server;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
} }
} }
@ -40,5 +40,4 @@ http {
sendfile on; sendfile on;
keepalive_timeout 65; keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
} }

View File

@ -1,24 +1,25 @@
version: '3.9'
services: services:
redis: redis:
container_name: redis container_name: node_api_redis
image: redis:6.2.14-alpine image: redis:6.2.14-alpine
healthcheck: healthcheck:
test: [ "CMD", "redis-cli", "ping" ] test: ["CMD", "redis-cli", "ping"]
timeout: 10s interval: 10s
retries: 10 timeout: 5s
retries: 5
ports: ports:
- 6379:6379 - 6379:6379
expose: expose:
- 6379 - 6379
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
server: server:
container_name: server container_name: node_api_server
image: pandrive:0.1.0 build:
context: .
dockerfile: Dockerfile.development
volumes: volumes:
- .:/app - .:/app
ports: ports:
@ -27,7 +28,9 @@ services:
- 3000 - 3000
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
environment:
- REDIS_HOST=redis
links: links:
- database - database
- redis - redis
@ -38,29 +41,30 @@ services:
condition: service_healthy condition: service_healthy
database: database:
container_name: database container_name: node_api_database
image: mysql:8 image: postgres:16.3
user: postgres
healthcheck: healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "database" ] test: ["CMD-SHELL", "pg_isready"]
timeout: 10s interval: 10s
retries: 10 timeout: 5s
retries: 5
cap_add: cap_add:
- SYS_NICE - SYS_NICE
ports: ports:
- 3306:3306 - 5432:5432
expose: expose:
- 3306 - 5432
volumes: volumes:
- db:/var/lib/mysql - db:/var/lib/postgresql/data
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
environment: environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - POSTGRES_PASSWORD=myPassword
- MYSQL_DATABASE=${MYSQL_DATABASE}
networks: networks:
x_trait_network: node_api_network:
driver: bridge driver: bridge
volumes: volumes:

View File

@ -1,8 +1,6 @@
version: '3.9'
services: services:
proxy: proxy:
container_name: proxy container_name: node_api_proxy
image: nginx:alpine image: nginx:alpine
ports: ports:
- 80:80 - 80:80
@ -14,37 +12,42 @@ services:
- ./configs/nginx.conf:/etc/nginx/nginx.conf - ./configs/nginx.conf:/etc/nginx/nginx.conf
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
depends_on: depends_on:
- server - server
links: links:
- server - server
redis: redis:
container_name: redis container_name: node_api_redis
image: redis:6.2.14-alpine image: redis:6.2.14-alpine
healthcheck: healthcheck:
test: [ "CMD", "redis-cli", "ping" ] test: ["CMD", "redis-cli", "ping"]
timeout: 10s interval: 10s
retries: 10 timeout: 5s
retries: 5
ports: ports:
- 6379:6379 - 6379:6379
expose: expose:
- 6379 - 6379
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
server: server:
container_name: server container_name: node_api_server
image: pandrive:0.1.0 build:
context: .
dockerfile: Dockerfile.production
ports: ports:
- 3000:3000 - 3000:3000
expose: expose:
- 3000 - 3000
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
environment:
- REDIS_HOST=redis
links: links:
- database - database
- redis - redis
@ -55,29 +58,30 @@ services:
condition: service_healthy condition: service_healthy
database: database:
container_name: database container_name: node_api_database
image: mysql:8 image: postgres:16.3
user: postgres
healthcheck: healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "database" ] test: ["CMD-SHELL", "pg_isready"]
timeout: 10s interval: 10s
retries: 10 timeout: 5s
retries: 5
cap_add: cap_add:
- SYS_NICE - SYS_NICE
ports: ports:
- 3306:3306 - 5432:5432
expose: expose:
- 3306 - 5432
volumes: volumes:
- db:/var/lib/mysql - db:/var/lib/postgresql/data
restart: always restart: always
networks: networks:
- x_trait_network - node_api_network
environment: environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - POSTGRES_PASSWORD=myPassword
- MYSQL_DATABASE=${MYSQL_DATABASE}
networks: networks:
x_trait_network: node_api_network:
driver: bridge driver: bridge
volumes: volumes:

1607
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,9 @@
"description": "node-api-template is a micro service api template.", "description": "node-api-template is a micro service api template.",
"main": "bin/node-api-template", "main": "bin/node-api-template",
"scripts": { "scripts": {
"start": "node --trace-deprecation -r ts-node/register/transpile-only -r tsconfig-paths/register bin/node-api-template", "start": "node --trace-deprecation bin/node-api-template",
"dev": "npx nodemon", "dev": "npx nodemon",
"build": "npx rimraf dist && npx tsc", "build": "npx rimraf dist && npx tsc --project tsconfig.json && tscpaths -p tsconfig.json -s ./src -o ./dist",
"clean": "npx rimraf dist", "clean": "npx rimraf dist",
"skip:postinstall": "npx sequelize db:migrate", "skip:postinstall": "npx sequelize db:migrate",
"db:setup:production": "npx sequelize db:create --env production && npx sequelize db:migrate --env production && npx sequelize db:seed:all --env production", "db:setup:production": "npx sequelize db:create --env production && npx sequelize db:migrate --env production && npx sequelize db:seed:all --env production",
@ -66,7 +66,10 @@
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"supertest": "^6.3.4", "supertest": "^6.3.4",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",
"typescript": "^5.3.3" "ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tscpaths": "^0.0.9",
"typescript": "^5.5.3"
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.7", "axios": "^1.6.7",
@ -91,8 +94,6 @@
"sequelize": "^6.37.3", "sequelize": "^6.37.3",
"sequelize-cli": "^6.6.2", "sequelize-cli": "^6.6.2",
"sequelize-typescript": "^2.1.6", "sequelize-typescript": "^2.1.6",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"winston": "^3.13.0", "winston": "^3.13.0",
"winston-daily-rotate-file": "^5.0.0" "winston-daily-rotate-file": "^5.0.0"
} }

View File

@ -71,7 +71,7 @@ const errorDailyRotateTransport = new DailyRotateFile({
}); });
const logger = createLogger({ const logger = createLogger({
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug', level: process.env.NODE_ENV === 'production' ? 'http' : 'debug',
silent: process.env.NODE_ENV === 'test', silent: process.env.NODE_ENV === 'test',
format: format.combine( format: format.combine(
format.timestamp({ format.timestamp({

View File

@ -28,7 +28,7 @@
"@middlewares/*": ["src/middlewares/*"], "@middlewares/*": ["src/middlewares/*"],
"@events": ["src/events/*"], "@events": ["src/events/*"],
"@base": ["src/base/*"], "@base": ["src/base/*"],
"@content": ["src/content/*"], "@content": ["src/content/*"]
}, },
"resolveJsonModule": true, "resolveJsonModule": true,