Back to Blog
Tutorial8 min read2026-06-30

How to Deploy a Jekyll Static Site

Deploy a Jekyll static site to production: the build process and environment, configuring baseurl and url, managing Ruby dependencies with Bundler, custom domains with SSL, and continuous deploys from Git.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Jekyll is the original Ruby-based static-site generator and still a great choice for blogs, project pages, and documentation, especially if you like writing in Markdown with Liquid templating. It compiles your content into a static _site/ directory that you serve from a CDN. Deploying it well is mostly about getting the build environment, Bundler dependencies, and URL configuration right. This guide covers it.

How Jekyll builds

Jekyll transforms Markdown, Liquid templates, and assets into static HTML:

bundle exec jekyll build

The output lands in _site/, a complete static site with no server runtime. You serve those files from a static host or CDN. Setting the production environment matters: some Jekyll features and plugins behave differently in production, so build with:

JEKYLL_ENV=production bundle exec jekyll build

With JEKYLL_ENV=production, things like analytics snippets and certain optimizations switch on. Always build for production when deploying, otherwise you might ship a dev-mode site.

url and baseurl

Jekyll's _config.yml has two settings that control link generation:

url: "https://example.com"   # the production origin
baseurl: ""                   # "" for root, "/blog" for a subpath

The classic Jekyll deployment bug is a wrong baseurl. If your site lives at the root of a domain, baseurl is an empty string. If it lives under a subpath (like a project page at example.com/myproject), set baseurl to /myproject. Use the relative_url and absolute_url Liquid filters in your templates so links respect these settings, hardcoded / links break when baseurl is non-empty.

Bundler and reproducible builds

Jekyll is Ruby, so dependencies are managed with Bundler. Commit both your Gemfile and Gemfile.lock so the deploy installs the exact gem versions you tested with:

source "https://rubygems.org"
gem "jekyll", "~> 4.3"
group :jekyll_plugins do
  gem "jekyll-feed"
  gem "jekyll-seo-tag"
  gem "jekyll-sitemap"
end

The Gemfile.lock is what guarantees reproducibility, without it, a gem minor-version bump can change your output or break the build. The deploy runs bundle install then bundle exec jekyll build.

Deploying on PandaStack

Jekyll output is static, so it deploys as a static site, building in a fast microVM and serving from the edge.

  1. 1Push your Jekyll project (with Gemfile and Gemfile.lock) to GitHub.
  2. 2Create a static site in the dashboard and connect the repo.
  3. 3PandaStack auto-detects the framework. Set the build command to JEKYLL_ENV=production bundle exec jekyll build and the publish directory to _site. Bundler dependencies install from the Gemfile.
  4. 4The build runs in a pandastack.ai microVM, isolated and fast, and the static output publishes to the edge with automatic SSL.
  5. 5Watch the live build logs to confirm the build completed and pages generated.
SettingValue
Build commandJEKYLL_ENV=production bundle exec jekyll build
Publish directory_site
DependenciesGemfile + Gemfile.lock
baseurl"" for root domain

Continuous deploys

Once connected, every push to your default branch rebuilds and redeploys. For a blog or docs site, that means writing a post in Markdown, committing it, and seeing it live minutes later, no manual build-and-upload dance. Deploy history records each build so you can roll back if something goes wrong.

Custom domains and SSL

Add your domain or subdomain in the dashboard and point DNS (a CNAME for subdomains, or the appropriate record for an apex domain) at the provided target. SSL is issued and auto-renewed. Make sure url in _config.yml matches the production domain so jekyll-seo-tag and jekyll-sitemap generate correct canonical URLs and a valid sitemap.

Performance and the free tier

A static Jekyll site served from the edge has no cold starts and no server to scale, performance is excellent out of the box. To keep it lean:

  • Optimize and compress images before committing.
  • Use jekyll-seo-tag and jekyll-sitemap for clean SEO output.
  • Avoid plugins you don't need; each adds build time.

The free tier includes static sites with 100GB bandwidth and 300 build minutes per month, plenty for a personal blog or project site. Static content has no scale-to-zero concern. If you publish frequently or run several sites, the Pro tier offers unlimited static sites and more build minutes.

Common pitfalls

  • Wrong baseurl, broken links and missing assets, especially for project sites under a subpath.
  • Missing Gemfile.lock, non-reproducible builds.
  • Forgetting JEKYLL_ENV=production, dev-mode output shipped to production.
  • Wrong publish directory, it's _site, not dist or public.

References

  • Jekyll documentation: https://jekyllrb.com/docs/
  • Jekyll deployment methods: https://jekyllrb.com/docs/deployment/
  • Jekyll configuration (url/baseurl): https://jekyllrb.com/docs/configuration/options/
  • Bundler: https://bundler.io/
  • jekyll-seo-tag: https://github.com/jekyll/jekyll-seo-tag

Jekyll is a dependable static generator, get the production environment, Bundler lockfile, and baseurl right and deploys are smooth and fast. Publish your Jekyll site with automatic SSL and Git-based continuous deploys on PandaStack's free tier: https://dashboard.pandastack.io

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also