Set up multiple websites on a Digital Ocean droplet running nginx and node.js
Set up your droplet
First you will need to setup an SSH Key
Click on the SSH Keys tab, then click Add SSH Key
Create the key in OpenSSH in Mac OSX or Linux, or using Putty for Windows.
Copy the ssh key and add it into Digital Ocean and give it a name.
Make a backup of your SSH key on your external hard drive etc...
Now click on the Create Droplet tab and fill out the fields for your droplet
Select your Droplet Hostname, Select your size, $5 or $10 a month plans are probably best if you are just using this for development projects.
Select you region, and distribution, I went with Ubuntu and New York.
On the Image/Applications tab select any applications you want setup by default, like node.
Now click Create Droplet to add your droplet
Connect to your Droplet
Connect via SSH from Terminal as follows, and if your SSH key is setup on your PC you should be logged in.
ssh root@SERVER_IP_ADDRESS
Server setup
Create a new user so you are not logging in with the root user, instead of steven, add your own name
adduser steven
Add "super user" or root privileges for our new account.
gpasswd -a steven sudo
Now your user can run commands with sudo super user privileges!
Copy the Public Key to the server
type <b>exit</b> to get out of your remote session
on your <b>local machine</b> get your ssh key and copy it to the clipboard
cat ~/.ssh/id_rsa.pub
now log back in to the server as root
ssh root@SERVER_IP_ADDRESS
enter the following command to switch to the new user (substitute your own user):
su - steven
Create a new directory called .ssh and restrict its permissions
mkdir .ssh
chmod 700 .ssh
Open a file in .ssh called authorized_keys with a text editor.
nano .ssh/authorized_keys
Insert your public key from your clipboard by pasting it into the editor.
Hit CTRL-X to exit the file, then Y to save the changes made, then ENTER to confirm the file name.
restrict the permissions of the authorized_keys file with this command:
chmod 600 .ssh/authorized_keys
Type exit to return to the root user
Now you can SSH login as your new user, using the private key as authentication.
Secure our server a little bit by modifying its SSH configuration. Edit the config file
nano /etc/ssh/sshd_config
Change SSH Port value from Port 22 to something in between 1025 and 65536
When you change this value, you will need to keep in mind that your server is running on the new port.
As an example if you change this to 4444. This means that when you connect, you need to tell SSH client to use this new, non-default port.
Port 4444
Now to restrict Root Login we need to find the line that looks like this:
PermitRootLogin yes
Modify this line to "no" if you want to disable root login:
PermitRootLogin no
Disabling remote root login is highly recommended on every server!
Save and close the file using the method we went over earlier (CTRL-X, then Y, then ENTER).
Reload SSH, we need to restart the SSH service so that it will use our new configuration.
service ssh restart
Now, before we log out of the server, we should test our new configuration.
We do not want to disconnect until we can confirm that new connections can be established successfully.
Open a new terminal window. In the new window, we need to begin a new connection to our server.
This time, instead of using the root account, we want to use the new account that we created and our new port number for ssh
ssh -p 4444 steven@SERVER_IP_ADDRESS
You will be prompted for the new user's password you configured. After that, you will be logged in as your new user.
Remember, if you need to run a command with root privileges, type "sudo" before it like this:
sudo command_to_run
If all is well, you can exit your sessions by typing:
exit
Additional steps for new server
First to <b>configure our firewall</b> we need to create an exception for SSH connections so that we can maintain access for remote administration.
Ubuntu ships with a tool called ufw that can be used to configure your firewall policies.
sudo ufw allow 4444/tcp
allow access to port 80 for running a HTTP web server
sudo ufw allow 80/tcp
If you plan to run a web server with SSL enabled, you should allow traffic to that port as well:
sudo ufw allow 443/tcp
If you need SMTP email enabled, port 25 will need to be opened:
sudo ufw allow 25/tcp
you can enable the firewall by typing:
sudo ufw enable
Set the <b>server's timezone</b> by reconfiguring the tzdata package selecting your geographic region
sudo dpkg-reconfigure tzdata
To configure <b>NTP synchronization</b> we will use a service ntp, which we can install from Ubuntu's default repositories:
sudo apt-get update
sudo apt-get install ntp
Now to <b>create a Swap File</b> Digital Ocean suggest that an amount equal to or double the amount of RAM on your system is a good size. I am using 1GB with the $10 a month plan.
sudo fallocate -l 1G /swapfile
After creating the file, we need to run the following commands, one after the other, to enable the system to use the swap file automatically at each boot
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sh -c 'echo "/swapfile none swap sw 0 0" >> /etc/fstab'
If you are happy with your configuration and wish to use this as a base for future installations, you can <b>take a snapshot of your server</b> through the DigitalOcean control panel.
To do so, shutdown your server from the command line by typing:
sudo poweroff
Now, in the DigitalOcean control panel, you can take a snapshot by visiting the "Snapshots" tab of your server:
After taking your snapshot, you will be able to use that image as a base for future installations by selecting the snapshot from the "My Snapshots" tab.
Install Node
Ubuntu 14.04 contains a version of Node.js in its default repositories. The version in the repositories is 0.10.25. This will not be the latest version, but it should be quite stable.
sudo apt-get update
sudo apt-get install nodejs
Because of a conflict with another package, the executable from the Ubuntu repositories is called nodejs instead of node.
The following command should link node to nodejs, so it runs correctly when you run node commands, link
sudo ln -s /usr/bin/nodejs /usr/bin/node
Now install npm, Node.js package manager.
sudo apt-get install npm
Setup Filezilla for ftp transfer
Open the FileZilla client, Click on the File menu item and select Site Manager.
On the left side of the Site Manager, click on the New Site button and type a unique name under My Sites for your connection
Now, under the General tab, fill in the Host with the IP address and Port fields
Logon type select Interactive and Click Connect
Setup nginx
Install and start nginx
sudo apt-get install nginx
sudo service nginx start
Confirm That nginx Has Started
ifconfig eth0 | grep inet | awk '{ print $2 }'
This will show your virtual server's IP address. Navigate to it in your browser, you will see the words, “Welcome to nginx”
Ensure that nginx will be up after reboot
update-rc.d nginx defaults
Set up domain names
Point your name servers to DigitalOcean. The DigitalOcean domain servers are
ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com
Now to configure your Domain move into the DigitalOcean control panel.
Within the DNS section, click on Add Domain, and fill in the the domain name field and your servers IP address
Fill in the A record for your domain, it should have updated the name servers to be correct,
If you leave it as @ it will be
http://example.com
Or you can specify a name prepended to your domain name, for example enter <i>test</i>
test.example.com
Fill in the AAAA Records. Enter in the IPv6 address of the droplet that you want to host your domain name on and the host name itself,
To prepend www to your URL, click on the CNAME tab and fill out the 2 fields.
www and @
Set up nginx virtual hosts
Log back in via ssh to your server. Now I wanted to set up multiple domains for my Nginx server.
For demonstration lets assume the domain names are example.com and test.com, obviously use your own domains you have configured with Digital Ocean and purchased somewhere like iwantmyname.com
sudo apt-get update
sudo apt-get install nginx
By default, Nginx on Ubuntu 14.04 has one server block enabled by default. It is configured to serve documents out of a directory at:
/usr/share/nginx/html
We won't use the default since it is easier to work with things in the /var/www directory.
We want a directory for each of our sites within the /var/www directory and we will have a directory under these called html to hold our actual files.
Create the necessary directories. We can do this with the following command
sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/test.com/html
Now that the directories are created, we need to transfer ownership to our regular user. We can use the $USER environmental variable to substitute the user account that we are currently signed in on.
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/test.com/html
Create Sample Pages for Each Site
Create an index.html file in your first domain:
nano /var/www/example.com/html/index.html
Now insert a basic index page that indicates what site we are currently accessing
<html>
<head>
<title>Welcome to Example.com!</title>
</head>
<body>
<h1>Success! The example.com server block is working!</h1>
</body>
</html>
Do the same for you second domain
Now that we have the content we wish to serve, we need to <b>create the server blocks</b> that will tell Nginx how to do this.
We will <b>create our first server block</b> config file by copying over the default file:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
Now, open the new file you created in your text editor with root privileges:
sudo nano /etc/nginx/sites-available/example.com
Set your first server as the default server block, so leave the default_server option in this file
Adjust the document root, specified by the root directive. Point it to the site's document root that you have created:
root /var/www/example.com/html;
Modify the server_name to match requests for our first domain. We can also add any aliases like www.example.com
server_name example.com www.example.com;
Save and close the file
Now that we have our initial server block configuration, we can use that as the basis for our <b>second server block file</b>.
Copy it over to create a new file:
sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/test.com
Open the new file with root privileges in your editor:
sudo nano /etc/nginx/sites-available/test.com
Remove the default server option and the ipv6only=on so the resulting 2 lines are:
listen 80;
listen [::]:80;
Adjust the document root directive to point to your second domain's document root:
root /var/www/test.com/html;
Adjust the server_name to match your second domain and any aliases:
server_name test.com www.test.com;
When adding additional server blocks for other domains, copy this second file and you will only have to modify the document root and domain name, alias
Save and close the file
You now have your server blocks created, we need to <b>enable them and restart nginx</b>.
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/test.com /etc/nginx/sites-enabled/
These files are now in the enabled directory. We need to disable the default server block file by removing the symbolic link.
sudo rm /etc/nginx/sites-enabled/default
We also need to adjust one setting quickly in the default Nginx configuration file. Open it up by typing:
sudo nano /etc/nginx/nginx.conf
Uncomment the one line that is currently commented out.
server_names_hash_bucket_size 64;
Now, we are ready to restart Nginx to enable your changes.
sudo service nginx restart
Now you should be able to visit your 2 new domains, and you will hopefully all will be working well, and you can start building your sites.
Written by Steven Iseki
Related protips
2 Responses
It worked for me. Only thing I had to fix was a 403 and that was due to index files not being in their respective html folders (var/www/html).
Would you recommend using the same approach for a subdomain?
Thanks!
Great article! Alternatively, you could just use Plesk and save tons of time managing your multiple domains and websites on DigitalOcean.
Check out https://marketplace.digitalocean.com/apps/plesk?action=deploy&refcode=eb4c817f6e43