Jekyll behind a NGINX proxy

Hello all

I would like to run Jekyll on a server in a DMZ, which should then be accessed with a NGINX proxy, via my router using DynDNS service.

Unfortunately, for example, the RSS feed is displayed to me with the initialised host. Here

Since the documentation for Jekyll is not very productive, I unfortunately have to ask the question here.

Is there a way to adjust this within the _config.yml (to dynamic IPs) or do I really have to change the code so that this problem no longer occurs?

Thank you

is that because you are running jekyll serve?

the built in jekyll webrick web server is not really a production server, you would be better off with something else.

Can you be more specific with where the problem is happening? I kinda think it would work.

What you want to do is run jekyll build as per the other answer.

But specifically build in production mode.

JEKYLL_ENV=production jekyll build --trace 

Trace helps for errors being verbose.

And you need to configure your URL so that when your own content, theme or plugins use a domain for the absolute URL, the domain is set.

In config:


Note protocol is included and no trailing slash

Its disappointing that URL is not covered in the docs

If you have a subpath then set that.

baseurl: /jekyll-blog-demo

My config

Also using Nginx and a build step locally or on a remote sidesteps all the wonderful technology available out there.

If you use GitHub Pages or Netlify, you can deploy your site for free to a standard or custom domain that your own, without having to touch Nginx config. And you get deploy pipelines running in the cloud so you can deploy your website changes while editing on your phone or whatever and multiple people on your team can easily deploy to the same site. Or work on a CMS.


I followed the installation instructions.

apt-get install automake make gcc g++ ruby-full build-essential ruby-dev

gem install bundler jekyll
mkdir [ pfad ]
cd [ pfad ]

bundle init

bundle config set path 'vendor/bundle'

bundle add jekyll

bundle exec jekyll new --force --skip-bundle . 
bundle install

And yes, I start the server with

bundle exec jekyll serve -w

Since the server then automatically only allows localhost, I naturally had to adjust the configuration accordingly.


port: 4000

I have also adapted the URL.

baseurl: "" # I do not use a subpath
url: ""

But also internally, by calling the private IP into the DMZ (, the data does not change. The RSS feed is still given to me with the address I don’t even need a proxy server like NGINX for this. I even tried to work with an internal domain, here jekyll.home, the result remained the same.

I don’t understand. Sorry.

What should I try, where and when?

How now? Jekyll is not at all suitable for delivering static websites from a DMZ via a NGINX proxy?

What you set as host is used for the dev server.

For production ie not on your laptop, you should use jekyll build.

JEKYLL_ENV=production jekyll build --trace

And copy the content of _site to wherever you want and put Nginx or whatever on top of that.

Run the build command locally or on your remote server on AWS or whatever. It doesn’t change the result.

Jekyll is not optimized for speed. It is also going to cost in money too for a Jekyll server running vs Nginx and static files.

I know know about the DMZ set up you have but Jekyll is a static site generator that makes static HTML files. Having a Jekyll server is only intended for development

Can you explain what DMZ is and why Jekyll static content is not suitable for that? I don’t understand from the last comment how it has an impact.

If you are simply talking about a private IP that you can access in your home or company or whatever.

Then copy contents of _site to /var/www or somewhere else on your laptop. You don’t need Jekyll to serve after the build is done.

And set up Nginx on your laptop to serve that www directory.

Or repeat on a machine in your network or the cloud or whatever, it’s the same principle.

that should be ok? I just set up nginx for an app using PM2, pm2 starts it locally on localhost:3000 and in nginx I have it relay the traffic to that, works great. there are actually 2 things running on localhost at different ports and it is fine.

But like MC says, I would never do this for a jekyll site when it is easier to host on netlify, aws amplify or any other plain web server. I use amplify and have it synced to my repos on bitbucket, it builds and deploys on any commit to the repo. Pretty easy.

DMZ = Demilitarised Zone, i.e. the network segment that forwards access from the Internet directly from the router.

I only have one IP address available at a time, but host several websites, which are then made available via NGINX proxy.

Thank you, I have understood now

Having to copy data back and forth is not an option for me. I was looking for something simple. Jekyll met the requirements in terms of creating and distributing data, but under these circumstances the system is simply not to be used. But that’s not how you build a system, it’s just a bad thing.

AWS, Bitbucket and co. are not an option for me. My data and I host it where I have it under control.

So you have one public IP and you use Nginx to map that to IPs on your internal network?

I don’t think you have to copy data back and forth. You need to run jekyll build when your markdown changed and then that will copy to _site or some configured shared directory.

Then you have Nginx running on that machine to serve that directory on say (if I was making a home network). Which replaces Jekyll serve on

and the Nginx on public side translates your public IP of 172… to (or :4000).

And to the earlier point, your Jekyll host must be or some other known IP like 172… or, so that Jekyll server accepts requests from other machines.

The suggestion for build command is meant to solve that issue (no need for and also performance (which might not matter for you).

All right. I have found my “mistake”.

The documentation may be detailed, but it is anything but suitable for newcomers to find their way around. But it is beautifully colourful.

Therefore, for all those who want to use jekyll on Debian 10 Buster and all that behind a NGINX proxy, this installation works.

apt-get install automake make gcc g++ ruby-full build-essential ruby-dev sudo

gem install bundler jekyll

Further then without root rights

mkdir [ path ]
cd [ path ]

bundle init

bundle config set path 'vendor/bundle'

bundle add jekyll

bundle exec jekyll new --force --skip-bundle . # Don't forget the dot!
bundle install	# installs missing gems

Starting the system for testing

JEKYLL_ENV=production bundle exec jekyll serve

My (part) NGINX conf

   location / {

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;

In case someone wants to have the whole thing a bit easier and wants to use jekyll-admin:

Securing the folder with a password would then work like this:

part of NGINX.conf for your Website

     location ^~ /admin {
         auth_basic "Administration";
         auth_basic_user_file /srv/htpasswd;


         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header Host $http_host;

Network diagram

<Internet> - <Router with NGINX proxy> - <Jekyll server on internal network>

Thank you. That takes care of the “problem”.

Many greetings and stay healthy.

1 Like

Oh yeah if you have Jekyll admin which you have not mentioned before, then you must leave Jekyll serve running.

But beware that there is no user sign in so anyone who can view /admin on your site can also edit and mess with your content. So your site might be public but /admin should be private or have some http basic auth at least on it

I have several ways to fill the system with content. An internal Gitlab instance, the possibility of using the Jekyll admin or quite puristically via file upload with scp.

Have a look here :smiley: