New to Rust? Grab our free Rust for Beginners eBook Get it free →
How To Deploy a Static Website to the Cloud with DigitalOcean App Platform

DigitalOcean can find the GitHub repository and still fail the deployment when the source directory, build command, or output directory points at the wrong place. I kept the sample at a root index.html because that removes two decisions from the first static-site deployment.
I tested the sample through a local HTTP server that requested its heading and stylesheet before the repository moved to App Platform, while generated sites add the build and output steps after the plain HTML path works.
What App Platform deploys for a static site
A DigitalOcean App Platform static-site component builds or reads files from a Git repository, then serves the output through DigitalOcean’s content delivery network instead of running a persistent web server.
| Repository type | Build command | Output directory |
|---|---|---|
| Plain HTML, CSS, and JavaScript | Leave blank | The directory containing index.html |
| Vite, Astro, Hugo, or another generator | The project’s production build command | The generated folder, such as dist or public |
DigitalOcean’s current free tier includes three apps with static sites, 1 GiB of data transfer per app, automatic HTTPS, custom domains, and a global content delivery network. Check the App Platform pricing page before launch because a paid service component changes the bill.
What you need before connecting the repository
The deployment source can be GitHub or GitLab, and this walkthrough uses GitHub with a main branch plus a plain static site before showing where a generated site differs.
do-static-site/
├── index.html
├── style.css
└── verify-site.sh
You also need DigitalOcean and GitHub accounts, plus the production build command and generated folder when a framework builds the site.
App Platform scans the repository root by default. A monorepo or nested project needs an explicit source directory, while a generated site needs an output directory that contains the built index.html.
How to deploy a static website to DigitalOcean App Platform
The repository moves from local files to a committed branch, then to a deployed static-site component.
Create a root index.html
A plain HTML site needs no build command, so App Platform can serve the repository contents directly. Save this file as index.html at the repository root.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DigitalOcean Static Site</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<h1>The static site is ready</h1>
<p>This page is served from the repository root.</p>
</main>
</body>
</html>
The link element makes the stylesheet part of the check. A page that loads while style.css returns a missing-file response is not ready to push.
Verify the local files through HTTP
This check starts a local server, requests the page and stylesheet, then stops the server, so save it as verify-site.sh beside index.html and make it executable.
#!/usr/bin/env bash
set -euo pipefail
python3 -m http.server 3100 >/dev/null 2>&1 &
server_pid=$!
trap 'kill "$server_pid" 2>/dev/null || true' EXIT
for attempt in 1 2 3 4 5; do
if page=$(curl --fail --silent http://127.0.0.1:3100/); then
break
fi
sleep 1
done
printf '%s' "$page" | grep -q '<h1>The static site is ready</h1>'
asset_status=$(curl --silent --output /dev/null \
--write-out '%{http_code}' http://127.0.0.1:3100/style.css)
printf 'index.html heading: OK\n'
printf 'style.css status: %s\n' "$asset_status"
printf 'site check: PASS\n'
The shell exits on a failed request or missing heading because set -e is active. Run the check only after style.css exists in the same directory.
chmod +x verify-site.sh
./verify-site.sh

The stylesheet returned HTTP 200, so the local page and its linked asset are available from the same root that a plain static-site component needs.
Commit the verified site to GitHub
Initialize the repository on the main branch and commit only after the local check passes, because I kept the committed main branch clean before adding its remote.
git init -b main
git add index.html style.css verify-site.sh
git commit -m "Prepare static site"
git status --short --branch
Create an empty repository on GitHub, then use the repository-specific commands GitHub shows under push an existing repository from the command line. This keeps the remote URL tied to your account instead of copying a placeholder that cannot authenticate.
Connect the repository in App Platform
Open the DigitalOcean control panel, choose App Platform, and create an app from source code. Select GitHub, authorize access to the repository, choose the repository, and select the main branch.
- Confirm the detected component type is Static Site.
- Keep the source directory at the repository root for this sample.
- Leave the build command blank because the repository already contains deployable files.
- Set the output directory to the repository root if the control panel asks for one.
- Keep autodeploy enabled when pushes to main should create deployments.
A generated site changes items three and four. Enter the production build command, then point the output directory at the folder that command creates.
| Project | Build command | Common output directory |
|---|---|---|
| Plain HTML | Blank | Repository root |
| Vite | npm run build | dist |
| Hugo | hugo | public |
Use the folder created by your own build rather than treating the table as a fixed rule. The output directory must contain the index document and every asset referenced by it.
Launch and verify the deployment
Review the plan before launch and remove any service component you did not intend to add. A static site can use the $0 tier, while a web service starts on paid compute.
- Open the Deployments view and require a successful build.
- Open View Logs when the build fails.
- Use Live App and confirm the heading plus the stylesheet.
- Check a nested route when the site uses client-side routing.
DigitalOcean’s static-assets sample documentation states that a root index.html lets App Platform detect static assets. It also points to the Deployments tab and build logs as the evidence for a successful release.
Fix repository, build, output, and route failures
Deployment failures become quicker to diagnose when you match the visible symptom to the field that controls it. Change one field, create a new deployment, and read the new log before changing another.
| Symptom | Check | Fix |
|---|---|---|
| The repository is missing | GitHub App permissions | Grant DigitalOcean access to that repository or organization, then reconnect the source. |
| App Platform cannot find index.html | Source directory | Point it at the folder that contains the source index, or set the correct index document. |
| The output directory does not exist | Build command and generated folder | Run the production build locally, note the folder it creates, and use that exact folder. |
| The build command fails | Deployment log and runtime settings | Use the command that succeeds from a clean checkout and add required build-time variables. |
| Nested routes return 404 | Catch-all document | For a single-page application, set the catch-all document to index.html. |
| A push creates no deployment | Branch and autodeploy | Match the configured branch to the pushed branch and enable autodeploy. |
I checked the generated folder before changing any hosting setting because a missing output directory is a build-result problem. The production build must create the configured folder before App Platform can publish it.
Let the next push prove the setup
Change the heading, commit it, and push to main. A new successful deployment followed by the changed Live App page proves that the repository, branch, build, output, and autodeploy settings agree.
git add index.html
git commit -m "Change the home page"
git push
If no deployment starts, check the configured branch before rebuilding the app. The branch is the trigger, so a clean site on the wrong branch will remain unchanged.
DigitalOcean static-site questions
These answers cover plan and configuration decisions that sit outside the main deployment path.
Is a DigitalOcean App Platform static site free?
DigitalOcean lists a $0 tier with three apps containing static sites and 1 GiB of transfer per app. Paid service components and usage outside the included limits can add charges.
Can App Platform deploy a private GitHub repository?
Yes. The DigitalOcean GitHub App needs permission to read the repository or its organization before the repository appears in the source picker.
Does a plain HTML site need a build command?
No. Leave the build command blank when the repository already contains index.html and the files App Platform should serve.
Can I use a custom domain with the static site?
Yes. Add the domain in the app settings, follow the displayed DNS instructions, and wait for DigitalOcean to provision HTTPS before switching traffic.




