Got a new VPS (Ubuntu 20.04) on Namecheap. It seems that the basic VPS tier on Namecheap offers double CPU, RAM and storage than that of my old basic tier on AWS lightsail.
This journal concisely notes: How to configurate a fresh VPS to host my new website peiwen.me.
Reminder:
Just run these commands once ssh into remote server
apt update
apt install curl
Notes:
-
apt
is a Linux package management system - 'fun' fact:
apt
cmd was introduced in 2014, partly replacedapt-get
after the release of Ubuntu 16.04, for being faster, friendlier, easier to use
Firstly! SSH
-
mosh
is a good mobile shell - highly responsive, gotta be installed both locally and remotely. - local ssh config for convenience:
# add info to local file: ~/.ssh/config
Host <name_your_remote>
HostName <static_IP>
User <remote_username>
IdentityFile <path_to_local_id_rsa>
IdentitiesOnly yes
- remote ssh config:
# local shell
ssh <user>@<static_IP>
# remote shell
mkdir .ssh
touch authorized_keys
apt-get install nano # just in case
apt-get install mosh # just in case
nano authorized_keys
# paste the content of the local file 'id_rsa.pub' to this file, save and exit
- NOW! YOU CAN~
# local shell
mosh <name_your_remote>
ssh <name_your_remote>
NodeJS
nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# might need to reconnect remote for `nvm` command to work properly
Note: check the latest nvm
installation script here
node
nvm list-remote
nvm install stable # or pick one from the list
nvm list
node -v
npm -v
npm install --global yarn # recommended
Note: if "nvm 'command' not found" - check 'Troubleshooting on Linux Section'
MongoDB
Problems with installing v5.0
🔥 This exact problem encountered when I installed v5.0 - mongod
service won't start. The reason might be:
> the VM’s CPU does not support instructions required by MongoDB 5.0 (such as AVX and SSE) which should be listed in the CPU flags
:
> flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr
Similar issues found:
You might need to install apt install procinfo
to run cat /proc/cpuinfo
to checkout your CPU type.
Install MongoDB v4.4 Community Edition
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt-get update
sudo apt-get install -y mongodb-org=4.4.15 mongodb-org-server=4.4.15 mongodb-org-shell=4.4.15 mongodb-org-mongos=4.4.15 mongodb-org-tools=4.4.15
Start and config
sudo systemctl start mongod
sudo systemctl status mongod
sudo systemctl enable mongod
mongo
mongosh
Note: sudo
can be omitted if you are the root
superuser
Uninstall MongoDB
sudo service mongod stop
sudo apt-get purge mongodb-org*
sudo rm -fr /var/log/mongodb
sudo rm -fr /var/lib/mongodb
Security Checklist
IP Binding to create a replica backup
Git
Installation
apt update
apt install git
git --version
Setup
To setup username if push to source is needed
git config --global user.name <username>
git config --global user.email <email>
git config --list # or ↓ directly check gitconfig file
nano ~/.gitconfig
This is NOT enough anyway if you were to edit code and push to source, for only SSH communication is allowed with github repos since 2021.
Clone repo
Clone web repo to ~/web/
, install the deps
git clone <repo_address>
cd <project>
yarn
# OR
npm i
Configure .env.local
touch .env.local
nano .env.local
.env.local
content ↓
MONGODB_URI=<get_this by typing mongosh>
MONGODB_DB=journal
PASS=<some_password>
NEXT_PUBLIC_PASS_TOKEN=<some_JWT_like_token>
NEXT_PUBLIC_REVAL_TOKEN=<some_token_for_revalidation_token>
Build
yarn build
yarn global add pm2
pm2 start yarn --name "peiwen.me" -- start
pm2 ls
# to start on startup
pm2 startup
# to freeze/save the processes
pm2 save
Nginx
1. Install, config firewall and enable nginx
apt install nginx
# firewall
ufw app list
# returns
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
mosh
# enable firewall
ufw allow 'Nginx Full'
ufw allow OpenSSH # important
ufw allow mosh
ufw enable
ufw status
# returns
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
mosh ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
mosh (v6) ALLOW Anywhere (v6)
# check your nginx server
systemctl status nginx
# get your IP if you don't already know for some reason
curl -4 icanhazip.com
<IP_address>
# enter this <IP_address> into the browser, you should be able to see the landing page of nginx
# lastely, enable it on every boot
systemctl enable nginx
2. Setting Up Server Blocks
An nginx server block
is a file inside folder /etc/nginx/sites-available/
cd /etc/nginx/sites-available
touch <new_domain> # optional
nano <new_domain>
Insert content:
server {
# the name of your domain
server_name <new_domain> www.<new_domain>;
location / {
# this must stay localhost. The port must be the same as your Next.js project
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;
}
# simple headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Frame-Options DENY always;
# this will serve the project on port 80
listen 80;
}
3. Verify and reload nginx for it to take effect
# check all working
nginx -t
ln -s /etc/nginx/sites-available/<new_domain> /etc/nginx/sites-enabled/
systemctl reload nginx
PS. Do NOT forget
- UPDATE
host records
: point to server IP (which record type to choose)
Refs:
SSL
1. Install certbot
and some preparation
apt install certbot python3-certbot-nginx
# firewall settings
ufw allow 'Nginx Full'
ufw allow 'Nginx HTTPS'
ufw deny 'Nginx HTTP'
ufw status
# check if the <server_name> is exactly the format "example.com www.example.com"
nano /etc/nginx/sites-available/example.com
2. Obtain the SSL/TLS Certificate
# do not forget the '-d' before www.example.com
certbot --nginx -d example.com -d www.example.com
# enter your email...
Once you configure HTTPS, Certbot completes generating the certificate and reloads Nginx with the new settings.
Finally, the output displays that you have successfully generated a certificate and specifies the location of the certificate on your server.
/etc/letsencrypt/live/example.com/fullchain.pem (success)
Ref: How to Secure Nginx with Let's Encrypt On Ubuntu 20.04
If you open your nginx file now nano /etc/nginx/sites-available/example.com
, you'll find the extra info has been added:
server {
server_name <new_domain> www.<new_domain>;
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;
}
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Frame-Options DENY always;
# ↓ the following lines are added by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name example.com www.example.com;
listen 80;
return 404; # managed by Certbot
}
} # an extra for some reason...
# check certificate's auto-renewal
certbot renew --dry-run
3. Setup Cronjob to Enable Automatic Certificate Renewal
# open Crontab
crontab -e
Add a line:
# Schedule it to run daily at a specified time (in this example, it does so at 05:00 a.m.)
0 5 * * * /usr/bin/certbot renew --quiet
Maintain
# in remote <site_folder>
git pull && yarn build && pm2 restart peiwen.me
Top comments (0)