Hi there! š
My name is Meir Gabay (a.k.a. unfor19) and Iām a DevOps Engineer at LSports. I am passionate about studying and teaching.
This website serves as a central point to all of my blog posts and videos; the main topics are:
This section is dedicated to the outstanding programmers who dedicated many hours to developing awesome projects in their spare time. Also, itās an excellent opportunity to share the technology stack that Iām using to develop, build and distribute this website.
Previously, I hosted a WordPress website on AWS Lightstail. The setup was relatively easy, and using WordPress was ok for me, up to a point where I realized that itās pointless to run a server to host my blog.
I didnāt want to:
You got the point; I wanted zero concerns, so I shifted from WordPress (web-server) to Jekyll (static website).
content="..."
. The content header, among other headers, is generated automatically for each page according to its contentsIāve created a custom theme to customize this website as much as I please. Having said that, Iām using many frameworks, so here they are:
bootstrap-min.css
from 160KB to 16KB. Itās like tree-shaking for unused CSS styles.Before we go any further, it might look like a commercial to Cloudflare; I donāt care, Iām in love.
Iām using Cloudflare for:
git commit
and git push
, thatās it.Custom Response Headers - To increase the security, Iāve added custom response headers with Cloudflare Workers; Check this siteās score in Mozilla Observatory, previously it was F and D, now itās B. It was very easy to implement and Iām deploying the workers with wrangler during the build stage in Cloudflare Pages. Hereās my Makefile
, I simply execute make cloudflare-ci
in the build stage, and the website is deployed followed by Cloudflare Workers deployment.
build-cloudflare: ## Build application in CloudFlare
pwd
ls -lh
bundle exec jekyll build
ls -lh
publish-wrangler: ## Publish worker to CloudFlare
@if [ "${CF_API_TOKEN}" != "" ]; then\
npm i @cloudflare/wrangler -g;\
cd worker-custom-headers && wrangler publish;\
else\
echo "CF_API_TOKEN empty, skipped wrangler";\
fi
cloudflare-ci: build-cloudflare publish-wrangler
And, not surprisingly, Iām using GitHub to host my source code.
One day, Iāll create a public open-source project that will include all the best practices that Iāve used to build and develop this website. But, until that day comes, Iāll share the technology stack that Iām using to make my life easier during the development process.
Yup, that is it š
A Dockerfile for local development of a Jekyll based website
ARG JEKYLL_VERSION="4.2.2"
### ----------------------------------------------------------------------
### Base Stage - Jekyll dependencies and app source code in /srv/jekyll
### ----------------------------------------------------------------------
FROM jekyll/jekyll:${JEKYLL_VERSION} as base
USER jekyll
RUN echo "gem: --no-document --no-suggestions --show-install-dir" > ~/.gemrc
ENV BUNDLE_PATH="~/.gem"
# Copy lock-files
WORKDIR /srv/jekyll/jekyll-theme-meirg
COPY jekyll-theme-meirg/Gemfile* jekyll-theme-meirg/jekyll-theme-meirg.gemspec ./
WORKDIR /srv/jekyll
COPY Gemfile* ./
USER root
RUN chown jekyll:jekyll Gemfile.lock
USER jekyll
# Install dependencies
RUN \
bundle config set --local without local_theme && \
bundle install
# Copy theme
WORKDIR /srv/jekyll/jekyll-theme-meirg
COPY jekyll-theme-meirg .
# Install theme
WORKDIR /srv/jekyll
RUN \
bundle config set --local without "" && \
bundle install
# Copy source code
COPY . .
ENTRYPOINT [ "bash" ]
### --------------------------------------------------------------------
### ----------------------------------------------------------------------
### Debug Stage - Debug the container
### ----------------------------------------------------------------------
FROM base as debug
WORKDIR /code/
# Skip copy since we're mounting the website to /code/
# docker run --rm -it -v "${PWD}/meirg.co.il":/code/ -p 4000:4000 -p 35729:35729 meirg-website:debug
EXPOSE 4000
EXPOSE 35729
ENTRYPOINT [ "bash" ]
### ----------------------------------------------------------------------
### ----------------------------------------------------------------------
### Serve Stage - Hot reload the application on file change
### ----------------------------------------------------------------------
FROM base as serve
WORKDIR /code/
# Skip copy since we're mounting the website to /code/
# docker run --rm -it -v "${PWD}/meirg.co.il":/code/ -p 4000:4000 -p 35729:35729 meirg-website:serve
EXPOSE 4000
EXPOSE 35729
ENV GIT_DISCOVERY_ACROSS_FILESYSTEM=1
ENTRYPOINT [ "bundle" ]
CMD ["exec", "jekyll", "serve", "--livereload", "--host", "0.0.0.0"]
### ----------------------------------------------------------------------
### ----------------------------------------------------------------------
### Build Stage - Generate a static website in "_site"
### ----------------------------------------------------------------------
FROM base as build
WORKDIR /src/jekyll
ENTRYPOINT [ "bundle" ]
CMD ["exec", "jekyll", "build" ]
### ----------------------------------------------------------------------
This is the Makefile
in my root dir
.EXPORT_ALL_VARIABLES:
ARTIFACT_PATH=meirg.co.il/_site
help: ## Available make commands
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's~:~~' | sed -e 's~##~~'
usage: help
build: ## Build Docker image and compile
docker build -f Dockerfile --target build -t meirg-website:build meirg.co.il && \
docker run --rm -it -v "${PWD}/meirg.co.il":/code/ --workdir=/code/ meirg-website:build
@du -sh "${ARTIFACT_PATH}"
build-serve: ## Build Docker image for serving a hot-reload app
docker build -f Dockerfile --target serve -t meirg-website:serve meirg.co.il
build-run: build-serve
run: ## Run hot-reload app
docker run --rm -it -v "${PWD}/meirg.co.il":/code/ -p 4000:4000 -p 35729:35729 meirg-website:serve
serve: run ## Run hot-reload app
This is the Makefile
in meirg.co.il
directory
.EXPORT_ALL_VARIABLES:
BOOTSTRAP_MIN_CSS_PATH="_site/assets/styles/bootstrap/bootstrap-5.1.3.min.css"
purge-css:
du -sh ${BOOTSTRAP_MIN_CSS_PATH}
purgecss --content _site/index.html \
_site/about/about.html \
_site/tags/index.html \
_site/page/2/index.html \
_site/tags/aws/index.html \
_site/2021/12/02/how-to-develop-a-progressive-web-application-on-an-android-device/index.html \
_site/404.html \
--css ${BOOTSTRAP_MIN_CSS_PATH} \
--safelist table table-responsive shadow shadow-sm bg-light bg-dark text-primary text-light mb-2 p-3 m-2 me-1 me-2 mt-1 active page-item page-link pagination card \
--output ${BOOTSTRAP_MIN_CSS_PATH}
du -sh ${BOOTSTRAP_MIN_CSS_PATH}
bundle-jekyll:
pwd
ls -lh
bundle exec jekyll build
ls -lh
# Assuming we're inside meirg.co.il
build: bundle-jekyll purge-css
cloudflare-deps:
npm i purgecss -g
build-cloudflare: cloudflare-deps bundle-jekyll purge-css ## Build application in CloudFlare
publish-wrangler: ## Publish worker to CloudFlare
@if [ "${CF_API_TOKEN}" != "" ]; then\
npm i @cloudflare/wrangler -g;\
cd worker-custom-headers && wrangler publish;\
else\
echo "CF_API_TOKEN empty, skipped wrangler";\
fi
cloudflare-ci: build-cloudflare publish-wrangler
Itās funny how I squeezed a whole blog post on āhow to create a Jekyll-based websiteā in my āabout pageā.