You've got your photos organised, your metadata filled in, and npm run dev shows a site you're happy with. Time to put it on the internet.
Obscura generates a plain dist/ folder of static files — no application server, no runtime, no database. You can host it anywhere that serves files over HTTP. Here are four options — pick whatever fits your setup.
The One Thing to Know First
Your original photos are gitignored — a portfolio of high-resolution images would make your repository enormous. Everything else under site/ (config, posts, pages, sidecar YAML) can be committed, but the source images themselves stay local. That means CI services can't build the site from your repo alone; they don't have the photos.
The simplest approach: build locally, deploy the output. Run npm run build on your machine and push only the dist/ folder. Every option below follows this pattern.
rsync to Your Own Server
If you have a VPS, a shared host with SSH access, or any machine you can reach over the network, rsync is hard to beat. It compares files on both sides and only transfers what's changed — which matters when your dist/ folder is hundreds of megabytes but you've only added a few new photos.
First deploy (uploads everything):
npm run build
rsync -avz --delete dist/ you@yourserver:/var/www/portfolio/
Subsequent deploys (only transfers changes):
npm run build && rsync -avz --delete dist/ you@yourserver:/var/www/portfolio/
The --delete flag removes files on the server that no longer exist locally — so if you delete a gallery or rename a post, the old files don't linger. The -avz flags preserve file attributes, show progress, and compress during transfer.
This is as straightforward as deployment gets: no platform accounts, no CLI tools to install, no build minutes to manage. If you can SSH into a server, you can deploy your portfolio.
GitHub Pages
A good free option if your code already lives on GitHub.
npm run build
npx gh-pages -d dist
The gh-pages package pushes your dist/ folder to a gh-pages branch. Go to your repository settings, enable Pages, set the source to the gh-pages branch, and your site is live at https://YOUR-USERNAME.github.io/obscura/.
To redeploy after changes:
npm run build && npx gh-pages -d dist
Netlify
If you'd like a CDN and instant rollbacks:
npm run build
npx netlify deploy --prod --dir=dist
The first time, the Netlify CLI will walk you through linking your project. After that, deploys are one command. Netlify gives you HTTPS, a global CDN, and deploy previews — all on the free tier.
Cloudflare Pages
Cloudflare Pages offers fast global distribution and generous free limits:
npm run build
npx wrangler pages deploy dist
Same pattern — build locally, push the output. Cloudflare handles the rest.
Custom Domain
Whichever host you choose, set your base_url in site/config/site.yaml before building:
base_url: https://www.your-domain.com
Then configure DNS with your hosting provider. Their documentation covers the specifics — it's usually a CNAME or A record.
The Routine
Once you're set up, publishing new work follows the same rhythm:
- Add photos to a gallery folder, write or update a blog post
- Run
npm run sidecarto fill in photo metadata npm run build- Deploy with your one-liner of choice
Build on your machine, push the result, done.