{"id":1666,"date":"2026-11-06T07:22:36","date_gmt":"2026-11-06T07:22:36","guid":{"rendered":"https:\/\/affordablevpsserver.com\/blog\/?p=1666"},"modified":"2026-11-06T07:22:36","modified_gmt":"2026-11-06T07:22:36","slug":"static-site-preview-deploys-cheap-vps","status":"publish","type":"post","link":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/","title":{"rendered":"Pull Request Preview Deploys for Static Sites on a Cheap VPS"},"content":{"rendered":"<p><strong>TL;DR \/ Summary:<\/strong> Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives designers and clients a URL for every open PR while production stays untouched on its own hostname.<\/p>\n<h2>The preview problem small teams actually have<\/h2>\n<p>Static site generators make production deploys easy and preview deploys awkward. Hosting platforms solve previews with magic URLs and a monthly bill that grows with seats. A five-person docs or marketing team often only needs disposable subdomains that die when the pull request merges.<\/p>\n<p>A budget VPS can host those previews if you accept a little scripting. The payoff is predictable cost and no surprise charge when a contractor opens twelve branches in a week.<\/p>\n<p>This pattern fits HTML, docs sites, and front-end builds that compile to a folder of static files. It is a poor fit for apps that need a database per preview.<\/p>\n<h2>One server, two jobs, clear walls<\/h2>\n<p>Run production on <em>www<\/em> or the bare domain. Run previews on a separate hostname such as <em>preview.example.com<\/em> with path-based or subdomain-based routing. Never deploy experimental branches into the production document root \u201ctemporarily.\u201d Temporary becomes permanent the week everyone is busy.<\/p>\n<ul>\n<li><strong>Deploy user with rsync rights<\/strong> \u2014 CI logs in as deploy, not as root<\/li>\n<li><strong>Per-PR directory<\/strong> \u2014 \/var\/www\/previews\/pr-184\/ keeps cleanup obvious<\/li>\n<li><strong>Automatic TLS<\/strong> \u2014 a wildcard cert or a per-PR cert strategy decided up front<\/li>\n<li><strong>Disk quota mindset<\/strong> \u2014 old previews must expire or the SSD fills with forgotten zips<\/li>\n<\/ul>\n<p>When you size the box, look at concurrent preview count more than peak production traffic. Browse options on <a href=\"https:\/\/affordablevpsserver.com\/\">affordable VPS server<\/a> pages for 2 GB plans if your builds unpack large asset folders; 1 GB is often enough for docs-only sites.<\/p>\n<h2>A minimal CI handshake<\/h2>\n<p>On each pull request, CI builds the static output, rsyncs it into the PR directory, and comments the URL back on the PR. On close or merge, CI deletes that directory. If CI cannot delete, a nightly cron that removes previews older than seven days is the safety net.<\/p>\n<h3>Auth for private work<\/h3>\n<p>Public previews are fine for open marketing pages. Private product docs need basic auth or an SSO gate at the reverse proxy. Putting secrecy only in an obscure URL is not access control; it is optimism.<\/p>\n<blockquote><p>If the preview URL leaks, the protection should still be a password or SSO\u2014not hope.<\/p><\/blockquote>\n<h2>nginx layout that stays readable<\/h2>\n<p>Prefer one server block for previews that maps <em>\/pr\/184\/<\/em> to the matching directory, or a subdomain scheme like <em>184.preview.example.com<\/em> if you already have wildcard DNS. Path-based routing is simpler for teams new to DNS wildcards.<\/p>\n<p>Disable directory listing. Enable gzip or brotli for text assets. Set short cache headers on previews so designers are not fighting yesterday\u2019s CSS after a push.<\/p>\n<p>Keep access logs rotated. Preview traffic is chatty during review week and will fill a disk if logrotate is forgotten.<\/p>\n<h2>Build resource limits on small CPUs<\/h2>\n<p>Static builds that run webpack-style pipelines can spike CPU. On a one-core VPS, two simultaneous PR builds will make SSH feel sticky. Limit CI concurrency to one preview build at a time or move the build step to CI runners and only upload artifacts to the VPS.<\/p>\n<p>Artifact-only deploys are usually the right default: CI builds elsewhere, the VPS only receives files and reloads nothing heavier than nginx. That keeps the cheap server honest about its job.<\/p>\n<h2>Client review habits that reduce rework<\/h2>\n<p>Paste the preview link in the same chat thread as the design notes. Ask for comments tied to the PR number. When feedback arrives as \u201cthe staging site,\u201d nobody knows which branch they meant.<\/p>\n<p>Destroy previews promptly after merge so nobody bookmarks a zombie URL and files bugs against deleted experiments.<\/p>\n<h2>DNS and certificate gotchas on first setup<\/h2>\n<p>Point the preview hostname at the VPS before you expect CI to succeed. Certificate issuance fails in confusing ways when DNS still targets an old host. If you use path-based previews on one hostname, one certificate covers every PR. If you use per-PR subdomains, arrange wildcard DNS and a wildcard certificate up front or you will spend a week issuing toys.<\/p>\n<p>Document the DNS records in the same repo as the deploy script. Future teammates should not rediscover the preview host by grepping Slack.<\/p>\n<h2>Protecting production from preview accidents<\/h2>\n<p>Separate SSH keys for preview deploys and production deploys. CI for pull requests should not hold the production key. A mistaken rsync destination is rarer when the credential literally cannot write to production paths.<\/p>\n<p>Add a dry-run mode to the deploy script that prints the target directory and exits. Require dry-run output in the first PR that introduces the pipeline. Five minutes of theater prevents a memorable outage.<\/p>\n<p>Label preview pages in the HTML title with \u201cPREVIEW\u201d and the PR number. Stakeholders sometimes bookmark freely; the label reduces angry tickets about \u201cprod looking weird\u201d when they were on a branch the whole time.<\/p>\n<h2>What success looks like after a month<\/h2>\n<p>You should see a stable monthly VPS invoice, a trash cron that keeps disk free, and PR comments that always include a fresh link. Designers stop asking for \u201ca quick upload somewhere.\u201d Production deploys stay boring. That boredom is the feature: a cheap VPS earning its keep as a preview factory, not as an accidental second production.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR \/ Summary: Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives designers and clients a URL for every open PR while production stays untouched on its own hostname. The preview problem small teams actually have Static site generators make production deploys easy [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":0,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-1666","post","type-post","status-publish","format-standard","hentry","category-vps-hosting-tutorials"],"blocksy_meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Pull Request Preview Deploys for Static Sites on a Cheap VPS - Affordable VPS Server Blog<\/title>\n<meta name=\"description\" content=\"TL;DR \/ Summary: Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pull Request Preview Deploys for Static Sites on a Cheap VPS\" \/>\n<meta property=\"og:description\" content=\"Pull Request Preview Deploys for Static Sites on a Cheap VPS\" \/>\n<meta property=\"og:url\" content=\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"Affordable VPS Server Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-06T07:22:36+00:00\" \/>\n<meta name=\"author\" content=\"Affordable-Vps-Server-Author\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Affordable-Vps-Server-Author\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/\",\"url\":\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/\",\"name\":\"Pull Request Preview Deploys for Static Sites on a Cheap VPS - Affordable VPS Server Blog\",\"isPartOf\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#website\"},\"datePublished\":\"2026-11-06T07:22:36+00:00\",\"author\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7\"},\"description\":\"TL;DR \/ Summary: Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives\",\"breadcrumb\":{\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/affordablevpsserver.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pull Request Preview Deploys for Static Sites on a Cheap VPS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#website\",\"url\":\"https:\/\/affordablevpsserver.com\/blog\/\",\"name\":\"Affordable VPS Server Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/affordablevpsserver.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7\",\"name\":\"Affordable-Vps-Server-Author\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g\",\"caption\":\"Affordable-Vps-Server-Author\"},\"sameAs\":[\"https:\/\/affordablevpsserver.com\/blog\"],\"url\":\"https:\/\/affordablevpsserver.com\/blog\/author\/affordablevpsserver\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Pull Request Preview Deploys for Static Sites on a Cheap VPS - Affordable VPS Server Blog","description":"TL;DR \/ Summary: Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/","og_locale":"en_US","og_type":"article","og_title":"Pull Request Preview Deploys for Static Sites on a Cheap VPS","og_description":"Pull Request Preview Deploys for Static Sites on a Cheap VPS","og_url":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/","og_site_name":"Affordable VPS Server Blog","article_published_time":"2026-11-06T07:22:36+00:00","author":"Affordable-Vps-Server-Author","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Affordable-Vps-Server-Author","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/","url":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/","name":"Pull Request Preview Deploys for Static Sites on a Cheap VPS - Affordable VPS Server Blog","isPartOf":{"@id":"https:\/\/affordablevpsserver.com\/blog\/#website"},"datePublished":"2026-11-06T07:22:36+00:00","author":{"@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7"},"description":"TL;DR \/ Summary: Pull-request preview sites do not require a pricey PaaS. A cheap VPS with nginx, a deploy user, and per-branch directories gives","breadcrumb":{"@id":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/affordablevpsserver.com\/blog\/static-site-preview-deploys-cheap-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/affordablevpsserver.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Pull Request Preview Deploys for Static Sites on a Cheap VPS"}]},{"@type":"WebSite","@id":"https:\/\/affordablevpsserver.com\/blog\/#website","url":"https:\/\/affordablevpsserver.com\/blog\/","name":"Affordable VPS Server Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/affordablevpsserver.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/685a02c93a3c45030f7427ec928b0df7","name":"Affordable-Vps-Server-Author","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/affordablevpsserver.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8fa20973a7dd04621d396c26ba26b5c5e6c19595583335121958527393f6f95e?s=96&d=mm&r=g","caption":"Affordable-Vps-Server-Author"},"sameAs":["https:\/\/affordablevpsserver.com\/blog"],"url":"https:\/\/affordablevpsserver.com\/blog\/author\/affordablevpsserver\/"}]}},"_links":{"self":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/comments?post=1666"}],"version-history":[{"count":1,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1666\/revisions"}],"predecessor-version":[{"id":1667,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/posts\/1666\/revisions\/1667"}],"wp:attachment":[{"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/media?parent=1666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/categories?post=1666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/affordablevpsserver.com\/blog\/wp-json\/wp\/v2\/tags?post=1666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}