Setting up PagePark on a DigitalOcean Droplet

A couple days ago I asked Dave Winer how he was able to point to a FeedLand news product, because CNAME records have to point to a hostname and can’t include a path. I wanted to point a subdomain at one of my own news products on FeedLand and couldn’t figure it out.

The answer was PagePark, a simple web server he wrote in 2014 to park his unused domains, and later expanded to include useful tools like serving redirects, content from GitHub and S3, and aliasing content from another site.

I realized that I had to set that up for myself. I have a bunch of domains I don’t use, some old sites that I should just turn into a static archive and stick somewhere, and domains that I’d like to point to other services, such as FeedLand news products.

That night I decided to set up PagePark on a DigitalOcean droplet. I thought I’d write out the steps in case I or anyone else want to set it up on DigitalOcean in the future.

Assuming you have a DigitalOcean account and are logged in:

  1. Set up a NodeJS droplet. I used DO’s NodeJS droplet template, which as of the time of this writing uses Node 18.12.1 and Ubuntu 20.04. I don’t expect to need a high powered server due to the low traffic to these domains, so I started with a $4/mo basic shared 512MB CPU with 10GB SSD and 500GB transfer. Basically the lowest tier.
  2. After the server came online, I SSH’d in.
  3. At the root, I cloned the PagePark repo: git clone
  4. Go into the pagePark directory: cd pagePark
  5. Install the app and dependencies: npm install
  6. Start the app: sudo -u root pm2 start pagepark.js
  7. Edit the nginx config to serve the app to the world. The default hello.js app that comes with the droplet is set to serve from port 3000. PagePark is set to serve from 1339, so we need to edit the location / block in nginx:
    • nano /etc/nginx/sites-available/default
    • Look for the block that looks like this:
location / {
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://localhost:3000;
  1. That second to last line, proxy_pass http://localhost:3000; is what we want to edit. Simple change 3000 to 1339. The line should now read: proxy_pass http://localhost:1339;
  2. Exit and save: ^X to exit, y to confirm save, hit enter to save it to the same filename
  3. Restart nginx: sudo systemctl restart nginx
  4. Delete the default app included with the droplet: sudo -u root pm2 delete hello
  5. Schedule the PagePark app to run at launch and stop the default hello app from running at launch: sudo -u root pm2 save
  6. Point a domain at the droplet to use for easy CNAME pointing for other domains. I used and pointed it via A record to the IP address listed in the DO dashboard under the project I added the droplet to > Resources > Domains.
  7. Back on the server, I went to ~/pagePark/domains and added a folder for, then added an index.html with a simple message to test my setup. I also moved the ~/pagePark/prefs/error.html and ~/pagePark/templates/* to the folder to make the accessible, then edited them and changed the path for the ~/pagePark/config.json keys for the following items to serve them from this server rather than Dave’s:
    • urlDefaultMarkdownTemplate
    • urlDefaultOpmlTemplate
    • urlDefaultErrorPage

That was it! started working, then I set up a couple more domains by adding new folders to the domains folder (follow the docs) and adding a cname record for the domains to

  • shows my Peekskill news product, running on FeedLand. It pulls in feeds from local news sources and the City of Peekskill.
  • shows the contents of a simple markdown file
  • – an interview website I set up on WordPress where I interviewed generative artists in 2021, then abandoned. I want the interviews to stay live, but I’m probably not going to do them anymore, so I generated a static site and put the HTML files here instead of keeping the WP site live. I’m probably going to do this with a few more old WP sites.
  • More to come soon!

Thanks for open sourcing PagePark, Dave! I’m already finding it useful.

Likes, Bookmarks, and Reposts

  • Chris Hardie
  • Matt Jordan
  • Andeshand
  • mrg
  • rhempel
  • Chris Boese
  • Craig Lee
  • rhempel
  • Chris Boese
  • Dave Winer ☕️
  • Mike Rodriquez
  • frostbyte
  • Jan

7 responses to “Setting up PagePark on a DigitalOcean Droplet”

  1. […] Setting up PagePark on a DigitalOcean Droplet […]

  2. Marcos Huerta Avatar

    @cagrimmett Nice! I think you could do all of this with just nginx, but reading over the docs I think advantage of PagePark is a bit easier configuration for subdomains (once it’s up and running.) With nginx, each subdomain would need its own server block in the ngnix config.

    With nginx, I have 4 domains running on one Digital Ocean droplet.

  3. Cameron Bales Avatar

    @cagrimmett @davew seems very confused.

  4. Chuck Grimmett Avatar

    @tarlbot How so? Is it broken?

  5. Cameron Bales Avatar

    @cagrimmett Can’t connect to server. Earlier I saw a progress bar very quickly starting many many times. At first I assumed Dave had crushed your small server, but the other links work.

  6. Chuck Grimmett Avatar

    @tarlbot Thanks for the heads up. It is resolving here, but I did set up the DNS differently for that one than the other two, so I’ll update it to match. Hopefully will be working in ~15 mins.

  7. Jan Avatar

    I have quite a few (sub)domains point to one and the same web server, and even one and the same WordPress (Multisite, and multidomain) install. Bit of DirectAdmin and .htaccess wizardry takes it from there.

Leave a Reply

%d bloggers like this: