command line setup and deployment of an nginx server on digitalocean
Mar 3, 2025
Introduction
In this post you will find my notes on deploying an nginx server on
a digitalocean droplet from the command line. I'll be using doctl
,
the command line tool provided by digitalocean as well as a bash script to do
all of the server setup. This post builds on two previous posts that might
be helpful to check out:
- doctl for command line deployment of digitalocean droplet (2025) and,
- VPS setup on digitalocean (2022) .
This post will combine the goals of the above references:
- setup of a VPS droplet runnning nginx, and
- use the command line (doctl and bash) to do it all.
warning
A reminder that launching a droplet on digitalocean is NOT free. So, proceed with caution and make sure you have the funds available to move forward :)
Creating the server with doctl
In a
previous post
I went over how to launch a droplet/VPS using doctl. As a result, I will not
repeat the details here. The doctl
command that I will use
here is:
$ doctl compute droplet create test-nginx \
--tag-names test-nginx-tag \
--image ubuntu-24-04-x64 \
--region nyc1 \
--size s-1vcpu-1gb \
--ssh-keys [---censored---] \
--user-data-file nginx-server-setup.sh \
--enable-ipv6 \
--enable-private-networking
This command will create a droplet/VPS with the following properties:
- the droplet name is "test-nginx",
- the droplet is given a tag "test-nginx-tag",
- the server OS is Ubuntu 24.04,
- the droplet is created in digitalocean's nyc1 data center
- the droplet size is 1 cpu, 1gb ram (1,000 GB transfer per month, 25GB SSD, $6/month on this date)
- the fingerprint for ssh key uploaded to server is given [censored] (see the previous post for more about this aspect)
- the bash script "nginx-server-setup.sh" is run on the new droplet to do all of the setup
- ipv6 networking is enabled, and
- private networking is enabled.
bash script for server setup
The bash script that is passed by the doctl
command will do all of the server set up, including installing nginx. The
script is commented, making this not too difficult to follow:
nginx-server-setup.sh
#!/bin/bash
set -euo pipefail
# [1]
# - set variables
#
USERNAME=testuser
DOMAIN=testdomain
# [2]
# - update ubuntu
# - install nginx
#
apt update
apt install nginx -y
# [3]
# - create non-root user
# - add to sudo group
# - force user to create password on first login
#
useradd --create-home --shell "/bin/bash" --groups sudo "${USERNAME}"
passwd --delete "${USERNAME}"
chage --lastday 0 "${USERNAME}"
# [4]
# - import ssh key
#
home_directory="$(eval echo ~${USERNAME})"
mkdir --parents "${home_directory}/.ssh"
cp /root/.ssh/authorized_keys "${home_directory}/.ssh"
chmod 0700 "${home_directory}/.ssh"
chmod 0600 "${home_directory}/.ssh/authorized_keys"
chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh"
# [5]
# - disable root login with password
#
sed --in-place 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config
if sshd -t -q; then systemctl restart sshd; fi
# [6]
# - create directories and index.html for domain
#
mkdir -p /var/www/${DOMAIN}/html
chown -R $USERNAME:$USERNAME /var/www/${DOMAIN}/html
chmod -R 755 /var/www/
cat > /var/www/${DOMAIN}/html/index.html << EOF
<html>
<head>
<title>Welcome to ${DOMAIN}!</title>
</head>
<body>
<h1>Success! Welcome to ${DOMAIN}!</h1>
</body>
</html>
EOF
# [7]
# - setup server block
#
cat > /etc/nginx/sites-available/$DOMAIN << EOF
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/${DOMAIN}/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
# [8]
# - create symbolic link to make active
# - delete default server block from nginx
#
ln -s /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default
# [9]
#- restart nginx
#
systemctl restart nginx
# [10]
# - set up ufw
# - allow Nginx Full on ports 80 and 443, by default
# - allow OpenSSH on port 22, by default
ufw default allow outgoing
ufw default deny incoming
ufw allow 'Nginx Full'
ufw allow 'OpenSSH'
ufw enable
The doctl
command and script above were run on Mar 5, 2025 and
worked just fine. Note that it takes a minute or two for nginx to be installed
and setup before the success page is displayed. Below is a quick explanation
of the things done in the bash script:
- Variable are set-- you should change these. The USERNAME and DOMAIN are used in other parts of the set up.
- Ubuntu package database is updated and nginx installed
- A non-root user is created, using the USERNAME variable, and added to the sudo group. The password is aged to force password creation by the user with first login.
- A home directory for the user is created and ssh key imported
- Root login with password is prohibited
- Directories and persmission for the domain are created and a simple
index.html
is placed in the new html directory for the domain - A server block (virtual domain) is created for the domain. This is a very simple configuration and sets the new domain to be the "default" for nginx.
- The html for the new domain is "enabled" by creating a soft link and the soft link for the nginx default werver block is deleted.
- nginx is restarted
- The ufw firewall is setup to
- Allow all outgoing traffic
- Deny all incoming traffice
- 'Nginx Full' is allowed (ports 80 and 443)
- 'OpenSHH' is allowed (port 22)
- The ufw firewall is enabled.
Well, that's it. If you need help with SSH to the server, check the previous post. It is exactly the same.