Skip to content

Installing on VPS

Akram El Assas edited this page Jul 5, 2024 · 16 revisions

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Installation Instructions
    1. API
    2. Frontend
    3. Backend
  4. Apply Updates
    1. Update API
    2. Update Frontend and Backend

Introduction

In this walkthrough, we are going to install Movin' In on a VPS running under Ubuntu 22.04 with at least 512MB of RAM and one CPU.

We will to use Apache as a web server and MongoDB Atlas free tier as database server. The free tier provides 512MB of storage which is largely enough for testing purposes. On production, you should use your own MongoDB server or choose another plan.

Prerequisites

  1. Install git:
    sudo apt update
    sudo apt install git
  2. Install Node.js:
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - &&\
    sudo apt install -y nodejs
    Update npm to its latest version:
    sudo npm i -g npm
  3. Install Apache server:
    sudo apt update
    sudo apt install apache2
    After letting the command run and all required packages are installed, test it out by typing in the IP address of the VPS on a web browser.
  4. Create and configure MongoDB Atlas account:
  5. Create a an account or login to MongoDB Atlas
  6. Fill out the forms and click on Finish
  7. Choose M0 Free
  8. You can change the name of the cluster or leave Cluster0
  9. Choose the Provider (AWS, Google Cloud or Azure)
  10. Choose the Region
  11. Click on Create Deployment
  12. Set admin as database username and save the generated password somewhere safe. You will need it later. Then, click on Create Database User.
  13. Click on Choose a Connection Method and select Node.js as Driver. Copy the connection string somewhere safe. We will need it later. The connection string looks like this:
    mongodb+srv://admin:PASSWORD@cluster0.xxxxxxx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
    
  14. Click on Review setup steps then on Done.
  15. On the left panel under Security, click on Network Access. Then, click on ADD IP ADDRESS. Then in Access List Entry, enter the IP address of the VPS to allow the VPS accessing MongoDB Atlas server. Finally, click on Confirm.

Installation Instructions

API

  1. Clone movinin repo:

    cd /opt
    sudo git clone https://github.com/aelassas/movinin.git
  2. Add permissions:

    sudo chown -R $USER:$USER /opt/movinin
  3. Create movinin service:

    sudo cp /opt/movinin/__services/movinin.service /etc/systemd/system
    sudo systemctl enable movinin.service
  4. Create /opt/movinin/api/.env file with the following content:

    NODE_ENV=production
    MI_PORT=4004
    MI_HTTPS=false
    MI_PRIVATE_KEY=/etc/ssl/movinin.key
    MI_CERTIFICATE=/etc/ssl/movinin.pem
    MI_DB_URI=mongodb+srv://admin:PASSWORD@cluster0.xxxxxxx.mongodb.net/movinin?retryWrites=true&w=majority&appName=Cluster0
    MI_DB_SSL=false
    MI_DB_SSL_CERT=/etc/ssl/movinin.pem
    MI_DB_SSL_CA=/etc/ssl/movinin.pem
    MI_DB_DEBUG=true
    MI_DEFAULT_LANGUAGE=en
    MI_COOKIE_SECRET=COOKIE_SECRET
    MI_AUTH_COOKIE_DOMAIN=localhost
    MI_JWT_SECRET=JWT_SECRET
    MI_JWT_EXPIRE_AT=86400
    MI_TOKEN_EXPIRE_AT=86400
    MI_SMTP_HOST=smtp.sendgrid.net
    MI_SMTP_PORT=587
    MI_SMTP_USER=apikey
    MI_SMTP_PASS=PASS
    MI_SMTP_FROM=no-reply@movinin.io
    MI_CDN_USERS=/var/www/cdn/movinin/users
    MI_CDN_TEMP_USERS=/var/www/cdn/movinin/temp/users
    MI_CDN_PROPERTIES=/var/www/cdn/movinin/properties
    MI_CDN_TEMP_PROPERTIES=/var/www/cdn/movinin/temp/properties
    MI_BACKEND_HOST=http://localhost:3003/
    MI_FRONTEND_HOST=http://localhost/
    MI_EXPO_ACCESS_TOKEN=EXPO_ACCESS_TOKEN
    MI_MINIMUM_AGE=21
    MI_STRIPE_SECRET_KEY=STRIPE_SECRET_KEY
    MI_ADMIN_EMAIL=admin@movinin.io
    MI_RECAPTCHA_SECRET=RECAPTCHA_SECRET
    

    Set the following options:

    MI_DB_URI=mongodb+srv://admin:PASSWORD@cluster0.xxxxxxx.mongodb.net/movinin?retryWrites=true&w=majority&appName=Cluster0
    MI_COOKIE_SECRET=COOKIE_SECRET
    MI_AUTH_COOKIE_DOMAIN=localhost
    MI_JWT_SECRET=JWT_SECRET
    MI_SMTP_HOST=smtp.sendgrid.net
    MI_SMTP_PORT=587
    MI_SMTP_USER=apikey
    MI_SMTP_PASS=PASSWORD
    MI_SMTP_FROM=no-reply@movinin.io
    MI_BACKEND_HOST=http://localhost:3003/
    MI_FRONTEND_HOST=http://localhost/
    

    Put you MongoDB Atlas URI in MI_DB_URI and don't forget mongodb.net/movinin. Replace JWT_SECRET with a secret token of your choice. COOKIE_SECRET and JWT_SECRET should at least be 32 characters long, but the longer the better. You can use an online password generator and set the password length to 32 or longer.

    Finally, set the SMTP options. SMTP options are necessary for sign up. You can use sendgrid or any other transactional email provider.

    If you choose sendgrid, create an account on sendgrid.com, login and go to the dashboard. On the left panel, click on Email API, then on Integration Guide. Then, choose SMTP Relay and follow the steps. You will be prompted to create an API Key. Once you create the API Key and verify the smtp relay, copy the API key in MI_SMTP_PASS in ./api/.env. Sendgrid's free plan allows to send up to 100 emails/day. If you need to send more than 100 emails/day, switch to a paid plan or choose another transactional email provider.

    The following settings are very important and if they are not set properly, authentication won't work:

    MI_AUTH_COOKIE_DOMAIN=localhost
    MI_BACKEND_HOST=http://localhost:3001/
    MI_FRONTEND_HOST=http://localhost/
    

    Replace localhost with an IP or FQDN. That is if you access the backend from http://<FQDN>:3001/. MI_BACKEND_HOST should be http://<FQDN>:3001/. The same goes for MI_FRONTEND_HOST. And MI_AUTH_COOKIE_DOMAIN should be FQDN.

    If you want to enable push notifications in the mobile app, follow these instructions and set the following option:

    MI_EXPO_ACCESS_TOKEN=EXPO_ACCESS_TOKEN
    

    If you want to enable stripe payment gateway, sign up for a stripe account, fill the forms and save the publishable key and the secret key from stripe dashboard. Then, set the secret key in the following option in api/.env:

    MI_STRIPE_SECRET_KEY=STRIPE_SECRET_KEY
    

    Don't expose stripe secret key on a website or embed it in a mobile application. It must be secret and stored securely in the server-side.

    In stripe, all accounts have a total of four API keys by default-two for test mode and two for live mode:

    • Test mode secret key: Use this key to authenticate requests on your server when in test mode. By default, you can use this key to perform any API request without restriction.
    • Test mode publishable key: Use this key for testing purposes in your web or mobile app’s client-side code.
    • Live mode secret key: Use this key to authenticate requests on your server when in live mode. By default, you can use this key to perform any API request without restriction.
    • Live mode publishable key: Use this key, when you’re ready to launch your app, in your web or mobile app’s client-side code.

    Use only your test API keys for testing. This ensures that you don't accidentally modify your live customers or charges.

    If you want to enable HTTPS, you have to set the following options:

    MI_HTTPS=true
    MI_PRIVATE_KEY=/etc/ssl/movinin.io.key
    MI_CERTIFICATE=/etc/ssl/movinin.io.crt
    
  5. Create cdn folder:

    sudo mkdir -p /var/www/cdn/movinin
    sudo chown -R $USER:$USER /var/www/cdn/movinin
  6. Start movinin service:

    cd /opt/movinin/api
    npm install --omit=dev
    sudo systemctl start movinin.service

    Make sure that movinin service is running with the following command:

    sudo systemctl status movinin.service
    

    Make sure that the database connection is established by checking the logs with the following command:

    tail -f /var/log/movinin.log

    Or this one:

    sudo journalctl -xfu movinin.service

    Or by opening this file:

    tail -f /opt/movinin/api/logs/all.log

    Error logs are written in:

    tail -f /opt/movinin/api/logs/error.log
  7. If you want to use the demo database, follow this step otherwise you can skip it.

    1. On your desktop PC, Download and install MongoDB Command Line Database Tools.
    2. On Windows, add MongoDB Command Line Database Tools folder to Path environment variable.
    3. Download movinin-db.zip down to your machine, unzip it and go to the unzipped folder from a terminal.
    4. Restore movinin demo db by using the following command:
    mongorestore --verbose --drop --gzip --uri="$URI" --nsInclude="movinin.*" --nsFrom="movinin.*" --nsTo="movinin.*" --archive=movinin.gz

    Replace $URI with your MongoDB Atlas URI. 5. Copy the content of cdn folder in /var/www/cdn/movinin/ on your VPS. You can use FileZilla and connect to your VPS through SFTP. cdn folder contains the following folders:

    • users: This folder contains users’ avatars and suppliers’ images.
    • properties: This folder contains properties’ images.
    • temp: This folder contains temporay files.

    Make sure permissions are set for these folders, otherwise run the following command:

    sudo chown -R $USER:$USER /var/www/cdn/movinin/

Frontend

Now, we are going to build the frontend on a desktop PC and install it on Apache server in the VPS:

  1. On your desktop PC, download the latest version of the source code down to your machine.

  2. download and install the latest LTS version of Node.js.

  3. Open the source code with Visual Studio Code.

  4. Create frontend/.env file with the following content:

    VITE_NODE_ENV=production
    VITE_MI_API_HOST=http://localhost:4004
    VITE_MI_DEFAULT_LANGUAGE=en
    VITE_MI_PAGE_SIZE=30
    VITE_MI_PROPERTIES_PAGE_SIZE=15
    VITE_MI_BOOKINGS_PAGE_SIZE=20
    VITE_MI_BOOKINGS_MOBILE_PAGE_SIZE=10
    VITE_MI_CDN_USERS=http://localhost/cdn/movinin/users
    VITE_MI_CDN_PROPERTIES=http://localhost/cdn/movinin/properties
    VITE_MI_AGENCY_IMAGE_WIDTH=60
    VITE_MI_AGENCY_IMAGE_HEIGHT=30
    VITE_MI_PROPERTY_IMAGE_WIDTH=300
    VITE_MI_PROPERTY_IMAGE_HEIGHT=200
    VITE_MI_MINIMUM_AGE=21
    VITE_MI_PAGINATION_MODE=classic
    VITE_MI_STRIPE_PUBLISHABLE_KEY=STRIPE_PUBLISHABLE_KEY
    VITE_MI_STRIPE_CURRENCY_CODE=USD
    

    Set the following options:

    VITE_MI_API_HOST=http://localhost:4004
    VITE_MI_CDN_USERS=http://localhost/cdn/movinin/users
    VITE_MI_CDN_PROPERTIES=http://localhost/cdn/movinin/properties
    VITE_MI_STRIPE_PUBLISHABLE_KEY=STRIPE_PUBLISHABLE_KEY
    VITE_MI_STRIPE_CURRENCY_CODE=USD
    

    Replace localhost with the VPS IP or FQDN.

    If you want to enable stripe payment gateway, set stripe publishable key in VITE_MI_STRIPE_PUBLISHABLE_KEY. You can retrieve it from stripe dashboard.

    VITE_MI_STRIPE_CURRENCY_CODE is the three-letter ISO 4217 alphabetic currency code, e.g. "USD" or "EUR". Required for Stripe payments. Must be a supported currency: https://docs.stripe.com/currencies

    VITE_MI_PAGINATION_MODE: You can choose between classic or infinite_scroll. This option defaults to classic. If you choose classic, you will get a classic pagination with next and previous buttons on desktop and infinite scroll on mobile. If you choose infinite_scroll, you will get infinite scroll on desktop and mobile.

  5. Go to frontend folder from a terminal and build the frontend with the following command:

    npm run build
  6. Copy the folder frontend/build in /opt/movinin/frontend/ on your VPS. You can use FileZilla and connect to your VPS through SFTP.

  7. Copy the content of /opt/movinin/frontend/build/ in /var/www/movinin/frontend/:

    sudo mkdir -p /var/www/movinin/frontend/
    sudo cp -rf /opt/movinin/frontend/build/* /var/www/movinin/frontend/
  8. Set up the frontend VirtualHost on Apache:

    1. We start this step by going into the configuration files directory:
      cd /etc/apache2/sites-available/
    2. Since Apache came with a default VirtualHost file, let’s use that as a base.
      sudo cp 000-default.conf movinin-frontend.conf
      sudo cp 000-default.conf 000-default.conf.original
      sudo a2dissite 000-default.conf
    3. Now edit the configuration file:
      sudo nano movinin-frontend.conf
      The file should have the following content:
      <VirtualHost *:80>
       # The ServerName directive sets the request scheme, hostname and port that
       # the server uses to identify itself. This is used when creating
       # redirection URLs. In the context of virtual hosts, the ServerName
       # specifies what hostname must appear in the request's Host: header to
       # match this virtual host. For the default virtual host (this file) this
       # value is not decisive as it is used as a last resort host regardless.
       # However, you must set it for any further virtual host explicitly.
       #ServerName www.example.com
      
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/movinin/frontend
      
       Alias /cdn /var/www/cdn
      
       <Directory "/var/www/cdn">    
         allow from all
         order allow,deny
         AllowOverride All
       </Directory>
      
       <Directory "/var/www/movinin/frontend">
         RewriteEngine On
         # Don't rewrite files or directories
         RewriteCond %{REQUEST_FILENAME} -f [OR]
         RewriteCond %{REQUEST_FILENAME} -d
         RewriteRule ^ - [L]
         # Rewrite everything else to index.html to allow html5 state links
         RewriteRule ^ index.html [L]
       </Directory>
      
       # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
       # error, crit, alert, emerg.
       # It is also possible to configure the loglevel for particular
       # modules, e.g.
       #LogLevel info ssl:warn
      
       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
      
       # For most configuration files from conf-available/, which are
       # enabled or disabled at a global level, it is possible to
       # include a line for only one particular virtual host. For example the
       # following line enables the CGI configuration for this host only
       # after it has been globally disabled with "a2disconf".
       #Include conf-available/serve-cgi-bin.conf
      </VirtualHost>
      
      # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
      
      If you want to enable HTTPS, add the following configuration at the end before </VirtualHost>:
      SSLEngine on
      SSLCertificateFile /path/to/ssl.cert
      SSLCertificateKeyFile /path/to/ssl.key
      SSLCACertificateFile /path/to/ssl.ca
      SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
      
    4. Activate Apache RewriteEngine:
      sudo a2enmod rewrite
      sudo systemctl restart apache2
    5. Activate frontend VirtualHost file:
      sudo a2ensite movinin-frontend.conf
    6. Check that you have the following configuration in /etc/apache2/apache2.conf:
      <Directory /var/www/>
       Options Indexes FollowSymLinks
       AllowOverride None
       Require all granted
      </Directory>
      
    7. Load the frontend:
      sudo systemctl restart apache2
      sudo systemctl status apache2
    8. The frontend is accessible on: http://<VPS-IP>

Backend

Now, we are going to build the backend on a desktop PC and install it on Apache server in the VPS:

  1. On your desktop PC, download the latest version of the source code down to your machine.

  2. download and install the latest LTS version of Node.js.

  3. Open the source code with Visual Studio Code.

  4. Create backend/.env file with the following content:

    VITE_NODE_ENV=production
    VITE_MI_API_HOST=http://localhost:4004
    VITE_MI_DEFAULT_LANGUAGE=en
    VITE_MI_PAGE_SIZE=30
    VITE_MI_PROPERTIES_PAGE_SIZE=15
    VITE_MI_BOOKINGS_PAGE_SIZE=20
    VITE_MI_BOOKINGS_MOBILE_PAGE_SIZE=10
    VITE_MI_CDN_USERS=http://localhost/cdn/movinin/users
    VITE_MI_CDN_TEMP_USERS=http://localhost/cdn/movinin/temp/users
    VITE_MI_CDN_PROPERTIES=http://localhost/cdn/movinin/properties
    VITE_MI_CDN_TEMP_PROPERTIES=http://localhost/cdn/movinin/temp/properties
    VITE_MI_AGENCY_IMAGE_WIDTH=60
    VITE_MI_AGENCY_IMAGE_HEIGHT=30
    VITE_MI_PROPERTY_IMAGE_WIDTH=300
    VITE_MI_PROPERTY_IMAGE_HEIGHT=200
    VITE_MI_MINIMUM_AGE=21
    VITE_MI_PAGINATION_MODE=classic     
    

    Set the following options:

    VITE_MI_API_HOST=http://localhost:4004
    VITE_MI_CDN_USERS=http://localhost/cdn/movinin/users
    VITE_MI_CDN_TEMP_USERS=http://localhost/cdn/movinin/temp/users
    VITE_MI_CDN_PROPERTIES=http://localhost/cdn/movinin/properties
    VITE_MI_CDN_TEMP_PROPERTIES=http://localhost/cdn/movinin/temp/properties
    

    Replace localhost with the VPS IP or FQDN.

    VITE_MI_PAGINATION_MODE: You can choose between classic or infinite_scroll. This option defaults to classic. If you choose classic, you will get a classic pagination with next and previous buttons on desktop and infinite scroll on mobile. If you choose infinite_scroll, you will get infinite scroll on desktop and mobile.

  5. Go to backend folder from a terminal and build the backend with the following command:

    npm run build
  6. Copy the folder backend/build in /opt/movinin/backend/ on your VPS. You can use FileZilla and connect to your VPS through SFTP.

  7. Copy the content of /opt/movinin/backend/build/ in /var/www/movinin/backend/:

    sudo mkdir -p /var/www/movinin/backend/
    sudo cp -rf /opt/movinin/backend/build/* /var/www/movinin/backend/
  8. Set up the backend VirtualHost on Apache:

    1. We start this step by going into the configuration files directory:
      cd /etc/apache2/sites-available/
    2. Let’s use the frontend configuration file as a base.
      sudo cp movinin-frontend.conf movinin-backend.conf
    3. Now edit the configuration file:
      sudo nano movinin-backend.conf
      The file should have the following content:
      Listen 3003
      <VirtualHost *:3003>
       # The ServerName directive sets the request scheme, hostname and port that
       # the server uses to identify itself. This is used when creating
       # redirection URLs. In the context of virtual hosts, the ServerName
       # specifies what hostname must appear in the request's Host: header to
       # match this virtual host. For the default virtual host (this file) this
       # value is not decisive as it is used as a last resort host regardless.
       # However, you must set it for any further virtual host explicitly.
       #ServerName www.example.com
      
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/movinin/backend
      
        <Directory "/var/www/movinin/backend">
         RewriteEngine On
         # Don't rewrite files or directories
         RewriteCond %{REQUEST_FILENAME} -f [OR]
         RewriteCond %{REQUEST_FILENAME} -d
         RewriteRule ^ - [L]
         # Rewrite everything else to index.html to allow html5 state links
         RewriteRule ^ index.html [L]
        </Directory>
       
       # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
       # error, crit, alert, emerg.
       # It is also possible to configure the loglevel for particular
       # modules, e.g.
       #LogLevel info ssl:warn
      
       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
      
       # For most configuration files from conf-available/, which are
       # enabled or disabled at a global level, it is possible to
       # include a line for only one particular virtual host. For example the
       # following line enables the CGI configuration for this host only
       # after it has been globally disabled with "a2disconf".
       #Include conf-available/serve-cgi-bin.conf
      </VirtualHost>
      
      # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
      
      If you want to enable HTTPS, add the following configuration at the end before </VirtualHost>:
      SSLEngine on
      SSLCertificateFile /path/to/ssl.cert
      SSLCertificateKeyFile /path/to/ssl.key
      SSLCACertificateFile /path/to/ssl.ca
      SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
      
    4. Activate backend VirtualHost file:
      sudo a2ensite movinin-backend.conf
    5. Load the backend:
      sudo systemctl reload apache2
      sudo systemctl status apache2
    6. The backend is accessible on: http://<VPS-IP>:3003

If you decided to not use the demo database, you need to create an admin user by navigation to http://<VPS-IP>:3003/sign-up and filling the form. Once the admin user is created, you need to secure the backend by commenting the following line in backend/src/App.tsx:

<Route exact path='/sign-up' element={<Signup />} />

Then you need to build the backend and run the installation process again.

Apply Updates

Update API

If you want to update the API to the latest version, run the following commands:

cd /opt/movinin/api
git pull
npm install --omit=dev
sudo systemctl restart movinin.service
sudo systemctl status movinin.service
tail -f /opt/movinin/api/logs/all.log

Update Frontend and Backend

If you want to update the frontend and the backend to the latest version, fetch the latest version of the source code from GitHub then run the installation steps of the frontend and the backend again.