Skip to content
  • 10 cloud providers
  • 51 configurations
  • Competitive pricing
  • Developer friendly

A first production deployment on DigitalOcean, start to finish

The path from an empty account to an application serving real traffic over HTTPS, with the security and backup steps that are easy to skip and painful to add later.

Abstract illustration accompanying this guide on digitalocean deployment

This is the sequence for getting a small web application onto a DigitalOcean Droplet and serving real traffic, in an order that puts the irreversible decisions first and the easily-changed ones last.

It assumes a conventional application that listens on a port and stores its data in a database. It does not assume any particular language.

Before you create anything

Decide two things, because both are awkward to change afterwards.

Region. Pick the one closest to the majority of your users. Latency to the database matters more than most people expect, and moving a running service between regions means rebuilding.

Whether the database is managed or self-hosted. A managed database costs more per month and removes backups, failover and patching from your responsibilities. Self-hosting on the same Droplet is cheaper and puts all of that on you. Either is defensible; deciding later is expensive because migrating a live database is the least pleasant part of this whole process.

Create the Droplet

Choose a current long-term-support Linux image. Choose a size smaller than your instinct suggests, because resizing upward is quick and you have no real data yet.

Add your SSH public key during creation. Do not choose password authentication, even temporarily. A Droplet with password SSH exposed to the internet begins receiving brute-force attempts within minutes of being created, and “I will harden it later” is how machines get compromised in the gap.

Secure it before it serves anything

This is the section people skip, and it takes about fifteen minutes.

Create a non-root user with sudo rights and copy your SSH key to it. Then disable root SSH login and password authentication entirely in the SSH configuration, and restart the service. Keep your existing session open while you test the new one from a second terminal, so a mistake locks out a session rather than the machine.

Configure the cloud firewall, which sits outside the Droplet and is therefore not something a compromised process can disable. Allow inbound SSH, HTTP and HTTPS. Allow nothing else. In particular, do not expose the database port to the internet, even briefly, even with a strong password.

Enable automatic security updates so that the machine patches itself without you remembering.

Get the application running, unencrypted, on localhost

Install your runtime and dependencies, get the application running, and confirm it responds on its own port on localhost. Do not expose it publicly yet.

Put it under a process manager so it restarts on failure and starts on boot. Systemd is present already and is sufficient. A service that does not survive a reboot is not deployed, it is running.

Set configuration through environment variables rather than files in the repository, and keep secrets out of your shell history.

Put a reverse proxy in front

Install a web server as a reverse proxy in front of the application. It terminates TLS, serves static files efficiently, handles multiple applications on one machine, and gives you somewhere to set headers and rate limits.

Point your domain’s A record at the Droplet’s IP address and wait for DNS to propagate before the next step, because certificate issuance validates over the domain.

Add HTTPS

Use an automated certificate client to obtain and install a certificate. It will configure renewal automatically. Verify that renewal actually works rather than assuming it, because the failure mode arrives silently in ninety days.

Redirect HTTP to HTTPS once the certificate is in place, not before.

Back up, and test the restore

Two separate things, and both are necessary.

Droplet backups or snapshots capture the whole machine. Snapshots are manual and cheap; automated backups are scheduled and cost a percentage of the Droplet price. Either protects against the machine breaking.

Database backups protect against the data being wrong, which is the more common disaster. A managed database does this for you. A self-hosted one needs a scheduled dump written somewhere off the machine, because a backup stored on the server it is backing up protects against nothing.

Then restore one. A backup you have never restored is a hypothesis. Restoring into a throwaway Droplet takes twenty minutes and converts it into a fact.

Know when something breaks

Enable DigitalOcean’s monitoring agent and set alerts on CPU, memory and disk. Disk filling up is the single most common cause of a small server failing, and it is entirely preventable with one alert.

Add an external uptime check from somewhere outside the Droplet. Monitoring that runs on the machine cannot tell you the machine is unreachable.

Make sure the alerts go somewhere you will actually see at three in the morning, or accept honestly that you will find out in the morning.

After it is live

Two habits keep a small deployment healthy: apply system updates on a schedule you actually keep, and check the disk usage trend monthly. Almost everything else can wait.

When traffic grows, resize the Droplet before re-architecting. Vertical scaling is unglamorous and it solves an enormous proportion of real capacity problems for a fraction of the effort of anything else.

For the vendor’s own reference on the services involved here, see the DigitalOcean documentation.

Questions people ask

Should I disable password SSH login immediately?

Yes. Add your public key at creation time and disable password authentication and root login before the machine serves anything. Automated brute-force attempts begin within minutes of a Droplet appearing.

Do I need a reverse proxy in front of my application?

It is strongly advisable. It terminates TLS, serves static files efficiently, lets several applications share one machine, and gives you a place to set security headers and rate limits.

Are Droplet snapshots enough of a backup?

They protect against the machine breaking, not against the data being wrong, which is the more common failure. Take database backups separately and store them off the machine.

What usually breaks first on a small server?

The disk filling up, most often from logs. A single disk-usage alert prevents the majority of small-server outages.

Telegram