/
xModel Lite Installation

xModel Lite Installation

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 address

    • admin.[your-domain] and point to server IP address

    • streaming.[your-domain] and point to server IP address

    • [your-domain] and point to server IP address

II. Software Requirements

xModels architecture needs these softwares

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.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 it 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 panel

  • api api of the app

  • config-example

    • env product environment example config

    • nginx nginx config example

1. API

  • Ensure node v16.x, MongoDB, Redis server, FFMPEG and yarn are running

  • CD to your API folder

  • Run yarn to install nodeJS dependencies

$ yarn yarn install v1.16.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies...
  • Create new .env from config-example > env > api.env file in the root dir

  • Content .env looks 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-success
  • Check Migration point to seed default

  • Run yarn start to start application

  • Open browsers and run http://localhost:8080 it should show success message or Hello World!

2. Frontend

  • Ensure nodejs and yarn are running

  • From frontend root directory run yarn insall --production=false to install nodeJS dependencies and dev dependencies

$ yarn yarn install v1.16.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies...
  • Create .env file from config-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
  • Run yarn start to start application

  • Then you can open browser http://localhost:8081 to see the web

  • Note: Do not run yarn dev because this minified version doesn't support

3. Admin Web

  • Similar Frontend web, same steps.

  • Create .env file from config-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=2000
  • Run yarn start to start application

  • Then you can open browser http://localhost:8082 to see the web

  • Note: Do not run yarn dev because 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 install command. Configure it like local setup, pm2 was installed

  • In API root directory run pm2 start yarn --interpreter bash --name api.example.com -- start to 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 -- start

2. Frontend Web

  • cd user web folder

  • Make sure you have installed nodeJS dependencies by yarn install command. Configure it like local setup, pm2 was installed

  • Run pm2 start yarn --interpreter bash --name api.example.com -- start to run application under port 8081. You can change port in package.json in start script

Note: If have error when starting with Pm2, please try to start without interpreter

pm2 start yarn --name example.com -- start

3. Admin Web

  • cd user admin folder

  • Make sure you have installed nodeJS dependencies by yarn install command. Configure it like local setup, pm2 was installed

  • Run pm2 start yarn --interpreter bash --name admin.example.com -- start to run application under port 8082. You can change port in package.json in start script

Note: If have error when starting with Pm2, please try to start without interpreter

pm2 start yarn --name admin.example.com -- start

4. Setup Nginx

a. API

  • Let say our frontend code is in /var/www/api.example.com folder and api is running under port 8080, add new file in /etc/nginx/sites-enabled/api.example.com and content as bellow

  • You 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.com folder and Frontend app is running under port 8081, add new file in /etc/nginx/sites-enabled/example.com and content as bellow

  • You 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.com folder and Frontend app is running under port 8082, add new file in /etc/nginx/sites-enabled/admin.example.com and content as bellow

  • You 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.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 applications

  • Run pm2 stop [id] to stop app or pm2 reload [id] to reload

  • Run applications in start up by pm2 startup then pm2 save

6. Set up nginx with https

7. Migration

  • From API root directory run yarn migrate to seed default values for settings and users

    • Default 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

Related content