Hey there 🙋♂️🙋♂️. Today, I’ll share how you can host your basic Single Page App for free using Digital Ocean’s App Platform. Why would you want to use Digital Ocean? To quote my mentor
“Digital Ocean is the poor man’s AWS”
-Lino
Side projects are fun but if you aren’t careful, they can rack up quite a bill. Now I won’t say you can’t bankrupt yourself with Digital Ocean, but at least you’ll be able to see yourself shooting your foot easily without needing to dig through infinite menus and an atrocious UI. Moving on
What is Digital Ocean’s App Platform?
From their docs
App Platform is a Platform-as-a-Service (PaaS) offering that allows developers to publish code directly to DigitalOcean servers without worrying about the underlying infrastructure.
🤷♂️🤷♂️ That’s it. It’s pretty similar to Vercel, Netlify or Heroku in that regard with the added benefit that its framework agnostic.
What benefits does Digital Ocean’ App Platform give me
For this article, the main benefit is that you can host 3 free static sites. This means, as long as you’re not doing anything crazy like Server-Side Rendering then it’s basically 3 free websites for you. I mean you do still need to buy your own custom domains if you don’t want the default one but that’s a minor issue.
Setting up the CI/CD pipeline
For my frontend framework, I’m using Vue, GitHub for my repository, and GitHub actions for running my deployment pipeline.
Digital Ocean’s App Platform tries to automatically determine what configuration your project needs based on your repository source files. From my experience, it struggles to give you the free static site hosting option if you pass in your source code repository directly. Instead, you can create a separate repository to store your build outputs and then reference that in Digital Ocean. This has three main benefits.
You keep the auto-deployment features of Digital Ocean
You can easily automate pushing your changes
The git history inherently gives you a backup since you have a history of your website’s state at any point in time
This isn’t the only way you can set things up, but I did find it to be simple and quick.
With that out of the way, here’s the YAML
file for the build steps you can put in the .github/workflows/deploy.yml
.
name: Build and Deploy
# trigger manually or on pushing to the main branch
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '22'
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
- name: Deploy to a separate repository
env:
DEPLOY_BRANCH: main
PAT: ${{ secrets.PAT }}
run: |
git clone https://$PAT@github.com/<username>/<repo name>.git out
rm -r out/*
cp -R dist/* out/
cd out
cp index.html 404.html
git config --global user.email "<email address>"
git config --global user.name "<username>"
git add .
git commit -m "Deploy build files"
git push origin $DEPLOY_BRANCH
This is a pretty straightforward build script that builds your project and pushes the outputs to a separate repository. This script does need you to do a bit of replacement though explained below to get it to work correctly.
<username>
Replace this with your GitHub username<repo name>
Replace this with your build output repository that I mentioned earlier<email address>
Replace this with your email address
Aside from this, you also need a Personal Access Token (PAT) so that the build script has permission to push your changes to the build output repository. Make sure it has full repository permissions. I’d recommend you only allow your token to have permission for that single-build output repository for security purposes.
Now this part is VERY VERY important. Don’t paste your PAT into this build script. Please don’t, Please don’t, you will expose it for all the world to see. This is a bad idea. Downright terrible. What you want to do instead is create a GitHub Action Secret with the name PAT
and the build script will automatically pick that up. This is way way better.
Side Note
you might notice this line in the YAML
file.
cp index.html 404.html
Digital Ocean’s App Platform doesn’t have a catch-all redirect for the free static site hosting. This is a problem for our SPA since anything that’s not /
will return a 404
. To get around this minor inconvenience we create a 404.html
page that’s returned alongside the 404
response which the App Platform does support. Since in our case, our 404.html
page is a direct copy of our index.html
page, we’ve now effectively implemented our catch-all redirect to index.html
.
Setting up the Digital Ocean App Platform
Firstly, you want to set up a Digital Oceans Account. When logged in navigate to the App Platform menu and create a new App.
Next, select the repository that contains your build output.
You should see something similar to the screen below if you've done this right. The important point is that it mentions your resource is a static site, thats how we get the free 💸💸.
Afterwards, you can continue without changing anything and congratulations 🥳🥳 we have a free website just like that.