A blogging/creative writing platform built with MongoDB, Express, React, Node (the MERN stack) and leveraging a novel reputation system.
- basis: https://www.youtube.com/watch?v=tlTdbc5byAs&list=PLj-4DlPRT48lGpll2kC4wOsLj7SEV_lYu
- Test data script
- can create & delete all fake posts, users, categories, votes, and comments
- from api directory:
- insertion:
node seedData.js -i -p # -u # -c #
- deletion:
node seedData.js -d
- example usage:
node seedData.js
- insertion:
- CkEditor features can be added or removed:
- download from https://ckeditor.com/ckeditor-5/online-builder/
- unzip folder into "client" folder
- rename unzipped folder into "ckeditor5"
- run "npm add file:./ckeditor5" in the client directory
- 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
- Requires account creation/login
- DEV_PASSWORD is recommended to be a complex password
- 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
- ENV should be set to production or development
- production:
ENV="PROD"
- development:
ENV="DEV"
- production:
- FILE_STORAGE_URL should be set to wherever the uploaded images are supposed to be stored
- production:
FILE_STORAGE_URL="http://[publicIpAddress]"
orFILE_STORAGE_URL="https://[publicIpAddress]"
- development:
FILE_STORAGE_URL="http://localhost:5000"
- production:
- 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
- Verify nodejs is version 16
node -v
- If nodejs is lower than v16, install nvm and update to the right node.js version:
If "command -v nvm" doesn't output "nvm", logout and relogin, and then:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash command -v nvm
nvm install 16.17.1
- Verify nodejs is version 16
- 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 ..
- Fill out the environment setup file (use http not https for the file storage url)
Refer to https://github.com/SethCram/book-club#environment-file for more details.
vi api/.env
- Create the required Search Indices on MongoDB Atlas to allow the Search Bar to function properly
- Login to MongoDB Atlas then go to "Deployment" > "Database" > "Search" > "Create Search Index" > "Visual Editor" > "Next"
- Change the Index Name to "searchPosts" and link it to your Database's posts collection > "Next" > "Create Search Index"
- "Create Index" again > "JSON Editor" > "Next"
- 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" } ] } } }
- "Create Search Index"
- Start the api and client by running
npm start
in their respective directories in different terminals
- Nodemon is installed for a responsive api
- Mongoose connects the API to MongoDB Atlas through NodeJS
- Multer allows for file posting to the API
- Uses Axios to communicate between frontend React and Express API
- Icons retrieved from Font Awesome
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.
- Launch a new EC2 instance on AWS:
- Select Ubuntu as the OS image
- Generate a new .pem key pair for SSH
- Allow SSH, HTTPS, and HTTP traffic from anywhere on the internet
- Set the storage to 20GB (arbitrarily)
- 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"
- 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
- Wait for the Instance State to read "Running"
- Go into the instance > Connect > EC2 Instance Connect > Connect
- If this doesn't work, go into the SSH client tab and follow the below steps, otherwise continue to step 4
- Then copy & paste the last part of the "Example:" into Putty as the Session
- Open up PuttyGen, "Load" the .pem key, and "Save private key" as .ppk
- In Putty, Connection > SSH > Auth > Credentials > and choose "Private key file for authentication" as the .ppk we just generated
- When prompted, choose to Accept
- 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
- Verify nodejs is version 16
node -v
- If nodejs is lower than v16, install nvm and update to the right node.js version:
If "command -v nvm" doesn't output "nvm", logout and relogin, and then:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash command -v nvm
nvm install 16.17.1
- Verify nodejs is version 16
- 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 ..
- If any npm install hangs, reboot the instance and reconnect to it and then setup debugging:
npm config set loglevel info npm install --verbose
- If any npm install hangs, reboot the instance and reconnect to it and then setup debugging:
- Copy the example environment setup file for the api
cd api cp .env.example .env cd ..
- Fill out the environment setup file
Refer to https://github.com/SethCram/book-club#environment-file for more details.
vi api/.env
- Make sure the domain and DNS are able to redirect to the public IP
cd client export DANGEROUSLY_DISABLE_HOST_CHECK=true; cd ..
- Manually start both the api and the client to ensure they both work in isolation
npm start cd ../client/ npm start cd ..
- 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
- 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 ..
- Setup nginx to direct external api requests to the api
add this inside the "server" block, replacing the "location" block with:
sudo vi /etc/nginx/sites-available/default
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; }
- Setup nginx to direct external website connections to the client
add this inside the "server" block, below the first "location" block:
sudo vi /etc/nginx/sites-available/default
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; }
- Verify the syntax of the nginx config file is okay and start nginx using it
sudo nginx -t sudo service nginx restart
- 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)
- 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]
- 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)
- Setup nginx to accept traffic from the domain name
replace the "server_name" with:
sudo vi /etc/nginx/sites-available/default
server_name domain_name www.domain_name
- Verify the syntax of the nginx config file is okay and restart nginx using it
sudo nginx -t sudo service nginx restart
- 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]
- Make sure the latest version of snapd is installed
sudo snap install core; sudo snap refresh core
- 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
- Get an HTTPS certificate and tell Certbot to edit your nginx config file to enabled HTTPS
sudo certbot --nginx
- Ask for certificates for both subdomains
1, 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
- Ask for certificates for both subdomains
- Change the file storage url from using HTTP to using HTTPS
vi api/.env
- 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]
- Lastly, ensure that automatic certificate renewal should go properly
sudo certbot renew --dry-run