Server deployment stuff
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ mobile/ios/**/xcuserdata/
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
local-*.json*
|
||||||
|
|||||||
132
README.md
132
README.md
@@ -4,11 +4,139 @@ This is the repository for the Deighton AR Training System.
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Ensure the [snap-tools]() are installed. Then clone the repository, and from the root do:
|
### Pre-requisites
|
||||||
|
|
||||||
|
Install locally:
|
||||||
|
|
||||||
|
- NodeJS
|
||||||
|
- MongoDB
|
||||||
|
- RabbitMQ
|
||||||
|
- Redis
|
||||||
|
|
||||||
|
The backend systems for this project have been developed and tested on macOS and Ubuntu systems.
|
||||||
|
|
||||||
|
Follow the instructions for additional dependencies for the [`canvas`](https://www.npmjs.com/package/canvas) NPM package.
|
||||||
|
|
||||||
|
For iOS development install Xcode. For Android development install Android Studio.
|
||||||
|
|
||||||
|
### Website, Server and Mobile Bundler
|
||||||
|
|
||||||
|
Ensure the [snap-tool](https://www.npmjs.com/package/snap-tool) is installed with `npm install -g snap-tool`.
|
||||||
|
|
||||||
|
Clone this repository, and from the root do:
|
||||||
|
|
||||||
```
|
```
|
||||||
snap install
|
snap install
|
||||||
snap start
|
snap start
|
||||||
```
|
```
|
||||||
|
|
||||||
This will start the website, server and mobile app.
|
This will start the website, server and the `Metro` bundler for development builds of the mobile apps.
|
||||||
|
|
||||||
|
### iOS App
|
||||||
|
|
||||||
|
You'll need Xcode fully installed and running. To run the iOS mobile app, start Xcode, open the `DeightonAR.xcproject`, plug in a iPhone and run the project.
|
||||||
|
|
||||||
|
### Android App
|
||||||
|
|
||||||
|
To run the Android mobile app, start Android Studio, open the `mobile/android` project, plug in an Android device and run the project.
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
### Website
|
||||||
|
|
||||||
|
To deploy the website for the 1st time do the following.
|
||||||
|
|
||||||
|
- Install `nginx`, `mongodb`, `rabbitmq` and configure as desired.
|
||||||
|
- Order SSL certificate for site and install under `/etc/nginx/ssl`.
|
||||||
|
- Install `.conf` file for the site (see below for example)
|
||||||
|
|
||||||
|
The `.conf` file for the site will look something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name dar.kss.us.com;
|
||||||
|
ssl_certificate /etc/nginx/ssl/dar_kss_us_com_chained.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/dar_kss_us_com.key;
|
||||||
|
ssl_session_cache shared:SSL:1m;
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
root /home/ubuntu/deighton-ar/website;
|
||||||
|
|
||||||
|
# Any route that starts with /api/ is for the backend
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:3001/;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_redirect off; # The backend doesn't redirect
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Server $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Any route containing a file extension
|
||||||
|
location ~ ^.+\..+$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Any route that doesn't have a file extension
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `nginx -t` to check configuration, then `nginx -s reload` to load it. API service will need to be set up to login (see next section).
|
||||||
|
|
||||||
|
Create `admin` and `user` users with passwords for the MongoDB database.
|
||||||
|
|
||||||
|
Install the `deighton-ar.service` file by copying it to the `/lib/systemd/system` directory and run `sudo systemctl --now enable deighton-ar` to start the service.
|
||||||
|
|
||||||
|
Create a `service/config/local-production.json5` file an insert an MongoDB URI with appropriate password.
|
||||||
|
|
||||||
|
For subsequent deployments, you can simply run:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd website
|
||||||
|
npm run build
|
||||||
|
npm run deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service
|
||||||
|
|
||||||
|
These instructions are for installation on Ubuntu. See [Install_Ubuntu_16.04_LTS_Service_Instance](https://github.com/jlyonsmith/HowTo/blob/master/Install_Ubuntu_16.04_LTS_Service_Instance.md) for detailed instructions on setting up a system appropriately.
|
||||||
|
|
||||||
|
First, create a log file directories:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo mkdir /var/log/deighton-ar
|
||||||
|
sudo chown ubuntu:ubuntu /var/log/deighton-ar
|
||||||
|
```
|
||||||
|
|
||||||
|
Then do:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd server
|
||||||
|
npm run build
|
||||||
|
npm run deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, on the server run:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### iOS App
|
||||||
|
|
||||||
|
You'll need an Apple Developer account. Set up appropriate AppID's in the developer port with plus signing keys installed correctly. Adjust project to use appropriate siging keys.
|
||||||
|
|
||||||
|
TBD.
|
||||||
|
|
||||||
|
### Android App
|
||||||
|
|
||||||
|
TBD.
|
||||||
|
|||||||
6
server/.rsync-exclude
Normal file
6
server/.rsync-exclude
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.*
|
||||||
|
package-lock.json
|
||||||
|
src/
|
||||||
|
scratch/
|
||||||
|
node_modules/
|
||||||
|
local-*
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
awsConfig: {
|
|
||||||
accessKeyId: 'AKIAJUP6XRVYDAXNTUNA',
|
|
||||||
secretAccessKey: 'hbZpkr9QLMivVK5oIGlnSa18ivqAYBPTdoUFYDqt',
|
|
||||||
region: 'us-west-2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
logDir: '/var/log/deighton-ar',
|
logDir: '/var/log/deighton-ar',
|
||||||
api: {
|
api: {
|
||||||
port: '3001',
|
port: '3005',
|
||||||
loginKey: '*',
|
loginKey: '*',
|
||||||
uploadTimout: 120,
|
uploadTimout: 120,
|
||||||
maxEmailTokenAgeInHours: 36,
|
maxEmailTokenAgeInHours: 36,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ User=ubuntu
|
|||||||
Group=ubuntu
|
Group=ubuntu
|
||||||
WorkingDirectory=/home/ubuntu/deighton-ar/server
|
WorkingDirectory=/home/ubuntu/deighton-ar/server
|
||||||
Environment='NODE_ENV=production'
|
Environment='NODE_ENV=production'
|
||||||
ExecStart=/usr/bin/node src/server.js
|
ExecStart=/usr/bin/node dist/server.js
|
||||||
Restart=on-abort
|
Restart=on-abort
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
script_dir=$(dirname $0)
|
script_dir=$(dirname $0)
|
||||||
script="${script_dir}/src/bin/$1"
|
script="${script_dir}/dist/bin/${1}.js"
|
||||||
|
|
||||||
if [[ -z "$1" ]]; then
|
if [[ -z "$1" ]]; then
|
||||||
echo "usage: $(basename $0) <command>"
|
echo "usage: $(basename $0) <command>"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available scripts are"
|
echo "Available commands are"
|
||||||
ls -1 ${script_dir}/src/bin
|
echo ""
|
||||||
|
find ${script_dir}/dist/bin -name \*.js -exec basename {} .js \;
|
||||||
exit -1
|
exit -1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# For scripts that need config access
|
# For scripts that need config access
|
||||||
export NODE_CONFIG_DIR="${script_dir}/config"
|
export NODE_CONFIG_DIR="${script_dir}/config"
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "babel-node src/server.js",
|
"start": "babel-node src/server.js",
|
||||||
"start:prod": "NODE_ENV=production npm start",
|
"start:prod": "NODE_ENV=production node dist/server.js",
|
||||||
"build": "babel src -d dist -s",
|
"build": "rm -rf dist && babel src -d dist -s",
|
||||||
"serve": "NODE_ENV=production node dist/server.js",
|
"deploy": "rsync -vr -e ssh --exclude-from .rsync-exclude * ubuntu@tmr:deighton-ar/server/",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"actor:api": "monzilla 'src/api/**/*.js:src/database/**/*.js' -- babel-node src/api/index.js",
|
"actor:api": "monzilla 'src/api/**/*.js:src/database/**/*.js' -- babel-node src/api/index.js",
|
||||||
"actor:api:debug": "babel-node --inspect-brk src/api/index.js",
|
"actor:api:debug": "babel-node --inspect-brk src/api/index.js",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import util from 'util'
|
|||||||
|
|
||||||
import autoBind from 'auto-bind2'
|
import autoBind from 'auto-bind2'
|
||||||
|
|
||||||
class SendMessageTool {
|
class AddUserTool {
|
||||||
constructor(toolName, log) {
|
constructor(toolName, log) {
|
||||||
autoBind(this)
|
autoBind(this)
|
||||||
this.toolName = toolName
|
this.toolName = toolName
|
||||||
@@ -20,7 +20,9 @@ class SendMessageTool {
|
|||||||
async run() {
|
async run() {
|
||||||
const mongoUri = config.get('uri.mongo')
|
const mongoUri = config.get('uri.mongo')
|
||||||
|
|
||||||
new DB().connect(mongoUri).then((db) => {
|
try {
|
||||||
|
const db = await new DB().connect(mongoUri)
|
||||||
|
|
||||||
console.log(`Connected to MongoDB at ${mongoUri}`)
|
console.log(`Connected to MongoDB at ${mongoUri}`)
|
||||||
|
|
||||||
const User = db.User
|
const User = db.User
|
||||||
@@ -33,18 +35,16 @@ class SendMessageTool {
|
|||||||
let password = readlineSync.question('Password? ', {hideEchoBack: true})
|
let password = readlineSync.question('Password? ', {hideEchoBack: true})
|
||||||
let cr = credential()
|
let cr = credential()
|
||||||
|
|
||||||
util.promisify(cr.hash)(password).then((json) => {
|
const json = await util.promisify(cr.hash)(password)
|
||||||
|
|
||||||
user.passwordHash = JSON.parse(json)
|
user.passwordHash = JSON.parse(json)
|
||||||
|
|
||||||
return user.save()
|
const savedUser = await user.save()
|
||||||
}).then((savedUser) => {
|
|
||||||
console.log(`User is ${user}`)
|
console.log(`User is ${user}`)
|
||||||
process.exit(0)
|
} catch(error) {
|
||||||
}).catch((error) => {
|
|
||||||
console.log(`error: ${error.message}`)
|
console.log(`error: ${error.message}`)
|
||||||
process.exit(-1)
|
}
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ const log = {
|
|||||||
warning: function() { console.error(chalk.yellow('warning:', [...arguments].join(' ')))}
|
warning: function() { console.error(chalk.yellow('warning:', [...arguments].join(' ')))}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = new AddUserTool('add-user', log)
|
const tool = new AddUserTool('addUser', log)
|
||||||
|
|
||||||
tool.run(process.argv.slice(2)).then((exitCode) => {
|
tool.run(process.argv.slice(2)).then((exitCode) => {
|
||||||
process.exit(exitCode)
|
process.exit(exitCode)
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const log = {
|
|||||||
warning: function() { console.error(chalk.yellow('warning:', [...arguments].join(' ')))}
|
warning: function() { console.error(chalk.yellow('warning:', [...arguments].join(' ')))}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = new SendMessageTool('send-message', log)
|
const tool = new SendMessageTool('sendMessage', log)
|
||||||
|
|
||||||
tool.run(process.argv.slice(2)).then((exitCode) => {
|
tool.run(process.argv.slice(2)).then((exitCode) => {
|
||||||
process.exit(exitCode)
|
process.exit(exitCode)
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { ServerTool } from './ServerTool'
|
|||||||
import pino from 'pino'
|
import pino from 'pino'
|
||||||
import * as pinoExpress from 'pino-pretty-express'
|
import * as pinoExpress from 'pino-pretty-express'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import fs from 'fs'
|
||||||
|
import config from 'config'
|
||||||
|
|
||||||
const serviceName = 'dar-server'
|
const serviceName = 'dar-server'
|
||||||
const isProduction = (process.env.NODE_ENV == 'production')
|
const isProduction = (process.env.NODE_ENV == 'production')
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/start.js",
|
"start": "node scripts/start.js",
|
||||||
"build": "node scripts/build.js",
|
"build": "node scripts/build.js",
|
||||||
|
"deploy": "rsync -vr -e ssh build/* ubuntu@tmr:deighton-ar/website/",
|
||||||
"lint": "eslint --ext .js --ext .jsx src/",
|
"lint": "eslint --ext .js --ext .jsx src/",
|
||||||
"lint:fix": "eslint --ext .js --ext .jsx --fix src/"
|
"lint:fix": "eslint --ext .js --ext .jsx --fix src/"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user