Generally there are 2 ways to deploy Jekyll static site to Heroku.
- Deploy as rails app using web server gem such as
puma
,passenger
,thin
, ‘etc’. - Deploy as Docker image running
nginx
service.
In this post, I chose 2nd approach since I like to use Docker image.
Prepare Dockerfile
We will serve this Jekyll site via nginx service. In order to map Heroku portnumber to our nginx service, we will need to use below default.conf
template.
server {
# Placeholder for Heroku port
listen $PORT;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
Dockerfile.
FROM nginx:alpine
# copy nginx `default.conf`
COPY nginx/default.conf /etc/nginx/conf.d/
# copy Jekyll generated files
COPY _site /usr/share/nginx/html/
# replace $PORT placeholder with HEROKU given port in default.conf and run nginx service
CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'
You can named this file as Dockerfile
or have a suffix to indiciate theHeroku process. For instance, if you want to run this application as web
process in Heroku, you could name it as Dockerfile.web
. This works well ifyou have multiple Dockerfile
s with different process such as web
, worker
, orclock
. Later on, when you run heroku container:push --recursive
, it willbuild all the Dockerfile
s with the correct suffix and push them to Heroku dockerregistry.
Configure Github Action
Even without Github Action, all I need is Heroku CLI to deploy this Dockerimage using below commands.
> bundle exec jekyll build
> heroku container:login
> heroku container:push -a <HEROKU_APP_NAME> --resursive
> heroku container:release -a <HEROKU_APP_NAME> web
Basically, in Github Actions, we are running above commands. Below is the fullGithub Action workflow yaml.
name: Push Container to Heroku
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Retrieve Gem Bundles Cache
uses: actions/cache@v2
with:
path: _bundle
key: $-gems-$
restore-keys: |
$-gems-
- name: Generate site
run: |
mkdir -p _bundle/cache
chmod a+rwx -R .
docker-compose run -e JEKYLL_ENV=production jekyll bundle install
docker-compose run -e JEKYLL_ENV=production jekyll bundle exec jekyll build --trace
- name: Login to Heroku Container registry
env:
HEROKU_API_KEY: $
run: heroku container:login
- name: Build and push
env:
HEROKU_API_KEY: $
run: heroku container:push -a $ --recursive
- name: Release
env:
HEROKU_API_KEY: $
run: heroku container:release -a $ web
With a push to master
branch, it will trigger a build which will
- Checkout code from
master
branch. - Generate Jekyll static files.
- Build and push the Docker image to heroku registry.
- Deploy the Docker image to Heroku with
web
process.
Conclusion
This approach not only work for static site, but also for other typesof application such as Rails application. Having a Dockerfile will give youfull control on what other linux packages you wish to install within theapplication server instance such as ImageMagick. It will also give youconsistent environment between running your application on your local machineand on Heroku.
Top comments (0)