xModel Lite Installation
- 1 I. Server Requirements
- 1.1 1. Web Server
- 2 II. Software Requirements
- 2.1 Testing
- 2.1.1 1. NodeJS
- 2.1.2 2. MongoDB
- 2.1.3 3. Redis Server
- 2.1.4 4. FFMPEG
- 2.1.5 5. NGINX
- 2.1.6 6. Pm2
- 2.1.7 7. Yarn
- 2.1 Testing
- 3 III. Setup and Test it Locally
- 3.1 1. API
- 3.2 2. Frontend
- 3.3 3. Admin Web
- 4 IV. Setup and setup production environment with nginx and pm2
I. Server Requirements
1. Web Server
xModels supports all platforms: Windows, MacOS, Linux.
xModels needs a VPS server with at least:
4GB of RAM - recommend 8GB
40GB of HDD
1 CPU core - recommend 2 cores at least
4 domains / sub domains
api.[your-domain]and point to server IP addressadmin.[your-domain]and point to server IP addressstreaming.[your-domain]and point to server IP address[your-domain]and point to server IP address
II. Software Requirements
xModels architecture needs these softwares
NodeJS
v16.xTo install please download NodeJS here
MongoDB
v3.6To install please download mongoDB
Redis server
v2.8To install please download and setup redis
Nginx
v1.3PM2 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
Testing
From command line / terminal please run these commands to check
1. NodeJS
$ node -v
v12.16.22. MongoDB
$ mongo --version
MongoDB shell version v4.0.7
git version: 1b82c812a9c0bbf6dc79d5400de9ea99e6ffa025
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_643. Redis Server
$ redis-server --version
Redis server v=5.0.4 sha=00000000:0 malloc=libc bits=64 build=d4ba11298acbb3664. 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.1005. NGINX
$ nginx -v
nginx version: nginx/1.10.36. Pm2
$ pm2 -v
[PM2] Spawning PM2 daemon with pm2_home=/Users/xxx/.pm2
[PM2] PM2 Successfully daemonized
4.4.07. Yarn
$ yarn -v
1.16.0III. Setup and Test it Locally
We provide source code with 4 folders, check below and use in the app accordingly
userweb frontend (front office)adminbackend (back office), admin control panelapiapi of the appconfig-exampleenvproduct environment example confignginxnginx config example
1. API
Ensure
node v16.x,MongoDB,Redis server,FFMPEGandyarnare runningCD to your API folder
Run
yarnto install nodeJS dependencies
$ yarn
yarn install v1.16.0
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...Create new
.envfromconfig-example > env > api.envfile in the root dir
Content
.envlooks like below
# production or development
NODE_ENV=production
# http port
HTTP_PORT=8080
# secret which is using to generate jwt. You should change with your key
TOKEN_SECRET=qG4EjJ9xJzbfnvUKieJT
# mongo connection string. check here https://docs.mongodb.com/manual/reference/connection-string/
MONGO_URI=mongodb://localhost/xmodels
# redis server config
# Redis connection string. Pattern redis[s]://[[username][:password]@][host][:port][/db-number]
# DB-number is a integer number
REDIS_URI=redis://127.0.0.1:6379/0
# redis prefix for queue service
QUEUE_PREFIX=xmodels_queue_
# queue event service prefix
QUEUE_EVENT_PREFIX=xmodels_queue_event_
MAILER_CONCURRENCY=2
TEMPLATE_DIR=templates
# domain will be used to generate some data
DOMAIN=example.com
# public API URL
BASE_URL=https://api.example.com
# public front office URL
USER_URL=https://example.com
# redirect email after user clicks to verificaiton email link
EMAIL_VERIFIED_SUCCESS_URL=https://example.com/auth/email-verified-successCheck Migration point to seed default
Run yarn start to start application
Open browsers and run
http://localhost:8080it should show success message or Hello World!
2. Frontend
Ensure
nodejsandyarnare runningFrom frontend root directory run
yarn insall --production=falseto installnodeJSdependencies and dev dependencies
$ yarn
yarn install v1.16.0
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...Create
.envfile fromconfig-example > env > user.env. Content looks like below. Change it with your configuration accordingly
# API endpoint for server call. It can be public API or internal API
API_SERVER_ENDPOINT=http://localhost:8080
# Public API endpoint, all API in client side will use this endpoint
API_ENDPOINT=https://api.example.com
# Socket endpoint, usually it is API public endpoint
SOCKET_ENDPOINT=https://api.example.comRun
yarnstart to start applicationThen you can open browser
http://localhost:8081to see the webNote: Do not run
yarn devbecause this minified version doesn't support
3. Admin Web
Similar Frontend web, same steps.
Create
.envfile fromconfig-example > env > user.env. Content looks like below. Change it with your configuration accordingly
# API endpoint for server call. It can be public API or internal API
API_SERVER_ENDPOINT=http://localhost:8080
# Public API endpoint, all API in client side will use this endpoint
API_ENDPOINT=https://api.example.com
# Socket endpoint, usually it is API public endpoint
SOCKET_ENDPOINT=https://api.example.com
# Public site (front office site). Use to generate URL
SITE_URL=https://example.com
# max size upload validate in client side
MAX_SIZE_IMAGE=5
MAX_SIZE_FILE=100
MAX_SIZE_TEASER=200
MAX_SIZE_VIDEO=2000Run
yarnstart to start applicationThen you can open browser
http://localhost:8082to see the webNote: Do not run
yarn devbecause this minified version doesn't support
IV. Setup and setup production environment with nginx and pm2
1. API
Make sure you have installed nodeJS dependencies by
yarn installcommand. Configure it like local setup,pm2was installedIn API root directory run pm2
start yarn --interpreter bash --name api.example.com -- startto run application under port 8080
Note: If have error when starting with Pm2, please try to start without interpreter
pm2 start yarn --name api.example.com -- start2. Frontend Web
cd user web folder
Make sure you have installed nodeJS dependencies by
yarn installcommand. Configure it like local setup,pm2was installedRun
pm2 start yarn --interpreter bash --name api.example.com -- startto run application under port 8081. You can change port inpackage.jsonin start script
Note: If have error when starting with Pm2, please try to start without interpreter
pm2 start yarn --name example.com -- start3. Admin Web
cd user admin folder
Make sure you have installed nodeJS dependencies by
yarn installcommand. Configure it like local setup,pm2was installedRun pm2
start yarn --interpreter bash --name admin.example.com -- startto run application under port 8082. You can change port inpackage.jsonin start script
Note: If have error when starting with Pm2, please try to start without interpreter
pm2 start yarn --name admin.example.com -- start4. Setup Nginx
a. API
Let say our frontend code is in
/var/www/api.example.comfolder and api is running under port 8080, add new file in/etc/nginx/sites-enabled/api.example.comand content as bellowYou have to change with our server name and source code path
server {
listen 80;
root /var/www/api.example.com/public;
index index.html;
server_name api.example.com;
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
sendfile_max_chunk 512k;
client_max_body_size 5000M;
access_log off;
error_log off;
location / {
try_files $uri @app;
}
location @app {
proxy_set_header
proxy_set_header
proxy_pass
proxy_set_header
proxy_set_header
proxy_cache_bypass $http_upgrade;
# WebSocket support
proxy_connect_timeout 1d;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
}
location /.well-known {
alias /var/www/api.example.com/public/.well-known;
}
location /videos/protected/ {
auth_request /authvideo;
root /var/www/api.example.com/public/;
}
location = /authvideo {
internal;
set $query '';
if ($request_uri ~* "[^\?]+\?(.*)$") {
set $query $1;
}
proxy_pass http://localhost:8080/assets/videos/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header range "";
}
location /photos/protected/ {
auth_request /authphoto;
root /var/www/api.example.com/public/;
}
location = /authphoto {
internal;
set $query '';
if ($request_uri ~* "[^\?]+\?(.*)$") {
set $query $1;
}
proxy_pass http://localhost:8080/assets/photos/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header range "";
}
location /digital-products/protected {
auth_request /authproduct;
root /var/www/api.example.com/public/;
}
location = /authproduct {
internal;
set $query '';
if ($request_uri ~* "[^\?]+\?(.*)$") {
set $query $1;
}
proxy_pass http://localhost:8080/assets/products/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header range "";
}
location /stories/protected/ {
auth_request /authstory;
root /var/www/api.example.com/public/;
}
location = /authstory {
internal;
set $query '';
if ($request_uri ~* "[^\?]+\?(.*)$") {
set $query $1;
}
proxy_pass http://localhost:8080/stories/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header range "";
}
}b. Frontend
Let say our frontend code is in
/var/www/example.comfolder and Frontend app is running under port 8081, add new file in/etc/nginx/sites-enabled/example.comand content as bellowYou have to change with our server name and source code path
server {
listen 80;
server_name example.com;
root /var/www/example.com/public; 6
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
sendfile_max_chunk 512k;
# tuning performance for log request
access_log off;
error_log off;
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
proxy_set_header
proxy_set_header
proxy_set_header
proxy_set_header
}
location /.well-known {
alias /var/www/example.com/public/.well-known;
}
location /_next/static/ {
alias /var/www/example.com/dist/.next/static/$1;
access_log off;
expires max;
}
}c. Admin
Let say our frontend code is in
/var/www/admin.example.comfolder and Frontend app is running under port 8082, add new file in/etc/nginx/sites-enabled/admin.example.comand content as bellowYou have to change with our server name and source code path
server {
listen 80;
server_name admin.example.com;
root /var/www/admin.example.com/public;
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
sendfile_max_chunk 512k;
access_log off;
error_log off;
location / {
try_files $uri @app;
}
location @app {
proxy_set_header
proxy_set_header
proxy_pass
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
location /.well-known {
alias /var/www/admin.example.com/public/.well-known;
}
location /_next/static/ {
alias /var/www/admin.example.com/dist/.next/static/$1;
access_log off;
expires max;
}
}d. Testing
Open browser and access:
http://yourdomain.comto access web frontendOpen browser and access:
http://admin.yourdomain.comto access web admin
5. Check applications are running under pm2
Run
pm2 lsto see your applicationsRun
pm2 stop [id]to stop app orpm2 reload [id]to reloadRun applications in start up by
pm2 startupthenpm2 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
yarnmigrate to seed default values for settings and usersDefault admin:
admin@[yourdomain]with domain is in .env fileDefault password:
adminadminIf admin password is wrong, you can run node script
reset-admin-pwto reset it to adminadmin
You can change default values in
src > migrationsfolder