A basic app that has all the features that all platforms have like authentication, validation, error handling and more.
Similar to the MEAN stack just with Neo4j rather than Mongo.
- Angular (client), Node (API), Neo4j (database)
- NodeJS in Typescript
- Webpack build bundle for Node (API)
- Angular CLI
- Chrome extension build output
- JWT (JSON web token) authentication
- Password hashing + salt
- SendGrid Email integration
- Angular Material
- Neo4j query integration
- API architecture (route -> controller -> service -> repository)
- Shared validation between Angular and Node (Error handling, type assertion)
- Shared strongly typed view models
- Shared strongly typed API endpoints
- Countly analytics - automatic page tracking
- Client share actions
- Lazy load routes with preloaded parts
- Image uploader to Firebase storage
- Tutorial/on-boading/tour framework
- Emoji picker (Material CDK)
- WYSIWYG editor (Quill)
- Media (Image, YouTube, Vimeo) display component
- Web share API
- Basic web socket connection
- Notifications area/panel
- Payment integration via Stripe (Card, Google/Android Pay, Apple Pay, PayPal)
- Custom Material theme + font + color palette (Night Mode, Global CSS variable colors)
- Progressive Web App (PWA) + custom install banner
- Complete server setup guide via GCP
- Backend logger (Node + Neo4j)
- Content Security Policy
- CORS
- Notifications via email and/or push notifications (Seperate NodeJS message broker/queue via RabbitMQ)
- Typescript best practises flags (strictNullChecks, strictFunctionTypes, strictPropertyInitialization, noImplicitAny, noImplicitThis, noImplicitReturns)
- Predefined dialog components/services
- Auto package versioning (Husky)
- Puppeteer scraper script to test infinite scroller
- Social media meta tags
- Common password checker
- GDPR/Cookie prompts
- Offline network message (PWA)
- Share API + Share Target API
- Network Speed service
- Apache Lucene fulltext search
- Lazy load icon pack
- Drag & Drop sorting capability
- TSLint + SonarQube
- Two Factor Authentication via Google Authenticator App
- Right Click context menu
- Basic CSS animations
- Global style management
- Internationalization (i18n)
- Background Particle Effect
- Desktop social share options
- Material Design and custom svg icons module
- Lazy load all images
- Complete build script
- Password Peek
- Skeleton Screens
- File Drop uploader
Client pages
- sign up
- login
- forgot password/reset password
- header nav for desktop and bottom nav for mobile
- newsletter sign up
- email feedback
- profile
- tutorials
- verify email
- terms and conditions, privacy policy and help
- invite a friend
- 404 error page
- onboarding
- items
- create
- edit
- comment
- favourites
- GraphQL integration (Apollo)
- Cordova IOS build output
Make sure you have Node.js and Docker installed.
node -v
docker -v
git clone git@github.com:CharlBest/nean-stack-starter.git
cd nean-stack-starter
npm install
npm start
Your app should have automatically opened the browser and be running on localhost:4200
- Visit localhost:32768 and setup Countly
- Get app key from Countly and replace client environment analytics keys
- Setup server environment variables in src/server/environments
- Rename all occurances of the word "nean" to your chosen name
- Replace logo in client assets folder
- Create accounts for services
- Firebase account (Images)
- Stripe (Payments)
- Google Cloud Platform
- Create VM instance in Compute Engine (f1-micro)
- Neo4j Instance (Database Hosting)
- RabbitMQ Instance (Message queue)
- Nginx reverse proxy
- PM2 Node manager
- Cloudflare (DNS)
- Namecheap Domain
Change to yours.
In the environments folder there are 2 files. one for dev and one for production. The angular CLI switches them at build time.
In the environments folder there is 1 file. In development default values are used. In production your hosting service should set process.env with the appropriate variables
Note: firebase storage has authentication on their buckets. Whitelist your url or something
- GitHub (source code)
- Firebase (image/blob storage)
- Zoho (email service)
- Stripe (payment service)
- Cloudflare (CDN)
- Google Cloud (server)
Google Cloud (VM), Ubuntu server, Xfce4, VNC server, Putty SSH, Git, NGINX, Angular CLI, NodeJS, PM2, Docker, Neo4j, RabbitMQ, Cloudflare, Namecheap
- NGINX: /etc/nginx/sites-avialable/
- Node apps: /var/www/<SITE_NAME>/
- Neo4j: /home//neo4j/<SITE_ENVIRONMENT>/
- RabbitMQ:
- home dir: /var/lib/rabbitmq
- config file(s): /etc/rabbitmq/rabbitmq.config
- database dir: /var/lib/rabbitmq//rabbit@<NODE_NAME>
- VNC: /home//.vnc/
- PM2: /home//.pm2/
- Node web: 3010
- Neo4j browser: 7474
- Neo4j: 7687
- RabbitMQ: 5672
- RabbitMQ management: 15672
- Node web: +10 (3020)
- Neo4j: +1 (7475)
- Neo4j browser: +1 (7688)
- RabbitMQ: +1 (5673)
- RabbitMQ management: +1 (15673)
Source: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04
- Google Cloud Platfrom
- Compute Engine
- VM Instance - Create instance
- Machine type - micro (1 shared vCPU)
- Ubuntu 18.04 LTS Minimal - 20GB SSD
- Allow HTTPS traffic
- Advanced
- Management: Enable deletion protection
- Networking: Static external IP (NB: can't assign afterwards)
Heroku charges $7 per instance that doesn't go to sleep after 30 minutes. That means if I want 3 Node instances, 2 for load balancing and zero downtime updates and 1 for the background worker process I have to pay ~$21. The VM is ~$25 and +- 7 instances can be run on it.
When building the client project with the Angular CLI the server freezes and a possible cause is the shared CPU because it doesn't happen with the standard machine types or it could be an out of memory problem.
Source: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-18-04
sudo apt update
- sudo: super user do (admin)
- apt: package manager command (apt combines apt-get and apt-cache commands and sets nice defaults like progress bar and num of packages installed)
- update: Refreshes repository index
sudo apt upgrade
- upgrade: Upgrades all upgradable packages
Packages repo site: https://packages.ubuntu.com/
sudo apt install xfce4 xfce4-goodies tightvncserver nano firefox
- install: all the following packages needs to be intalled
- xfce4: Meta-package for the Xfce Lightweight Desktop Environment (File Manager, Panel, Session Manager, Settings, etc.)
- xfce4-goodies: enhancements for the Xfce4 Desktop Environment (clipboard, terminal, etc.)
- tightvncserver: virtual network computing server software (Remote desktop)
- text editor
- firefox browser
Optional: autocopysel (clipboard copy paste library but consumes lots of memory and scared of multiple running instances)
- Start
vncserver
-
Enter password and set view-only password to NO
-
1 represents the number of vnc server running
vncserver -kill :1
- Copy of your existing/default VNC configuration
cp ~/.vnc/xstartup ~/.vnc/xstartup_backup
- Edit default config
nano ~/.vnc/xstartup
- Edit file
#!/bin/bash
xsetroot -solid grey
/etc/X11/Xsession
export XKL_XMODMAP_DISABLE=1
startxfce4 &
-
Then hit Ctrl + X, and then Y to save and exit Nano
-
Start server again (higher resolution and color depth can degrade performance)
vncserver -geometry 1280x720 -depth 24
-
Go to https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
-
Download and install PuTTY and puttygen.exe
-
Open puttygen
- Click "Generate"
- Key comment = eg. bob
- Click "Save private key" and use in PuTTY connection utility
- Copy public key and add to Google Compute allowed SSH keys for your instance via the web console
-
Open PuTTY
- Session
- Host Name (or IP address) = @<SERVER_IP_ADDRESS> eg. bob@35.225.150.147
- Port = 22
- Connection > SSH > Auth
- Private key file for authentication
- Click "Browse" and choose previously generated private key
- Connection > SSH > Tunnels
- Source port = 5901
- Destination = localhost:5901
- Click "Add"
- Session
- Saved sessions = vnc
- Click "Save"
- Click "Open" at the bottom
- Enter password for instance in console
- Session
- Download and install RealVNC from https://www.realvnc.com/en/connect/download/vnc/windows/
- VNC server address = localhost:5901
Buy a domain name and set the name servers to cloudflare
- Create free account
- Enable HTTPS certificates
- Setup DNS
- Create Cloudflare account
- DNS section (Domain name system)
- Create A record (root domain) eg. nean.io
- Name = @
- IPv4 address = 35.225.150.147
- Create cname record
- name = www
- Domain name = nean.io
- Create A record (sub domain) eg. dev.nean.io
- Name = dev
- IPv4 address = 35.225.150.147
- Create Page Rule for LetsEncrypt auto renew (first)
- URL: http://nean.io/.well-known/acme-challenge/
- Setting: Cache Level: Standard
- Create Page Role for redirecting to HTTPS (second)
- URL: http://nean.io/
- Setting: Always Use HTTPS
- Caching
- Browser Cache Expiration = 2 days
Source: https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04
Complete source: https://medium.com/@jgefroh/a-guide-to-using-nginx-for-static-websites-d96a9d034940
Example: https://github.com/FranciscoKnebel/nginx-reverseproxy
Proxy summary: https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- Install
sudo apt install nginx
- Test
sudo nginx -v
- Create /etc/nginx/sites-available/nean.io
server {
listen 443 http2;
# IPv6 addresses
listen [::]:443 http2;
ssl on;
ssl_certificate /etc/letsencrypt/live/nean.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nean.io/privkey.pem;
server_name nean.io www.nean.io;
root /var/www/nean.io/dist/client;
access_log /var/www/nean.io/nginx/nginx.access.log;
error_log /var/www/nean.io/nginx/nginx.access.log;
include snippets/static-files.conf;
location /api/ {
proxy_pass http://localhost:3010;
include snippets/api-params.conf;
}
location /analytics/ {
proxy_pass http://localhost:32768/;
}
}
- Create /etc/nginx/sites-available/dev.nean.io
server {
listen 443 http2;
# IPv6 addresses
listen [::]:443 http2;
ssl on;
ssl_certificate /etc/letsencrypt/live/dev.nean.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev.nean.io/privkey.pem;
server_name dev.nean.io;
root /var/www/nean.io/dev/dist/client;
access_log /var/log/dev.nean.io/nginx.access.log;
error_log /var/log/dev.nean.io/nginx.error.log;
include snippets/static-files.conf;
location /api/ {
proxy_pass http://localhost:3020;
include snippets/api-params.conf;
}
}
- Create snippets/static-files.conf
index index.html;
location / {
# First attempt to serve request as file, then as directory, then fall back to displaying the index.html
try_files $uri $uri/ /index.html;
# Cacheing
# expires 1d;
# add_header Cache-Control "public, no-cache";
}
- Create snippets/api-params.conf
proxy_http_version 1.1;
# Set host header
proxy_set_header Host $host;
# List of IP addresses
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Log IP on nginx proxy server
proxy_set_header X-Real-IP $remote_addr;
# HTTP or HTTPS?
proxy_set_header X-Forwarded-Proto $scheme;
# CORS https://www.digitalocean.com/community/questions/allow-cors-origin-for-node-angular-api-on-nginx
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Authorization $http_authorization;
# proxy_set_header X-NginX-Proxy true;
# proxy_max_temp_file_size 0;
# proxy_redirect off;
# proxy_read_timeout 240s;
# TODO: proxy_cache_bypass $http_upgrade;
- Create symbolic links in /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/nean.io /etc/nginx/sites-enabled/nean.io
ln -s /etc/nginx/sites-available/dev.nean.io /etc/nginx/sites-enabled/dev.nean.io
ln: make link command -s: symbolic link flag
- Test config
sudo nginx -t
- Restart
sudo service nginx restart
- Set permissions
sudo chown -R $USER:$USER /var/www/nean.io
sudo chmod -R 755 /var/www/nean.io
# If the above doesn't work use this
# sudo chown -R www-data:www-data /var/www/nean.io
Note:
4 different cache location exist:
- Browser (Cache-Control header)
- Service Worker (ng-config.json)
- CloudFlare (browser UI)
- Nginx (.conf)
Install & Update NVM (Node version manager: https://github.com/creationix/nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
Test NVM
nvm --version
List Node versions
nvm ls-remote
Install Node
nvm install v10.13.0
Important: when installing a new Node version you need to reinstall the global packages like pm2
Test Node
node --version
NPM packages to work (those that require compiling code from source, for example)
sudo apt install build-essential
Notes:
- check how to run multiple versions of Node and test on newer ones
Install PM2
npm install pm2 -g
Test PM2
pm2 -v
-
Create ecosystem.config.js in /var/www/nean.io/
-
Replace ecosystem.config.js text
// Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
const environmentVariables = {
APP_HOST: "",
AUTHENTICATION_KEY: "37LvDSm4XvjYOh9Y",
NODE_ENV: "production",
SENDGRID_API_KEY: "***",
SENDGRID_TEMPLATE_FEEDBACK: "***",
SENDGRID_TEMPLATE_FORGOT_PASSWORD: "***",
SENDGRID_TEMPLATE_INVITE: "***",
SENDGRID_TEMPLATE_NOTIFICATION: "***",
SENDGRID_TEMPLATE_PASSWORD_UPDATED: "***",
SENDGRID_TEMPLATE_PAYMENT_SUCCESSFUL: "***",
SENDGRID_TEMPLATE_RESEND_EMAIL_VERIFICATION_LINK: "***",
SENDGRID_TEMPLATE_SYSTEM: "***",
SENDGRID_TEMPLATE_WELCOME: "***",
STRIPE_KEY: "***",
VAPID_PRIVATE_KEY: "***",
VAPID_PUBLIC_KEY: "***",
};
function generate(environment, server, env, port = 0, instances = 1) {
return {
name: `${environment}_${server}`,
script: `${server}.bundle.js`,
cwd: `${environment}/dist/server/${server}`,
instances: instances,
env: { ...environmentVariables, PORT: port, ...env },
// Time in ms to wait before restarting a crashing app
restart_delay: 10000,
// Number of times a script is restarted when it exits in less than min_uptime
max_restarts: 10,
// Minimum uptime of the app to be considered started
min_uptime: 1000,
};
}
module.exports = {
apps: [
generate(
"prod",
"web",
{
AMQP_URL: "amqp://server_api:<PASSWORD>@localhost:5672",
DATABASE_PASSWORD: "<PASSWORD>",
DATABASE_URI: "bolt://localhost:7687",
DATABASE_USERNAME: "server_api",
},
3010,
2
),
generate("prod", "worker", {
AMQP_URL: "amqp://server_worker:<PASSWORD>@localhost:5672",
DATABASE_PASSWORD: "<PASSWORD>",
DATABASE_URI: "bolt://localhost:7687",
DATABASE_USERNAME: "server_worker",
}),
generate(
"dev",
"web",
{
AMQP_URL: "amqp://server_api:<PASSWORD>@localhost:5673",
DATABASE_PASSWORD: "<PASSWORD>",
DATABASE_URI: "bolt://localhost:7688",
DATABASE_USERNAME: "server_api",
},
3020,
2
),
generate("dev", "worker", {
AMQP_URL: "amqp://server_worker:<PASSWORD>@localhost:5673",
DATABASE_PASSWORD: "<PASSWORD>",
DATABASE_URI: "bolt://localhost:7688",
DATABASE_USERNAME: "server_worker",
}),
],
deploy: {
dev: {
host: "localhost",
ref: "origin/dev",
repo: "https://github.com/heroku/node-js-getting-started.git",
path: "var/www/nean.io/deploy/dev",
"post-deploy":
"npm install && npm run build && pm2 reload ecosystem.config.js",
},
staging: {
host: "localhost",
ref: "origin/staging",
repo: "https://github.com/heroku/node-js-getting-started.git",
path: "var/www/nean.io/deploy/staging",
"post-deploy":
"npm install && npm run build && pm2 reload ecosystem.config.js",
},
},
};
- Generate script to run
pm2 startup
-
Copy paste command to setup
-
Take snapshot of what processes should start on startup
pm2 save
- Test
sudo systemctl status pm2-<USERNAME>
pm2 link <key> <key> MACHINE_NAME
https://github.com/adnanh/webhook
Source: https://medium.com/@riyadhalnur/managing-and-deploying-nodejs-apps-with-pm2-173fbc7d3f95
Source: https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-18-04
- Install
sudo apt install git
- Set global git configuration
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"
- Acquire an SSL cert
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx certonly
-
Automatic cron job will be created to renew certificates
-
Remember to set disable HTTP access to server in Google Cloud firewall settings
-
Remember to set Cloudflare > Crypto > SSL to "Full (strict)"
Add http2 in NGINX conf after port numbers
listen 443 http2;
Source: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04
- Get package
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
sudo apt update
- Install
sudo apt install docker-ce
- Test
sudo systemctl status docker
- Executing the Docker Command Without Sudo by adding the current user to the docker group
sudo usermod -aG docker ${USER}
- Log out and back in for changes to take effect
- Create docker-compose.yml
version: "3"
services:
countly:
container_name: countly
image: countly/countly-server
ports:
- "32768:80"
volumes:
- ./countly:/data/db
restart: unless-stopped
neo4j.nean.io:
container_name: neo4j.nean.io
image: neo4j/3.5-enterprise
ports:
- "7474:7474" ## Browser
- "7687:7687" ## Bolt connection
volumes:
- $HOME/neo4j/nean.io/data:/data
- $HOME/neo4j/nean.io/backup:/backup
- $HOME/neo4j/nean.io/logs:/logs
- $HOME/neo4j/nean.io/plugins:/plugins
environment:
NEO4J_dbms_memory_heap_max__size: "512M"
NEO4J_dbms_memory_pagecache_size: "512M"
NEO4J_AUTH: "neo4j/password"
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
restart: unless-stopped
rabbitmq.nean.io:
container_name: rabbitmq.nean.io
image: rabbitmq:3.7
hostname: rabbitmq.nean.io
ports:
- "5672:5672"
restart: unless-stopped
neo4j.dev.nean.io:
container_name: neo4j.dev.nean.io
image: neo4j/3.5-enterprise
ports:
- "7475:7474" ## Browser
- "7688:7687" ## Bolt connection
volumes:
- $HOME/neo4j/dev.nean.io/data:/data
- $HOME/neo4j/dev.nean.io/backup:/backup
- $HOME/neo4j/dev.nean.io/logs:/logs
- $HOME/neo4j/dev.nean.io/plugins:/plugins
environment:
NEO4J_dbms_memory_heap_max__size: "512M"
NEO4J_dbms_memory_pagecache_size: "512M"
NEO4J_AUTH: "neo4j/password"
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
restart: unless-stopped
rabbitmq.dev.nean.io:
container_name: rabbitmq.dev.nean.io
image: rabbitmq:3.7
hostname: rabbitmq.dev.nean.io
ports:
- "5673:5672"
restart: unless-stopped
- container_name: Unique name for the container
- image: docker hub image
- ports: first port is what docker exposes and second one is what it maps to in the container
- 7474 for Neo4j Browser
- 7474 for Neo4j HTTP connection
- 7473 for Neo4j HTTPS connection
- 7687 for Neo4j Bolt connection
- 15672 for RabbitMQ Management Plugin
- 5672 for RabbitMQ AMQP connection
- volumes: shared filesystems
- environment: spesify environment config
- Neo4j: 512 MB is the default for both variables but should be increased in prod.
- RabbitMQ: set username and password for user
- restart=on-failure: Restart only if the container exits with a non-zero exit status.
- Run docker compose
docker-compose up -d
- up: Download images from docker hub and create container instances
- -d: detached mode: Container starts up and run in background. Console is not attached to the container's process.
# terminal within container
docker exec -it <container_name> bash
# Execute cyper in container
bin/cypher-shell -u server_api -p password
# process monitoring for containers
docker stats
# process monitoring for specific container
docker top <container_name>
- Create new users
3.2 RabbitMQ
# RabbitMQ ## Create virtual host docker exec -it rabbitmq.nean.io rabbitmqctl add_vhost nean ## Create user docker exec -it rabbitmq.nean.io rabbitmqctl add_user server_api password docker exec -it rabbitmq.nean.io rabbitmqctl add_user server_worker password ## Set permissions docker exec -it rabbitmq.nean.io rabbitmqctl set_permissions -p nean server_api ".*" ".*" ".*" docker exec -it rabbitmq.nean.io rabbitmqctl set_permissions -p nean server_worker ".*" ".*" ".*"
- Do the same for other instances
- Create crontab for user
export VISUAL=nano; crontab -e
- Set backup commands every 1 hour
Short codes
- @reboot – Run once, at startup
- @yearly – Run once a year, “0 0 1 1 *”.</>
- @annually – same as @yearly
- @monthly – Run once a month, “0 0 1 * *”
- @weekly – Run once a week, “0 0 * * 0”
- @daily – Run once a day, “0 0 * * *”
- @midnight – same as @daily
- @hourly – Run once an hour, “0 * * * *”
@hourly docker exec neo4j.nean.io bin/neo4j-admin backup --from=localhost:6362 --backup-dir=/backup --name=graph.db-backup --fallback-to-full=true --check-consistency=true --pagecache=2G
-
Save file
-
Repeat for neo4j.dev.nean.io instance
-
Optionally send emails after cron job. https://cloud.google.com/compute/docs/tutorials/sending-mail/using-sendgrid
- Install Java
sudo apt install openjdk-8-jre
- Signing Key
wget -O - https://debian.neo4j.org/neotechnology.gpg.key | sudo apt-key add -
- Source List File
echo 'deb https://debian.neo4j.org/repo stable/' | sudo tee -a /etc/apt/sources.list.d/neo4j.list
- Install Neo4j
sudo apt update
sudo apt-get install neo4j=1:3.4.9
- Test
sudo service neo4j status
- Start automatically on boot
sudo systemctl enable neo4j
Navigate to localhost:7474 in your browser
- Enter cypher shell
/usr/bin/cypher-shell -u neo4j -p neo4j
- Create user and disable password set on first login
CALL dbms.security.createUser('nean_dev', 'nean_dev', false)
- Signing Key
wget -O - "https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc" | sudo apt-key add -
- Source List File (debian bionic main + erlang)
echo "deb https://dl.bintray.com/rabbitmq/debian bionic main erlang" | sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list
- Install packages
sudo apt update
sudo apt install rabbitmq-server
- Test
sudo service rabbitmq-server status
- Install management plugin
sudo rabbitmq-plugins enable rabbitmq_management
- Test
Navigate to localhost:15672 in your browser
- $HOME/.pm2/logs
- web + worker logs in dist > server
- $HOME/neo4j/<app_name>/logs
- /var/log/rabbitmq
- nginx logs
- /var/log/nginx/access.log
- /var/log/nginx/error.log
- /var/log/<app_name>
- $HOME/.vnc
- /var/lib/docker/containers/<CONTAINER_ID>/<CONTAINER_ID>-json.log
https://winscp.net/eng/download.php
gcloud compute scp --recurse <FROM_DIR> <USERNAME>@<VM_INSTANCE_NAME>:/var/www/nean.io/
- gcloud: Google Cloud SDK
- compute: Google's term for their VM offering
- scp: secure copy paste
- --recurse: recursively copy directory and all inner file/folders
- <FROM_DIR>: C:\Users...
- : Linux username
- <VM_INSTANCE_NAME>: VM instance name
- GitHub Import repository
- URL = https://github.com/CharlBest/nean-stack-starter.git
- git clone
- cd repo
- git remote add upstream https://github.com/CharlBest/nean-stack-starter.git
- git fetch upstream
- npm install
- npm run build
- change services
- .env file
- docker-compose exposed posts and container names
- nginx ports
- pm2 environment variables in ecosystem.config.js
- Rename all NEAN words to new project name
- Change theme colors in material theme, manifest.json, index.html icons, index.html loading screen bg
- Change icon/logo
- Note procedure for domain and subdomains are the same, just add the subdomains before the root domain
- Go to /var/www/
- Create new directory (sudo mkdir domain.com)
- copy over dist folder via WinSCP into
- start services
cd /var/www/nean.io/
docker-compose up --detach
- Add A record for subdomain pointing to server IP
- Create symlink to enable domain (ln -s /var/www/nean.io/services/nginx.conf /etc/nginx/sites-enabled/domain.com)
- create log folder (sudo mkdir /var/www/nean.io/nginx)
- sudo nginx -t
- sudo service nginx restart
- comment out certificates (ssl) and listen http2 (443)
- Add listen 80;
- sudo service nginx restart
- Make sure DNS provider (CloudFlare) has a A Record with name domain.com and content = the IP of the server
- sudo certbot certonly -d domain.com
- Choose option 3 - Place files in webroot directory (webroot0)
- Input the webroot of the domain (/var/www/domain.com)
- Open /etc/nginx/sites-available/domain.com
- Uncomment certificate links, 443 (SSL) config and remove listen 80
- Set SSL/TLS encryption mode to Full (strict)
- Add first CloudFlare page rule
- http://domain.com/.well-known/acme-challenge/
- Cache Level
- Standard Add second CloudFlare page rule
- http://domain.com/
- Always Use HTTPS
- sudo service nginx restart
- add web and worker apps
- change name, node server port, neo4j port and rabbitmq port
cd /var/www/nean.io/
pm2 reload ecosystem.config.js --update-env
# save the process list
pm2 save
Local
# Get latest code from base
git fetch upstream
git merge upstream/master
npm run build
Server
- Open WinSCP
- copy over newdist to server next to dist
- mv /var/www/nean.io/dist /var/www/nean.io/olddist && mv /var/www/nean.io/newdist /var/www/nean.io/dist && pm2 reload all && rm -rf /var/www/nean.io/olddist