Scaling down my VMs
I've had custom apps running on DigitalOcean VMs for years even though it wasn't the most cost efficient nor clean way to run them.
It's high time I turned them down.
Moving domains from .io to .dev
.io domains now cost $64 per year while .dev and .com domains cost only $12 per year. So I stopped renewing my io domains. Now all my mobile apps that point to them need to be recompiled with the new domain name.
- Stop the renewal of the io domains on the registrars.
- Set up a new DNS on the .dev domains to point to the same VM.
- Go to the VM, regenerate the SSL certificates with Certbot.
- Change the domain name in the nginx config. Reload nginx.
- Recompile my mobile apps to use the new domain.
- Publish an update.
Moving an Apache web client to Firebase hosting
The smallest DigitalOcean VM costs $7 per month to run. The web client I am using is completely static. Hence it could be hosted on Firebase hosting.
However the web client is so old that I am not confident I could recompile it from the code. I also need to check what else was on that VM so that I can back it up before destroying it.
Here's the problem: The VM is 6 years old. At the time, for security reasons, I disabled access through login/password and only allowed login through whitelisted SSH keys. Since then, I've sold my old computers. So now I cannot access that VM on my new Mac. I had to go use the Recovery Console:
Use the Recovery Console if you need to use the recovery ISO or you can't connect to your Droplet with the Droplet Console. To use the recovery console, you must enable password authentication. If necessary, you can reset your root password below.
Recovery Console
So I reset my root password, then accessed the Recovery Console. I went into ~/.ssh/authorized_keys
and tried to add a new one. The issue? Copy/paste does not work properly in that Recovery Console!!
Droplet Console
DigitalOcean proposes a second way to SSH into the VM: the Droplet Console. I try running that command.
It fails because I don't have wget installed on my machine. A Google search tells me I should run brew install wget
. It fails with this error:
Error: can't modify frozen String: "The bottle needs the Xcode Command Line Tools to be installed at /Library/Developer/CommandLineTools.\nDevelopment tools provided by Xcode.app are not sufficient.\n\nYou can install the Xcode Command Line Tools, if desired, with:\n xcode-select --install\n"
So I run xcode-select --install
and it decides to download the Internet.
Then I try again:
% wget -qO- https://repos-droplet.digitalocean.com/install.sh | sudo bash
Password:
Verifying machine compatibility...
bash: line 246: dmidecode: command not found
The DigitalOcean Droplet Agent is only supported on DigitalOcean machines.
I was supposed to run it on the VM itself. Can't read...
Once installed, the option to SSH into it on the browser shows up:
Luckily this browser client works better than the recovery console and I was able to copy/paste my new public key into authorized_keys.
I then SSH into it properly, and back up /var/www.html:
/var/www# tar czf project_name.tar.gz html
Then I copy it into my Mac:
scp root@[VM IP]:/var/www/project_name.tar.gz .
Firebase Hosting
Running this command throws a bunch of errors:
% npm install -g firebase-tools
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: 'firebase-tools@13.29.2',
npm WARN EBADENGINE required: { node: '>=18.0.0 || >=20.0.0' },
npm WARN EBADENGINE current: { node: 'v16.17.0', npm: '8.19.3' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@google-cloud/cloud-sql-connector@1.6.0',
npm WARN EBADENGINE required: { node: '>=18' },
npm WARN EBADENGINE current: { node: 'v16.17.0', npm: '8.19.3' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: 'marked@13.0.3',
npm WARN EBADENGINE required: { node: '>= 18' },
npm WARN EBADENGINE current: { node: 'v16.17.0', npm: '8.19.3' }
npm WARN EBADENGINE }
...
I need to switch to Node 18+:
% nvm use 18
Now using node v18.18.0 (npm v10.1.0)
% npm install -g firebase-tools
added 636 packages in 5s
70 packages are looking for funding
run `npm fund` for details
The tool is pretty nice.
Once set up, I can deploy the static files:
% firebase deploy
=== Deploying to 'project_name'...
i deploying hosting
i hosting[project_name]: beginning deploy...
i hosting[project_name]: found 7 files in public
✔ hosting[project_name]: file upload complete
i hosting[project_name]: finalizing version...
✔ hosting[project_name]: version finalized
i hosting[project_name]: releasing new version...
✔ hosting[project_name]: release complete
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/project_name/overview
Hosting URL: https://project_name.web.app
The last step is to set up the domain names correctly. When I click "Add custom domain", Firebase asks me to modify the DNS settings to verify my domain ownership. Once that is done, it shows up in my list of domains where the web app is served, and next to the new domain, it says "Minting certificate".
Nice! Now I won't have to run certbot and generate SSL certificates myself anymore!
Wrong instructions from Firebase
Firebase told me to delete the previous [my_app] A field from [my_domain].dev and set up the CNAME as domain: [my_app].[my_domain].dev
and wouldn't pass validation until I did. So after it validated, I waited a good 3 hours for the DNS to change.
After 3 hours, pinging failed. Then I googled how long Squarespace actually updates CNAME fields. I found this: https://forum.squarespace.com/topic/320695-two-days-and-cname-has-not-propagated-anywhere/. They complain it's been two days, to which someone responds that the CNAME field should only be [my_app]. So I added such a field and also verified with ping [my_app].[my_domain].dev.[my_domain].dev
and this did indeed return. So like the last person said, Google was wrong. Wow.