SethCram / book-club

A blogging/creative writing platform leveraging a novel reputation system.
1 stars 0 forks source link
aws blog blog-engine express expressjs mongodb node nodejs nosql reactjs reputation-system

Book-Club

A blogging/creative writing platform built with MongoDB, Express, React, Node (the MERN stack) and leveraging a novel reputation system.

Read the paper

Watch the videos

Quick Intro

Book Club

Detailed Overview

Book Club

Developer Notes

Environment File

  1. MONGO_URL should be found through MongoDB Atlas "Deployment" > Database > Connect > Drivers > Driver as "Node.js" version "4.1 or later", then copy & paste connection string, and replace with the password for the given user
    1. Requires account creation/login
  2. DEV_PASSWORD is recommended to be a complex password
  3. JWT_ACCESS_SECRET_KEY and JWT_REFRESH_SECRET_KEY should be extremely complex and distinct since they won't be required for direct usage, just authentication
  4. ENV should be set to production or development
    1. production: ENV="PROD"
    2. development: ENV="DEV"
  5. FILE_STORAGE_URL should be set to wherever the uploaded images are supposed to be stored
    1. production: FILE_STORAGE_URL="http://[publicIpAddress]" or FILE_STORAGE_URL="https://[publicIpAddress]"
    2. development: FILE_STORAGE_URL="http://localhost:5000"

Developer Setup Instructions

  1. Install Node.js v16 & npm
    curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
    sudo apt-get install -y nodejs
    sudo apt install -y npm
    1. Verify nodejs is version 16 node -v
    2. If nodejs is lower than v16, install nvm and update to the right node.js version:
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
      command -v nvm

      If "command -v nvm" doesn't output "nvm", logout and relogin, and then:

      nvm install 16.17.1
  2. Clone the project and install the project dependencies
      git clone https://github.com/SethCram/book-club.git
      cd book-club/api/
      npm install
      cd ../client/ckeditor5/
      npm install
      cd ..
      npm install 
      cd ..
  3. Fill out the environment setup file (use http not https for the file storage url)
    vi api/.env

    Refer to https://github.com/SethCram/book-club#environment-file for more details.

  4. Create the required Search Indices on MongoDB Atlas to allow the Search Bar to function properly
    1. Login to MongoDB Atlas then go to "Deployment" > "Database" > "Search" > "Create Search Index" > "Visual Editor" > "Next"
    2. Change the Index Name to "searchPosts" and link it to your Database's posts collection > "Next" > "Create Search Index"
    3. "Create Index" again > "JSON Editor" > "Next"
    4. Change the Index Name to "autoCompletePosts", select your Database's posts collection again, and replace what's in the JSON Editor with
      {
      "mappings": {
      "dynamic": false,
      "fields": {
        "title": [
          {
            "foldDiacritics": false,
            "maxGrams": 7, 
            "minGrams": 3,
            "tokenization": "edgeGram",
            "type": "autocomplete"
          }
        ]
      }
      }
      }
    5. "Create Search Index"
  5. Start the api and client by running npm start in their respective directories in different terminals

Packages

Deployment Notes

The Deployment Instructions assume the project is being deployed onto AWS. The only changes necessary to deploy it elsewhere is to ensure port 80 is open to HTTP traffic and port 443 to HTTPS traffic.

Deployment Instructions

  1. Launch a new EC2 instance on AWS:
    1. Select Ubuntu as the OS image
    2. Generate a new .pem key pair for SSH
    3. Allow SSH, HTTPS, and HTTP traffic from anywhere on the internet
    4. Set the storage to 20GB (arbitrarily)
  2. On AWS, navigate "Network & Security" > "Elastic IPs" > "Allocate Elastic IP address" > "Allocate" > Select the IP > "Associate Elastic IP address" > Choose the instance we're running on > "Associate"
    1. If an elastic public IP isn't created and associated with the instance, when the instance is stopped and started back up again, the public IP address will change
  3. Wait for the Instance State to read "Running"
  4. Go into the instance > Connect > EC2 Instance Connect > Connect
    1. If this doesn't work, go into the SSH client tab and follow the below steps, otherwise continue to step 4
    2. Then copy & paste the last part of the "Example:" into Putty as the Session
    3. Open up PuttyGen, "Load" the .pem key, and "Save private key" as .ppk
    4. In Putty, Connection > SSH > Auth > Credentials > and choose "Private key file for authentication" as the .ppk we just generated
    5. When prompted, choose to Accept
  5. Install setup application software Node.js v16 & npm and server software nginx & pm2
    curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
    sudo apt-get install -y nodejs
    sudo apt install -y npm
    sudo apt install -y nginx
    sudo npm i -gy pm2
    1. Verify nodejs is version 16 node -v
    2. If nodejs is lower than v16, install nvm and update to the right node.js version:
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
      command -v nvm

      If "command -v nvm" doesn't output "nvm", logout and relogin, and then:

      nvm install 16.17.1
  6. Clone the project and install its dependencies
    git clone https://github.com/SethCram/book-club.git
    cd book-club/api/
    npm install
    cd ../client/ckeditor5/
    npm install
    cd ..
    npm install 
    cd ..
    1. If any npm install hangs, reboot the instance and reconnect to it and then setup debugging:
      npm config set loglevel info
      npm install --verbose
  7. Copy the example environment setup file for the api
    cd api
    cp .env.example .env
    cd ..
  8. Fill out the environment setup file
    vi api/.env

    Refer to https://github.com/SethCram/book-club#environment-file for more details.

  9. Make sure the domain and DNS are able to redirect to the public IP
    cd client
    export DANGEROUSLY_DISABLE_HOST_CHECK=true;
    cd ..
  10. Manually start both the api and the client to ensure they both work in isolation
    npm start 
    cd ../client/
    npm start 
    cd ..
  11. Make sure pm2 runs the required processes and nginx boots on server restart
    pm2 startup
    sudo env PATH=$PATH:/home/ubuntu/.nvm/versions/node/v16.17.1/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu
    sudo systemctl enable nginx
  12. Indefinitely run the api and client, then verify and save it to run on server restart
    cd api
    pm2 start --name api npm -- start
    cd ../client
    pm2 start --name client npm -- start
    pm2 logs 
    pm2 save
    cd ..
  13. Setup nginx to direct external api requests to the api
    sudo vi /etc/nginx/sites-available/default

    add this inside the "server" block, replacing the "location" block with:

    location /api {
        proxy_pass http://localhost:5000;
        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;
    }
  14. Setup nginx to direct external website connections to the client
    sudo vi /etc/nginx/sites-available/default

    add this inside the "server" block, below the first "location" block:

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
  15. Verify the syntax of the nginx config file is okay and start nginx using it
    sudo nginx -t
    sudo service nginx restart
  16. Login to MongoDB Atlas and go "Security" > "Network Access" > "Add IP Address", then add the elastic public IP of the AWS EC2 instance (visible under EC2 instance details)
  17. Verify the website is live through navigating to the public IP address using a browser (e.g. http://[publicIPAddress]) and the frontend should be visible or use curl to verify curl http://[publicIPAddress]
  18. Create an account and register a subdomain and its corresponding "www." at http://freedns.afraid.org/menu/ (make sure they're linked to the EC2 instance's public IP)
  19. Setup nginx to accept traffic from the domain name
    sudo vi /etc/nginx/sites-available/default

    replace the "server_name" with:

    server_name domain_name www.domain_name
  20. Verify the syntax of the nginx config file is okay and restart nginx using it
    sudo nginx -t
    sudo service nginx restart
  21. Navigate to the domain name using a browser (e.g. http://[domain_name]) and the frontend should be visible or use curl to verify curl http://[domain_name]
  22. Make sure the latest version of snapd is installed
    sudo snap install core; sudo snap refresh core
  23. Ensure no other versions of certbot exist, install it via snap, and make sure it's properly linked
    sudo apt-get remove certbot
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot
  24. Get an HTTPS certificate and tell Certbot to edit your nginx config file to enabled HTTPS
    sudo certbot --nginx
    1. Ask for certificates for both subdomains 1, 2
    2. If a error is encountered that talks about "too many certificates already issued for [domain_name]", wait until the specified date and rerun this step's command or setup an at job to automate the certificate issuance
  25. Change the file storage url from using HTTP to using HTTPS
    vi api/.env
  26. Navigate to the secured domain name using a browser (e.g. https://[domain_name]) and the frontend should be visible or use curl to verify curl https://[domain_name]
  27. Lastly, ensure that automatic certificate renewal should go properly
    sudo certbot renew --dry-run