Moving a Node App from Google Compute Engine to DigitalOcean
Tags: node, hosting, webdev
Published: 2021-10-13 22:19:40

There’s nothing like trying to deploy a minor site update and having your VM hang while SSHing 75% of the time, give up mid-build the other 25%, and then fall apart completely when you try to restart it. Since all I remember about setting up a Google Compute Engine Node instance in the first place is that it took me a while and wasn’t particularly intuitive, this seemed like a good opportunity to try a new host. I’m running a commercial Next.js site with a custom server so after browsing around [DigitalOcean](https://m.do.co/c/fe46dcdd5314) seemed like the best option.

And it was actually pretty painless!

Of course, it would be even quicker with a step-by-step guide so here’s a reference for my future self or anyone else who wants it. My guide for migrating a Node app to DigitalOcean (this may vary a little depending on your site):

1. **Sign up for DigitalOcean and create a Droplet using [NodeJS 1-Click App](https://marketplace.digitalocean.com/apps/nodejs).** Poking around the DigitalOcean Community questions, I ran into some talk about additional installations for production but my Droplet came with Nginx, PM2, and optional Let's Encrypt for SSL out of the box so those discussions may be a little out of date.
2. **Add the new IPv4 address to MongoDB Atlas.** DigitalOcean provides instructions for getting started with your Droplet but I wound up skipping around a bit. Since I already had a MongoDB database set up, I completely ignored their section on creating a new one. To use an existing database, just remember to log in to MongoDB Atlas and add your new IP address (using port 22) to the IP Address List under Network Access.
3. **Clone your repo.** Using `ssh root@0.0.0.0` (replacing the zeros with your IP address), ssh into your Droplet and clone your repo.
4. **Copy environmental variable files, assets, etc.** From outside your Droplet, use `scp -r /path/on/computer root@0.0.0.0:/path/on/droplet` (replacing the paths and zeros) to copy any necessary files that weren't included in the repo.
5. **Start your app.** Back in the Droplet, start with a good old `yarn install`. Then, for a Next.js site, run `yarn build` followed by `sudo NODE_ENV=production -u nodejs pm2 start server.js` to start a custom server. This is also a good time to jump back to the DigitalOcean instructions for shutting down the starter app with `sudo -u nodejs pm2 delete hello` and saving your PM2 process list with `sudo -u nodejs pm2 save`.
6.  **Create an Nginx configuration.** I added “read up on everything Nginx can do” to my todo list but for now I have a pretty simple config with basic asset caching in my `/etc/nginx/sites-enabled/` directory. You can view the file in [this Gist](https://gist.github.com/laurenashpole/352cbd10fbf35483b79a24a1c1c4e52d) but keep in mind it's pretty tailored to my SSL setup. Whether you alter my example, the DigitalOcean default, or start fresh, make sure to 1) switch the `root` setting to something like  `/root/your-site/.next/pages;` for Next.js and 2) update the `proxy_pass` to use your app's port (8443 in my example). Restart with `sudo systemctl restart nginx`.
7.  **Point your domain to the new IPv4 address**. How you do this will depend on your DNS host but you’ll want to complete the migration by updating your `A name` to point to your new IP address.

There it is in seven steps. The first run through took some trial and error but hopefully this will speed things up next time.