Installation Guide for xCams
- 1 I. Server Requirements
- 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. User Frontend Web
- 3.3 3. Admin
- 4 IV. Setup production environment with NGINX
I. Server Requirements
xCams supports all platforms: Windows, MacOS, Linux. There are 2 web service and streaming media service we need to setup
1. Web service
xCams V3 needs a VPS server with at least:
2GB of RAM - recommend 4GB
40GB of HDD
1 CPU core - recommend 2 cores at least
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
2. Streaming Server
xCams V3 use Ant media as a media streaming service for broadcast, private and group chat. Recommend server with CPU optimized plan at least
Ubuntu 18.04
4GB of RAM
2 CPU core
streaming domain like streaming.[your-domain]
Note: Ant media is able to be installed on Ubuntu 18.04, Ubuntu 20.04 or CentOS 8 only
II. Software Requirements
xCams V3 architecture needs these softwares
NodeJS LTS >= v20.11.1
To install please download NodeJS here
MongoDB >= v4.2
To install please download mongoDB
Redis server >= v7.x
To install please download and setup redis
Nginx >= v1.3 with http-auth-request module has been enabled
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
Testing
From command line / terminal please run these commands to check
1. NodeJS
$ node -v
v21.2.12. MongoDB
$ mongo --version
MongoDB shell version v5.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=7.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 v12.x,MongoDB,Redis server,FFMPEGandyarnare runningCD to your API folder
Run
yarnto install nodeJS dependencies. Make sure your NODE_ENV is notproductionor runyarn install --production=falseto 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
.envfromconfig-example > env > api.envfile in the root dir
Open file
.envand change config accordingly. The config looks like below
NODE_ENV=production
# Change with your custom HTTP port
HTTP_PORT=8080
# Change secret with your key
TOKEN_SECRET=1213456
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DB=0
REDIS_PREFIX=bee_queue
# Change mongo uri correctly. Read more about connection string here https://docs.mongodb.com/manual/reference/connection-string/
MONGO_URI=mongodb://localhost/xcams-v3
# Use for seed and some features, change with your domain without http(s)://
DOMAIN=yourdomain.com
BASE_URL=http://localhost:9000
USER_URL=http://yourdomain.comOpen browsers and run
http://localhost:8080it should show success message orHello World!
2. User Frontend Web
CD to
userfolderRun
yarnto install nodeJS dependencies. Make sure your NODE_ENV is notproductionor runyarn install --production=falseto install both dependencies and devDependencies
$ yarn
yarn install v1.16.0
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...Create file
.envfromconfig-example > env > user.envand update your config accordingly. Config looks like below
# http port
PORT=8081
NEXT_PUBLIC_DEBUG=false
# api endpoint we can call in the server side, if single server it can run to api:port without proxy
API_ENDPOINT=http://localhost:8080
NEXT_PUBLIC_API_ENDPOINT=http://localhost:8080
NEXT_PUBLIC_SOCKET_ENDPOINT=http://localhost:8080
# upload file
NEXT_PUBLIC_MAX_VIDEO_BITRATE_KBPS=900
NEXT_PUBLIC_IMAGE_ACCPET=.jpeg, .jpg, .png
NEXT_PUBLIC_MAXIMUM_SIZE_UPLOAD_AVATAR=2Run
yarn run devto 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 configurationThen you can open browser
http://localhost:8081to see the web
3. Admin
Similar Frontend web, same steps. but create
.envfromconfig-example > env > admin.envRun
yarn devthen openhttp://localhost:8082to see your admin app
IV. Setup production environment with NGINX
1. API
Deploy / copy your api folder to
/var/www/api.example.comCD to
/var/www/api.example.comand install nodeJS dependencies byyarncommand. Setup.envfile accordinglyInstall
pm2(check softwares point)Make sure you have installed nodeJS dependencies by
yarncommand or runyarn install --production=falseto install both dependencies and devDependenciesChange port to 8080 in .env file or
export HTTP_PORT=8080In 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.62sTesting by run command
yarn start:prodornode 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
export NODE_ENV=productionRun
pm2 start dist/main.js --name=apito run API under background
Or run pm2 start yarn --interpreter bash --name xcams-v3-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 xcams-v3-api -- start:prod2. Frontend Web
Deploy / copy your user folder to
/var/www/example.comCD to
/var/www/example.comand install nodeJS dependencies byyarncommand. Setup.envfile accordinglyInstall
pm2(check softwares point)Make sure you have installed nodeJS dependencies and devDependencies by
yarncommand or runyarn install --production=falseto 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
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 startornode dist/index.jsit should show success message
$ yarn start
yarn run v1.16.0
next start
ready - started server on http://localhost:3000Run
export NODE_ENV=productionRun
export PORT=8081Run
pm2 start dist/index.js --name xcams-v3-web -- startto run application
3. Admin
Similar as Frontend web, same steps.
Deploy / copy your user folder to
/var/www/admin.example.comCD to
/var/www/admin.example.comand install nodeJS dependencies byyarncommand. Setup.envfile accordinglyInstall
pm2(check softwares point)Make sure you have installed nodeJS dependencies and devDependencies by
yarncommand or runyarn install --production=falseto install both dependencies and devDependenciesRun
yarn buildRun
export NODE_ENV=productionRun
export PORT=8082If have dist folder after build, run
pm2 start dist/index.js --name xcams-v3-admin -- startto run applicationOr run
pm2 start yarn --interpreter bash --name xcams-v3-admin -- start -p 8082to run application under port 8080Note: If have error when starting with Pm2, please try to start without interpreter
pm2 start yarn --name xcams-v3-admin -- start -p 8082
4. Setup nginx
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 512;
client_max_body_size 2000M;
# tuning performance for log request
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;
}
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/user/performer-assets/videos/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
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/performer/performer-assets/photos/auth/check?$query;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
}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;
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 512;
# 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 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/example.com/public/.well-known;
}
location /_next/static/ {
alias /var/www/example.com/dist/.next/static/$1;
access_log off;
expires max;
}
location /static/ {
alias /var/www/example.com/public/static/$1;
expires max;
autoindex off;
}
}Note
if have dist folder after build, the
location /_next/static/should bealias /var/www/example.com/dist/.next/static/$1;If don’t have dist folder, check and update
location /_next/static/toealias /var/www/example.com/.next/static/$1;
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 512;
# tuning performance for log request
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:8082;
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/.next/static/$1;
access_log off;
expires max;
}
location /static/ {
alias /var/www/admin.example.com/public/static/$1;
expires max;
autoindex off;
}
}Note
if have dist folder after build, the
location /_next/static/should bealias /var/www/admin.example.com/dist/.next/static/$1;If don’t have dist folder, check and update
location /_next/static/toealias /var/www/example.com/.next/static/$1;
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 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, open .env and edit DOMAIN value to your domain (without protocol eg http://example.com ). Run
yarn migrate(if command not found, try to check package.json file and see if havescript:migratecommand instead) 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-pwto reset it toadminadmin
You can change default values in src > migrations folder