Move Website From GoDaddy Shared Host to Digital Ocean VPS

This will be a documentation of moving a website from GoDaddy shared hosting to Digital Ocean droplet.  Any other cloud hosting service should work with variation in the server creation on the cloud system.  For example other services such as Linode etc.  Note that Digital Ocean calls their virtual machines droplets, other providers will have a different name.

While documenting this process I moved the domain 09flhrc.com from GoDaddy shared hosting to a Digital Ocean Droplet. For this documentation I am using this bogus IP address to represent the IP address assigned to the droplet: 123.456.709.012

Digital Ocean

AI description:  DigitalOcean is a developer-friendly cloud infrastructure-as-a-service (IaaS) provider offering simple, scalable, and cost-effective virtual machines (Droplets), managed databases, and Kubernetes. Designed for startups and SMBs, it simplifies deployment with a user-friendly interface, 1-click apps, and transparent pricing starting at $4–$5/month.

Key details about DigitalOcean include: Core Product (Droplets): Linux-based virtual machines that can be deployed in seconds to run applications.

Key Offerings: Compute: Droplets (shared or dedicated CPU). Storage: Block and Object storage. Database: Managed MySQL, PostgreSQL, Redis, and MongoDB. Networking: Firewalls, load balancers, and Virtual Private Cloud (VPC). Platform as a Service (PaaS): DigitalOcean App Platform for deploying code directly. Target Audience: Software developers, startups, and small-to-medium businesses (SMBs).

Key Advantages: Known for simplicity, developer experience, and extensive documentation/tutorials.

It is often chosen as an alternative to more complex cloud providers like AWS, Google Cloud, or Azure. Reddit Reddit

Create Droplet (virtual machine)

  • log in or create an account on Digital Ocean
  • Droplets are grouped under Projects - may have to create an inital project
  • Create a droplet for this test I chose:   - 2 GB Memory   - 60 GB Disk   - SFO2   - Ubuntu 24.04 (LTS) x64  (you can choose from several distros.  For this I went with Ubuntu Long Term Support.

Looks like plenty of options to upgrade the server, so perhaps go with the smallest option and upgrade if needed later.  With static webpage and no database needed we do not have to have too much power.

When creating the droplet I chose to login with root and password.  An option was provided during setup to create a root password.  

You can also choose to set up with ssh.  I chose the login with password in case ssh keys are lost.  When I set up the server, a user will be created who will log in with ssh keys.  I will disable root login with ssh, and leave the root password access for the Digital Ocean console as a option of all else fails.  If this turns out to be a bad ideal I can go back and change the console to ssh access only.

A status dashboard will appear.  When the server is created, the status and IP address will be shown.  Copy the IP address.

Now that we have an IP address we can check to see if they installed sshd while creating the server.  If not we can log into the Digital Ocean console to install ssh.

Go to the terminal on your computer and ssh into the droplet:


ssh root@123.456.709.012

change server ip to the IP address of your server

For me the ssh attempt worked so sshd was installed on my droplet.

set up DNS

It is going to take a while for the IP changes to propagate across the Internet.  Now that we have an IP address lets get the process started to change the DNS records for our domain.

check DNS tool

I used mxtoolbox.com to check the domain and DNS record this tool will show what DNS records the domain servers have

Next: Go to GoDaddy account

Go to the domain you want to edit.

make a copy of the current DNS records

I removed all the CNAME records except the www which pointed to the domain.  I then edited the main “@” A record and changed the IP address to the address of my Digital Ocean droplet.

go back to mxtoolbox.com to check if the new IP is used.  I used this tool to keep checking the records and watching for the droplet IP to appear.

Set Up and Configure the Server

Update the system’s local package index, checking repositories for newer versions of installed software.


apt update && apt upgrade -y

When I updated the packages it appeared to update the kernel and wanted a reboot.  Now is a good time to reboot and make sure the droplet comes back up as expected.


reboot

the connection should disconnect and reset.  Wait a minute or two and ssh back in (you should be at your local pc prompt and not the server prompt)


ssh root@123.456.709.012

most terminal emulators have a history so you should be able to hit the up arrow to get the ssh command that was entered earlier

Yes, the kernel was updated during the upgrade.  The first time I logged into the server the motd (message of the day) showed:

Welcome to Ubuntu 24.04.3 LTS (GNU/Linux 6.8.0-71-generic x86_64)

now it shows

Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-100-generic x86_64)

Install packages

We need to set up the firewall to shut down unneeded ports.  Will use ufw.  Let’s check to see if it is installed first:


which ufw

The server responded with


/usr/sbin/ufw

ufw is installed on this droplet

install nginx webserver


apt install nginx

check version to confirm install


nginx -v

also check if nginx is running


systemctl status nginx

ctrl c to exit

go to web browser and enter the IP address of the server.  We should get the generic Welcome to nginx! page if the droplet is serving the webpage.

The folder for the generic website is located at:


/var/www/html

use nano or neovim to modify the index file at this location to validate that is indeed the location nginx is using.  Change the title or the h1 tag. save

better yet, change the default to say that the domain is under construction.  Please check back in a little while after maintenance is complete.

check the server again in the browser to see if changes are shown you may have to use the IP address of the droplet until DNS propagates

once DNS is updated the webpage will change from what was on GoDaddy to the droplet nginx default

nginx sites


cd /etc/nginx

list the dir /etc/nginx/sites-available

there should be a default file with configuration for the default website

create a new configuration file for the new website


nvim /etc/nginx/sites-available/09flhrc.com

add server block to file


server {

    listen 80;

    server_name 09flhrc.com www.09flhrc.com;

    root /var/www/html;

    index index.html;

    location / {

        try_files $uri $uri/ =404;

    }

}

create a link to the configuration file to the sites-enabled dir


ln -s /etc/nginx/sites-available/09flhrc.com /etc/nginx/sites-enabled/

list the sites-enabled dir to verify the link was created


ls /etc/nginx/sites-enabled

check for configuration errors


nginx -t

rename the default html to index.html


cd /var/www/html

mv index.nginx-debian.html index.html

reload nginx


systemctl reload nginx

go back to browser to make sure web page is served

Server Security

set up firewall


ufw status

allow port 22 (ssh) before enabling the firewall.  we connect via ssh so it would be bad to block port 22


ufw allow OpenSSH

OpenSSH is a shortcut to allow ssh ports


ufw enable

check status of ufw


ufw status vebose

check webpage.  ufw should be preventing the webpage from loading.  we closed all ports except for 22.  Now lets open ports 80 and 443 for http and https

Nginx Full is shortcut for nginx ports


ufw allow 'Nginx Full'

now check the browser to see if the webpage is now served.

SSH key No Root, No Password

create user


adduser jim

Add user to sudo for elevated privileges


usermod -aG sudo jim

exit as root


exit

now ssh as this user from computer terminal


ssh jim@09flhrc.com

if unsuccessful then DNS may not have propagated, try

ssh jim@123.456.709.012

if successful exit


exit

you should be back to the local computer prompt

create ssh key

technically for ssh key comment you would enter your email address, but I did not this time


ssh-keygen -t ed25519 -C "DO Droplet RSGW"

follow prompts to save in the user .ssh directory.  you should rename the key if you already have a key  or want keys named.  When prompt comes up for Enter file in which to save key enter on Windows:


C:\Users\jim/.ssh/rsgwdroplet

enter a passphrase if you want a more secure key.  The password will have to be entered each time the key is used if you are worried about keys getting in wrong hands.  Note when sharing keys on a server. there are 2 ssh keys, always use the key with .pub, not the other private key.  No security risk if someone has the .pub key.

copy the public key to the droplet


ssh-copy-id jim@serverip or domain

Windows does not have a ssh-copy-id command.  I have git installed and was able to use the git bash terminal to install the key.  Notice I changed into the .ssh directory and listed to see the key name and make the copy command cleaner.  otherwise you will need to add the path to the public key. There are other ways to copy the key in Windows, but since the Git bash shell worked I did not try others.


cd .ssh

ls

ssh-copy-id -i 09flhrc.pub jim@09flhrc.com

will prompt for password and install the key if successful.

now try to log in to the droplet using the ssh key. It should not ask for a password since you are authenticating via ssh key


ssh -i ./09flhrc jim@09flhrc.com

modify the sshd_config to no allow passwords


sudo nvim /etc/ssh/ssh_config

we have to use sudo to gain elevated privileges.  if not using neovim editor change nvim to editor of choice i.e. nano

find PermitRootLogin change to PermitRootLogin no

find #PasswordAuthentication yes and change to

PasswordAuthentication no

PermitEmptyPasswords no

note that the # was removed

UsePAM no

X11Forwarding no

at the bottom of the file add


AuthenticationMethods publickey

AllowUsers jim randy

restart ssh to read the config file


sudo systemctl restart ssh

and exit from server to test


exit

test with fake account


ssh fake@serverip

should get permission denied (publickey)

.ssh/config

You can set up an ssh config file so that you do not have to enter the -i command and make ssh easier to enter and remember.  This config file located on the remote PC in the .ssh dir is a file named config.  You can set up this file so that you can ssh into the above server with


ssh 09flhrc

Example SSH config file


Host 09flhrc

    HostName 09flhrc.com

    User jim

    IdentityFile ~/.ssh/09flhrc

Install Certbot

certbot is not in the Ubuntu repository but is available in snap


sudo snap install --classic certbot

create certs


certbot --nginx

check the 09flhrc configuration file to see if certbot made changes

cat, nano or nvim


sudo nvim /etc/nginx/sites-available/rsgaugeworks.com

you can now go to the browser and refresh the web page.  it should now have SSL certificate and be routed to https.  You can examine the cert to validate it is from Let’s Encrypt.

Certbot should refresh the cert every 90 days. (a cron job has been added by the certbot installation)

Use Git to manage website files

download git

Once downloaded I find using the Git bash terminal works best when working with ssh and git on Windows.  You can right click on the upper tab in Windows Terminal to select Git Bash shell

validate git


git --version

configure git


git config --global user.name "Jim"

git config --global user.email "myemail@gmail.com"

make a directory where you will store your html files

initialize the directory


git init

add html files for the webserver

then add to git


git add .

commit the changes to git


git commit -m "Initial Commit" -a

-m is commit message

-a all files

GitHub

create or navigate to your Github repository where you will maintain the html files.

Verify your SSH key is set up locally: Ensure your private key is in the ~/.ssh/ folder.

Ensure the key is added to the SSH agent: Run eval “$(ssh-agent -s)” and then ssh-add ~/.ssh/your_private_key.

Confirm the public key is on the remote service: Make sure the content of your public key file (e.g., ~/.ssh/id_rsa.pub) has been added to your user profile’s SSH keys section on the hosting platform (e.g., GitHub SSH settings).

Test the SSH connection: Run ssh -T git@github.com (replace github.com with your host if different). A successful connection will usually display a welcome message with your username.

Ensure you’re using the correct SSH URL format: The URL should typically look like git@github.com:username/repo-name.git.

Add your public ssh key to Github

test ssh


ssh -vT git@github.com

copy the github ssl command from repository (found under Code button)


git@github.com:tipnmog/rsgaugeworks.git

add your remote to the origin then check that the url is correct with-v


git remote add origin git@github.com:tipnmog/rsgaugeworks.git

git remote -v

now push your commit to the origin (Github)  note the origin name used to be master and now most have been changed to main.


git push origin master

clone the repository into the webserver

navigate to the location to clone to on the server. In this example I loaded the rsgaugeworks site to the droplet for testing


cd /var/www/html

sudo git clone https://github.com/tipnmog/rsgaugeworks.git

Update the sites available file


sudo nvim /etc/nginx/sites-available/09flhrc.com

reload nginx


sudo systemctl reload nginx

go back to browser to make sure web page is served

Fail2ban

Fail2ban is an open-source intrusion prevention framework written in Python that protects Linux servers from brute-force attacks and unauthorized access. It works by scanning service log files (e.g., /var/log/auth.log) for malicious patterns, such as too many failed login attempts, and automatically updates firewall rules (iptables, FirewallD) to temporarily or permanently ban the offending IP addresses.

Install package


sudo apt install fail2ban

check status


systemctl status fail2ban

go to fail2ban configuration dir


cd /etc/fail2ban

create fail2ban.local - fail2ban will not overwrite this file. it is best practice to use the .local files, fail2ban will read these if present, but will not overwrite them during updates.


cp fail2ban.conf fail2ban.local

create a jail.local which will not be overwritten during updates


sudo cp jail.conf jail.local

you can update the jail.local to change the bantime, findtime, and maxretrys  will default to banning if 5 failures occur (maxretry) in 10 minutes (findtime) it will ban for 10 minutes (bantime).  Note that ssh gives 3 attempts to correct the password.  Each of these 3 attempts will be 1 attempt (retry) in fail2ban

will need to install sendmail if you want to set up email notices

check the jails in the config file.  Note that sshd jail is enabled by default. If you want to use one of the jails enter


enabled = true

under the jail name.

check to see what jails are active


fail2ban-client status

jails in the Jail list: are enabled

to check fail2ban log


sudo nvim /var/log/fail2ban/log

Server Maintenance

certbot pulls a certificate which is valid for 90 days.  It creates a cron job to refresh that certificate.  Create a meeting invite in your calendar or on your calendar for day after the cert expires to make sure the refresh happened.  You can get that info by looking at the cert on the website.  The cert I have looks like this:

Common Name (CN)   09flhrc.com

Organisation (O)    

Organisational Unit (OU)    

Common Name (CN)    E8

Organisation (O)    Let’s Encrypt

Organisational Unit (OU)    

Issued On   Saturday, 21 February 2026 at 13:00:47

Expires On  Friday, 22 May 2026 at 13:00:46

Certificate a88b0522ae08289018d4241a11e6a54397f478868cdc6d416d2fd4aebadec614

Public key  fd397f2b94b2ce3942ec2435bf2c23095aa39562aec2669ec40c900817962792

I can set a meeting invite on 5/22/2026 at 2:00pm to check the cert.

monthly do updates and upgrades

sudo apt update && sudo upgrade -y