Next.js Set up
This article will talk about:
-
Config a new server
-
create a new user
-
create ssh connection for new user
-
enable UFW firewall
-
-
Config Domain
-
install and config nginx
-
buy domain name
-
add SSL
-
-
Deploy Next.js App
-
git clone / git pull App, and build Next.js App
-
install Node.js and npm
-
install pm2
-
run Next.js App with pm2
-
Configure Your New Server
In this section, we'll walk through how to gain remote access to the server and set up some basic configuration to help keep it secure before we deploy and run your Next.js application on it.
Access Server Using Root
ssh root@server_ip_address
Create A New User
-
create a new user
adduser bob
-
add new user to
sudo
group, so that new user can runsudo
commands, has the root privileges.usermod -aG sudo bob
After creating a user with root privileges, all the operations are done by this user.
su - bob
Add Public Key Authentication
By setting up public-key authentication for the new user, it will increase your server's security by requiring a private SSH key to login in instead of anyone being able to access the server via password.
ssh-keygen
ssh-copy-id bob@server_ip_address
After successfully authenticating, your public key will be added to the server user's .ssh/authorized_keys
file. The corresponding private key can now be used to log into the server.
Add a Basic Firewall
Another security improvement we can make to the server is to add a basic firewall.
Ubuntu servers can use the UFW
firewall to ensure only connections to certain services are allowed.
-
add allowed Apps,
OpenSSH
:sudo ufw allow OpenSSH
-
Apps allowed by UFW :
sudo ufw app list
-
enable UFW :
sudo ufw enable
-
check UFW status :
sudo ufw status
Configure Nginx
install it:
sudo apt-get update && sudo apt-get install nginx
There are three profiles available for Nginx:
-
Nginx Full: opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
-
Nginx HTTP: opens only port 80 (normal, unencrypted web traffic)
-
Nginx HTTPS: opens only port 443 (TLS/SSL encrypted traffic)
sudo ufw allow 'Nginx Full'
Configure a Domain Name
Buy it.
For exemple, we bought the example.com
and www.example.com
URLs.
Obtain SSL Certificates
Let's Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps.
Install Certbot
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt install python-certbot-nginx
Obtain SSL Certificates
sudo certbot --nginx -d example.com -d www.example.com
This command runs certbot with the --nginx
plugin and also uses the -d
directive to specify the names we want certificates to be valid for.
The redirect option is the suggested choice.
Let's Encrypt’s certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process.
The certbot package we installed takes care of this for us by running certbot renew
twice a day via a systemd timer. On non-systemd distributions, this functionality is provided by a script placed in /etc/cron.d
. This task runs twice a day and will renew any certificate that’s within thirty days of expiration.
To test the renewal process, you can do a dry run with certbot:
sudo certbot renew --dry-run
Config Node.js
To run your Next.js application, you'll need to have Node.js installed on the server.
cd ~
use curl to retrieve the installation script for the Node.js 12.x archives (replace 12.x with the version of Node.js you want to use):
curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
The PPA has now been added to your configuration and your local package cache should have automatically updated.
The nodesource_setup.sh script won't be needed again, so let's delete it:
sudo rm nodesource_setup.sh
You can now install the Node.js package
sudo apt-get install nodejs
Now, node.js is installed, test it:
node --version
npm --version
It's optional but recommended to install a node manager, n
or nvm
. I use n
.
sudo npm install -g n
Then, intall node version.
n lts
Now, there are 2 nodejs installed.
which -a node
/usr/bin/node # old one
/usr/local/bin/node # new one, added by n
remove the old one
sudo apt-get uninstall nodejs
Finally, update npm
npm install -g npm@latest
Deploy the Next.js Application
To deploy your Next.js website, we'll need to push the code for your project to GitHub (or Gitlab) and pull it into our DigitalOcean server. Then we'll run the application in production mode and keep it running forever using the PM2 NPM package.
Push Application Code To GitHub/Gitlab
# .gitigore
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
.next
Configure & Run Your Application On The Server
git clone
the project:
cd ~
git clone https://github.com/your_github_username/your_repository_name.git website
The website portion of the command will ensure the name of the project folder created is /website
.
Then install App:
cd website
npm install
npm run build
When it's complete, a new /.next
folder will be created in your project directory. The production version of your website will be ran using the code in that folder.
Install & Use PM2 To Run Application
Install it globally:
sudo npm install -g pm2
run the application with PM2:
cd website
pm2 start --name=website npm -- start
The specific command we used gives the application the name
of "website" within PM2. This will help us easily identify all the applications running within PM2 as we add more.
start pm2:
pm2 startup systemd
In the resulting output on the last line, there'll be a command that you must run with superuser privileges:
[PM2] Init System found: systemd
[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u bob --hp /home/bob
Copy and paste the command that was generated (same as above but with your username instead of bob) to have PM2 always start when your server is booted.
This will create a systemd
unit that will run PM2 for your user on boot. This PM2 instance, in turn, will run all the applications configured to run using PM2. To check the status of the new systemd unit, use the following command:
systemctl status pm2-bob
Configure Nginx as a Reverse Proxy
Next application is running and listening on localhost:3000
, we need to make it so people from the outside world can access it.
On Debian systems (i.e. Ubuntu), Nginx server configuration files are stored in /etc/nginx/sites-available
directory, which are enabled through symbolic links to the /etc/nginx/sites-enabled
directory.
# /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
# default setting is above, following setting is custom
# set URL
server_name example.com www.example.com;
# set Reverse Proxy
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;
}
}
save the file and create a symbolic link
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
More config can be done in /etc/nginx/nginx.conf
.
Finally, do lint check and restart nginx
sudo nginx -t
sudo systemctl restart nginx
Future Deployment
In the future, you'll most likely need to push new code updates. To do so, you can follow these steps:
# user: bob
cd website
sudo pm2 stop website
git pull
npm install
npm run build
sudo npm start website