Installation Documentation - xScorts
- 1 I. Server requirement
- 2 II. Software requirements
- 2.1 Helpful links
- 2.2 Testing
- 2.2.1 1. NodeJS
- 2.2.2 2. MongoDB
- 2.2.3 3. Redis server
- 2.2.4 4. FFMPEG
- 2.2.5 5. NGINX
- 2.2.6 6. Pm2
- 2.2.7 7. Yarn
- 3 III. Setup and test project locally
- 3.1 1. API
- 3.2 2. User Frontend web
- 3.3 3. Admin web
- 4 IV. Setup and setup production environment with nginx
- 4.1 1. API
- 4.2 2. Frontend web
- 4.3 3. Admin web
- 4.4 4. Setup nginx
- 4.4.1 a. Api
- 4.4.2 b. Frontend
- 4.4.3 c. Admin
- 4.4.4 d. Testing
- 4.5 5. Check applications are running under pm2
- 4.6 6. Set up nginx with https
- 4.7 7. Migration
Version | Description | Date |
---|---|---|
2.0.0 | Updated software requirements for v2.1.0 | 08 Oct 2024 |
1.1 | Update nginx config | 17 Aug 2022 |
1.0 | Initial document | 30 Dec 2021 |
I. Server requirement
xScorts needs a VPS server with at least:
4GB of RAM
40GB of HDD
2 CPU core
3 domains / sub domains
api.[your-domain] and point to server IP address
admin.[your-domain] and point to server IP address
[your-domain] and point to server IP address
II. Software requirements
xScorts architecture needs these softwares
NodeJS v16.x LTS version
To install please download NodeJS here
MongoDB >= v3.6
To install please download mongoDB
Redis server >= v2.8
To install please download and setup redis
Nginx >= v1.3
PM2 is a daemon process manager that will help you manage and keep your application online 24/7
Yarn or npm to manage nodeJS package
Ensure all softwares above are running before setup source code
Helpful links
Testing
From command line / terminal please run these commands to check
1. NodeJS
$ node -v
v16.3.2
2. MongoDB
$ mongo --version
MongoDB shell version v4.0.7
git version: 1b82c812a9c0bbf6dc79d5400de9ea99e6ffa025
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_64
3. Redis server
$ redis-server --version
Redis server v=5.0.4 sha=00000000:0 malloc=libc bits=64 build=d4ba11298acbb366
4. FFMPEG
$ ffmpeg -version
fmpeg version 2.8.15-0ubuntu0.16.04.1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
5. NGINX
$ nginx -v
nginx version: nginx/1.10.3
6. Pm2
$ pm2 -v
[PM2] Spawning PM2 daemon with pm2_home=/Users/xxx/.pm2
[PM2] PM2 Successfully daemonized
4.4.0
7. Yarn
$ yarn -v
1.16.0
III. Setup and test project locally
We provide source code with 4 folders, check below and use in the app accordingly
user
web frontend (front office)admin
backend (back office), admin control panelapi
api of the appconfig-example
env
product environment example confignginx
nginx config example
1. API
Ensure
node v16.x
,MongoDB
,Redis server
,FFMPEG
andyarn
are runningCD to your API folder
Run
yarn
to install nodeJS dependencies. Make sure your NODE_ENV is notproduction
or runyarn install --production=false
to install both dependencies and devDependencies
$ yarn
yarn install v1.16.0
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
Create new
.env
fromconfig-example > env > api.env
in the root dir
Content looks like below
# production or development
NODE_ENV=production
# http port
HTTP_PORT=8080
# secret which is using to generate jwt, password, etc... You should change with your key
TOKEN_SECRET=your token secret
# mongo connection string. check here https://docs.mongodb.com/manual/reference/connection-string/
MONGO_URI=mongodb://localhost/xscorts
# redis server config
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DB=xscorts_db
REDIS_PREFIX=xscorts_queue
MAILER_CONCURRENCY=2
TEMPLATE_DIR=templates
DOMAIN=example.com
BASE_URL=https://api.example.com
USER_URL=https://example.com
EMAIL_VERIFIED_SUCCESS_URL=https://example.com/auth/email-verified-success
Check Migration point and seed default data
Run
yarn start:dev
to start development env
$ yarn start:dev
:48 PM] Starting compilation in watch mode...
[2:49:13 PM] Found 0 errors. Watching for file changes.
[Nest] 60068 - 08/03/2020, 2:49:17 PM [NestFactory] Starting Nest application...
[Nest] 60068 - 08/03/2020, 2:49:17 PM [InstanceLoader] QueueModule dependencies initialized +134ms
[Nest] 60068 - 08/03/2020, 2:49:17 PM [InstanceLoader] RedisModule dependencies initialized +0ms
[Nest] 60068 - 08/03/2020, 2:49:17 PM [InstanceLoader] HttpModule dependencies initialized +1ms
[Nest] 60068 - 08/03/2020, 2:49:17 PM [InstanceLoader] QueueModule dependencies initialized +0ms
[Nest] 60068 - 08/03/2020, 2:49:17 PM [InstanceLoader] ServeStaticModule dependencies initialized +4ms
....
Open browsers and run
http://localhost:8080
it should show success message orHello World!
2. User Frontend web
Ensure
nodejs
andyarn
are runningFrom user root directory run
yarn
to install nodeJS dependencies. Make sure your NODE_ENV is notproduction
or runyarn install --production=false
to install both dependencies and devDependencies
$ yarn
yarn install v1.16.0
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
Create
.env
file fromconfig-example > env > user.env
and edit information accordingly. Content looks like below
NODE_ENV=production
PORT=8081
# endpoint will be executed in the server side only
API_ENDPOINT=http://localhost:8080
NEXT_PUBLIC_API_ENDPOINT=https://api.example.com
NEXT_PUBLIC_SOCKET_ENDPOINT=https://api.example.com
Run
yarn run dev
to start development env
$ yarn run dev
yarn run v1.16.0
$ ts-node --project tsconfig.server.json server/index.ts
Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected.
See here for more info: https://err.sh/next.js/built-in-css-disabled
> Using external babel configuration
Then you can open browser
http://localhost:8081
to see the web
3. Admin web
Similar Frontend web, same steps.
CD to
admin
fodlerCreate
.env
file fromconfig-example > env > admin.env
and edit information accordingly. Content looks like below
NODE_ENV=production
PORT=8082
API_ENDPOINT=http://localhost:8080
NEXT_PUBLIC_API_ENDPOINT=https://api.example.com
NEXT_PUBLIC_SITE_URL=https://example.com
NEXT_PUBLIC_MAX_SIZE_IMAGE=5
NEXT_PUBLIC_MAX_SIZE_FILE=100
NEXT_PUBLIC_MAX_SIZE_TEASER=200
NEXT_PUBLIC_MAX_SIZE_VIDEO=2000
You should change default port with
yarn run dev -p 9001
then openhttp://localhost:8082
to see your admin app
IV. Setup and setup production environment with nginx
1. API
Make sure you have installed nodeJS dependencies by
yarn
command or runyarn install --production=false
to install both dependencies and devDependenciesIn API root directory, run
yarn build
$ yarn build
yarn run v1.16.0
$ rimraf dist
$ nest build && yarn copy-template
$ cp -r ./src/templates ./dist/templates
✨ Done in 22.62s
Testing by run command
yarn start:prod
ornode dist/main.js
$ yarn start
yarn run v1.16.0
$ node dist/main
[Nest] 60205 - 08/03/2020, 2:56:11 PM [NestFactory] Starting Nest application...
....
Run
pm2 start dist/main.js --name=api
to run API under background
Or run pm2 start yarn --interpreter bash --name xscorts-api -- start:prod
to run application under port 8080
Note: If have error when starting with Pm2, please try to start without interpreter
pm2 start yarn --name xscorts-api -- start:prod
2. Frontend web
Make sure you have installed nodeJS dependencies by
yarn
command or runyarn install --production=false
to install both dependencies and devDependenciesRun
yarn build
$ yarn build
yarn run v1.16.0
$ next build && tsc && tsc --project tsconfig.server.json
Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected.
See here for more info: https://err.sh/next.js/built-in-css-disabled
> Using external babel configuration
> Location: "/Users/tuong/Projects/frontend-base-reactjs/.babelrc"
Creating an optimized production build
Compiled with warnings.
chunk styles [mini-css-extract-plugin]
Conflicting order between:
* css ./node_modules/css-loader??ref--6-1!./node_modules/less-loader/dist/cjs.js??ref--6-2!./src/components/video/video.less
* css ./node_modules/css-loader??ref--6-1!./node_modules/less-loader/dist/cjs.js??ref--6-2!./src/components/common/layout/page.less
* css ./node_modules/css-loader??ref--6-1!./node_modules/less-loader/dist/cjs.js??ref--6-2!./src/components/common/base/loader.less
....
Testing by run
yarn start
ornode dist/index.js
it should show success message
$ yarn start
yarn run v1.16.0
next start
ready - started server on http://localhost:3000
Run
export NODE_ENV=production
Run
export PORT=8081
Run
pm2 start dist/index.js --name xscorts-web -- start
to run application
3. Admin web
Similar Frontend web, same steps. Make sure all node dependencies are installed or run
yarn install --production=false
to install both dependencies and devDependenciesRun
yarn build
Run
export NODE_ENV=production
Run
export PORT=8082
Run
pm2 start dist/index.js --name xscorts-admin -- start
to run application
4. Setup nginx
a. Api
Let say our api code is in
/var/www/api.xscorts.info
folder and api is running under port 8080, add new file in/etc/nginx/sites-enabled/api.xscorts.info
and content as bellowYou have to change with our server name and source code path
server {
listen 80 ;
root /var/www/api.xscorts.info/public;
index index.html;
server_name api.xscorts.info;
# reduce the data that needs to be sent over network -- for testing environment
gzip on;
# gzip_static on;
gzip_min_length 10240;
gzip_comp_level 1;
gzip_vary on;
gzip_disable msie6;
gzip_proxied expired no-cache no-store private auth;
gzip_types
# text/html is always compressed by HttpGzipModule
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# allow the server to close connection on non responding client, this will free up memory
reset_timedout_connection on;
# cache informations about FDs, frequently accessed files
# can boost performance, but you need to test those values
open_file_cache max=200000 inactive=300s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# depend on server, we can change 128k, 256k, 512k...
sendfile_max_chunk 1m;
client_max_body_size 2000M;
# to boost I/O on HDD we can disable access logs
access_log off;
error_log off;
location / {
try_files $uri @app;
}
location @app {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
# WebSocket support
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
}
location /.well-known {
alias /var/www/api.example.com/public/.well-known;
}
}
b. Frontend
Let say our frontend code is in
/var/www/xscorts.info
folder and Frontend app is running under port 8081, add new file in/etc/nginx/sites-enabled/xscorts.info
and content as bellowYou have to change with our server name and source code path
server {
listen 80;
server_name xscorts.info;
root /var/www/xscorts.info/public;
# cache informations about FDs, frequently accessed files
# can boost performance, but you need to test those values
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# to boost I/O on HDD we can disable access logs
access_log off;
error_log off;
# copies data between one FD and other from within the kernel
# faster than read() + write()
sendfile on;
# send headers in one piece, it is better than sending them one by one
tcp_nopush on;
# don't buffer data sent, good for small data bursts in real time
tcp_nodelay on;
# reduce the data that needs to be sent over network -- for testing environment
gzip on;
# gzip_static on;
gzip_min_length 10240;
gzip_comp_level 1;
gzip_vary on;
gzip_disable msie6;
gzip_proxied expired no-cache no-store private auth;
gzip_types
# text/html is always compressed by HttpGzipModule
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# allow the server to close connection on non responding client, this will free up memory
reset_timedout_connection on;
# request timed out -- default 60
client_body_timeout 10;
# if client stop responding, free up memory -- default 60
send_timeout 2;
# server will close connection after this time -- default 75
keepalive_timeout 30;
# number of requests client can make over keep-alive -- for testing environment
keepalive_requests 100000;
types_hash_max_size 2048;
sendfile_max_chunk 512k;
client_max_body_size 200M;
location / {
try_files $uri @app;
}
location @app {
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /.well-known {
alias /var/www/api.example.com/public/.well-known;
}
location /_next/static/ {
alias /var/www/xscorts.info/.next/static/$1;
access_log off;
expires max;
}
}
c. Admin
Let say our frontend code is in
/var/www/admin.xscorts.info
folder and Frontend app is running under port 8082, add new file in/etc/nginx/sites-enabled/admin.xscorts.info
and content as bellowYou have to change with our server name and source code path
server {
listen 80;
server_name admin.xscorts.info;
root /var/www/admin.xscorts.info/public;
# cache informations about FDs, frequently accessed files
# can boost performance, but you need to test those values
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# to boost I/O on HDD we can disable access logs
access_log off;
# copies data between one FD and other from within the kernel
# faster than read() + write()
sendfile on;
# send headers in one piece, it is better than sending them one by one
tcp_nopush on;
# don't buffer data sent, good for small data bursts in real time
tcp_nodelay on;
# reduce the data that needs to be sent over network -- for testing environment
gzip on;
# gzip_static on;
gzip_min_length 10240;
gzip_comp_level 1;
gzip_vary on;
gzip_disable msie6;
gzip_proxied expired no-cache no-store private auth;
gzip_types
# text/html is always compressed by HttpGzipModule
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# allow the server to close connection on non responding client, this will free up memory
reset_timedout_connection on;
# request timed out -- default 60
client_body_timeout 10;
# if client stop responding, free up memory -- default 60
send_timeout 2;
# server will close connection after this time -- default 75
keepalive_timeout 30;
# number of requests client can make over keep-alive -- for testing environment
keepalive_requests 100000;
types_hash_max_size 2048;
sendfile_max_chunk 512k;
client_max_body_size 200M;
location / {
try_files $uri @app;
}
location @app {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:8082;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
location /.well-known {
alias /var/www/api.example.com/public/.well-known;
}
location /_next/static/ {
alias /var/www/admin.xscorts.info/.next/static/$1;
access_log off;
expires max;
}
}
d. Testing
Open browser and access: http://yourdomain.com to access web frontend
Open browser and access: http://admin.yourdomain.com to access web admin
5. Check applications are running under pm2
Run
pm2 ls
to see your applicationsRun
pm2 stop [id]
to stop app orpm2 reload [id]
to reloadRun applications in start up by
pm2 startup
thenpm2 save
6. Set up nginx with https
Check here to setup https with nginx
Setup https with Certbot nginx
7. Migration
From API root directory run
yarn migrate
to seed default values for settings and usersDefault admin: admin@[yourdomain] with domain is in .env file
Default password: adminadmin
If admin password is wrong, you can run
node script reset-admin-pw
to reset it to adminadmin
You can change default values in
src > migrations
folder