{"categories":["Meta"],"contentHtml":"<p>Making a website in the modern era is not easy to do for free. I did it using Zola, Github Pages, and Github Actions.\nI've always wanted to have a personal website where I can upload what I do on my local computer to access remotely and have the world see. But it always seemed like too much of a hassle to set up and I didn't have the capital to invest in a website that I didn't need. However, when I started going back to university in-person this year, I found it much easier to take notes by typing them instead of using OneNote as I was accustomed, as the amount of code I had to write was drastically increased. Needing a way to access them remotely with a nice view, I thought a blog would be a good way to do that in addition to all the other things I had always wanted a website for. So, I embarked on a journey to create a website.</p>\n<h2>Github Pages</h2>\n<p>A website is no use unless we have somewhere to put it. <a href=\"https://pages.github.com/\" rel=\"noopener noreferrer\">Github Pages</a> is a service offered by Github since 2008 that allows you to host your own website from a Github repository. You get one free website per Github account, which is called [username].github.io. All we have to do to enable it is create a repository named [username].github.io and enable Github Pages in the settings!</p>\n<pre><code># should be above 2.28 to enable default branch name change\ngit --version\n\nmkdir [username].github.io\ncd [username].github.io\n\n# personal git config\ngit config --global user.name \"NAME\"\ngit config --global user.email \"EMAIL\"\ngit config --global init.defaultBranch \"main\"\ngit init\n\ngh repo create [username].github.io --public --source=. --remote-upstream\n</code></pre>\n<p>If you're using <a href=\"https://code.visualstudio.com/\" rel=\"noopener noreferrer\">Visual Studio Code</a> as your editor, there's a nicer way to do this than through the command line. After installing <a href=\"https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github\" rel=\"noopener noreferrer\">the Github extension</a>, go to the Source Control button on the sidebar. There should be a button labeled \"Publish to Github\" which allows you to interactively initialize a Git repository in the current folder and publish it to Github.</p>\n<h2>Github Actions</h2>\n<p>We might have created our Github page, but we need a way to get all of the code from our repository to the website. This is called <strong>deployment</strong>. Luckily, we have a way to automatically deploy our website through <strong>Github Actions</strong>. <a href=\"https://github.com/features/actions\" rel=\"noopener noreferrer\">Github Actions</a> is another service offered by Github since 2019 that gives you free CI in public repositories. Although the free tier is <a href=\"https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes\" rel=\"noopener noreferrer\">fairly limited</a> at 500 MB and 2000 minutes per month, it should be more than enough for a static blog that is not deployed very often.</p>\n<p>There is an action automatically created for our Github page called <code>pages-build-deployment</code> which, as the name implies, builds and deploys the page you've created on push. The way that I organized my code, which is probably the simplest option, is that I hosted my code at the <code>main</code> branch and had a <code>gh-pages</code> branch that hosted the actual website which was built from the <code>main</code> branch. If you want to do the same, go to <code>Settings</code> -&gt; <code>Pages</code> and make sure that the build target is the <code>gh-pages</code> branch at the root.</p>\n<p>For now, this won't do anything because we don't have a <code>gh-pages</code> branch or anything in our <code>main</code> branch. So how do we <em>actually</em> make our website?</p>\n<h2>Zola</h2>\n<p><a href=\"https://www.getzola.org/\" rel=\"noopener noreferrer\">Zola</a> is a static site generator written in <a href=\"https://www.rust-lang.org/\" rel=\"noopener noreferrer\">Rust</a>, and is one of the fastest out there. I decided to choose it for my website. If you'd prefer a different generator, this is where this guide diverges for you. There are plenty of tutorials for Hugo websites or others, but I have found a lack of Zola guides so I decided to create this.</p>\n<p>To start, <a href=\"https://www.getzola.org/documentation/getting-started/installation/\" rel=\"noopener noreferrer\">install Zola on your system</a>. The documentation on the website is pretty stellar so I would recommend reading that to get a quick understanding on how to use Zola. I will explain the parts that I personally found difficult or unclear.</p>\n<pre><code>zola init\nzola build # unnecessary as serve will also automatically build it\nzola serve\n</code></pre>\n<p>Now you can see your new website at <code>127.0.0.1:1111</code>!</p>\n<h2>Zola Deployment</h2>\n<p>Although we can build your website very simply on our local machine, it would be preferable to automatically build the website when we publish content so we don't have to mess around with all of that. The <a href=\"https://www.getzola.org/documentation/deployment/github-pages/\" rel=\"noopener noreferrer\">Zola-approved way</a> to do this is by using <a href=\"https://github.com/shalzz/zola-deploy-action\" rel=\"noopener noreferrer\">zola-deploy-action</a>. All of you have to do is click the <code>New Workflow</code> button on the <code>Actions</code> page from your Github repository and follow the link to <code>set up a workflow yourself</code>, then copy-paste this into it:</p>\n<pre><code># On every push this script is executed\non: push\nname: Build and deploy GH Pages\njobs:\n  build:\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs/heads/main'\n    steps:\n      - name: checkout\n        uses: actions/checkout@v2\n      - name: build_and_deploy\n        uses: shalzz/zola-deploy-action@v0.14.1\n        env:\n          # Target branch\n          PAGES_BRANCH: gh-pages\n          # Provide personal access token\n          TOKEN: ${{ secrets.TOKEN }}\n</code></pre>\n<p>However, I wanted more configuration and control over my action. Github Actions operates using Jekyll by default, so unless you add a <code>.nojekyll</code> file to the build branch it will run unnecessary steps to build a Jekyll theme. In order to reduce complexity, I decided to make a similar action that adds that command. If you're comfortable with the workflow as provided, then skip the next section.</p>\n<h2>Creating a Github Action</h2>\n<p>An action of the type we want here consists of three files: <code>action.yaml</code>, <code>Dockerfile</code>, and <code>entrypoint.sh</code>. Let's break these down.</p>\n<ul>\n<li><code>action.yaml</code>: the configuration file that tells Github Actions what to do</li>\n<li><code>Dockerfile</code>: the configuration file for the Docker container that Github Actions will set up</li>\n<li><code>entrypoint.sh</code>: the shell script that will execute the commands we want</li>\n</ul>\n<p><code>action.yaml</code> is simple. It should follow this general format:</p>\n<pre><code># action.yaml\nname: 'ACTION_NAME'\ndescription: 'DESC'\nauthor: 'NAME'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n</code></pre>\n<p>The Dockerfile is more complex and has many more options. I kept mine simple to what is needed, you may have your own preference for Docker images.</p>\n<pre><code># any Docker image is fine, I prefer debian\nfrom debian:stable-slim\nMAINTAINER NAME &lt;EMAIL&gt;\n\n# for github actions\nLABEL \"com.github.actions.name\"=\"ACTION_NAME\"\nLABEL \"com.github.actions.description\"=\"DESC\"\n\n# locale, I am in the U.S. so I use en_US\nENV LC_ALL C.UTF-8\nENV LANG en_US.UTF-8\nENV LANGUAGE en_US.UTF-8\n\n# standard apt-get + wget and git for getting and building\nRUN apt-get update &amp;&amp; apt-get install -y wget git\n\n# get zola on the docker image\nRUN wget -q -O - \\\n\"https://github.com/getzola/zola/releases/download/v0.15.3/zola-v0.15.3-x86_64-unknown-linux-gnu.tar.gz\" \\\n| tar xzf - -C /usr/local/bin\n\nCOPY entrypoint.sh /entrypoint.sh\n\n# give the entrypoint executable permissions\nRUN chmod +x entrypoint.sh\nENTRYPOINT [\"/entrypoint.sh\"]\n</code></pre>\n<p><code>entrypoint.sh</code> is where all the magic happens. Fundamentally, all that it does is call <code>zola build</code> on the <code>main</code> branch, which builds your website inside the <code>public</code> directory (you can configure this if you so wish). It then commits those website files to the <code>gh-pages</code> branch.</p>\n<p>We need one more thing before we can create <code>entrypoint.sh</code>; a token. We need to authorize our action to be able to push to <code>gh-pages</code>. You can create a token by going to <a href=\"https://github.com/settings/tokens\" rel=\"noopener noreferrer\">this page</a> and creating a new token with at least <code>repo</code> rights. You can add the token to your repository by going to <code>Settings</code> -&gt; <code>Secrets</code> -&gt; <code>Actions</code> and creating a new repository secret called <code>TOKEN</code> (or any other name you like).</p>\n<p>With that token, this is the basic necessities for <code>entrypoint.sh</code>:</p>\n<pre><code>#!/bin/bash\nset -e\nset -o pipefail\n\nmain() {\n    git config --global url.\"https://\".insteadOf git://\n    git config --global url.\"$GITHUB_SERVER_URL/\".insteadOf \"git@github.com\":\n\n    # update git submodules (important if you have themes)\n    git submodule update --init --recursive\n\n    zola build\n\n    cd public\n\n    # if you want to add any commands do it here e.g. `touch .nojekyll`\n\n    git init\n    git config user.name \"GitHub Actions\"\n    git config user.email \"github-actions-bot@users.noreply.github.com\"\n    git add .\n\n    git commit -m \"Deploy ${GITHUB_REPOSITORY} to ${GITHUB_REPOSITORY}:gh-pages\"\n    git push --force \"https://${GITHUB_ACTOR}:${TOKEN}@github.com/${GITHUB_REPOSITORY}.git\" master:gh-pages\n}\n\nmain \"$@\"\n</code></pre>\n<p>With all of these settings, this is how your workflow should look:</p>\n<pre><code># .github/workflows/main.yml\non: push\nname: Build and deploy GH Pages\njobs:\n  build:\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs/heads/main'\n    steps:\n      - name: checkout\n        uses: actions/checkout@v2\n      - name: build-and-deploy\n        uses: ./ # wherever your action is in relation to the root of the repo\n        env:\n          TOKEN: ${{secrets.TOKEN}}\n</code></pre>\n<h2>Themes</h2>\n<p>Zola requires a <a href=\"https://tera.netlify.app/\" rel=\"noopener noreferrer\">Tera</a> template to render your site for the base site <code>index.html</code> as well as <code>page.html</code> for page-specific settings. You can also use <a href=\"https://sass-lang.com/\" rel=\"noopener noreferrer\">Sass</a> stylesheets if you enable it in your <code>config.toml</code>. <strong>Themes</strong> are a convenient way to have those built for you so you can get a website looking nice without excessive fiddling. I decided to use the <a href=\"https://github.com/getzola/after-dark\" rel=\"noopener noreferrer\">after-dark</a> theme which is based on the Hugo theme of the same name. Since I wanted to make my own modifications to it, <a href=\"https://github.com/sharifhsn/after-dark\" rel=\"noopener noreferrer\">I forked it</a> and added the changes I wanted. The easiest way to add a theme for Github pages is to use submodules:</p>\n<pre><code>git submodule add https://github.com/getzola/after-dark.git themes/after-dark\n</code></pre>\n<p>The deploy action will take care of updating the submodule as necessary. Just add the theme to your <code>config.toml</code> file and voila!</p>\n<p>Although I like the <code>after-dark</code> theme, I might change to a different theme or make my own in the future to accommodate my goals for this website. If that happens, I'll detail that process in another post.</p>\n<h2>$\\KaTeX$</h2>\n<p>Most of the lecture notes I write incorporate <a href=\"https://katex.org/\" rel=\"noopener noreferrer\">$\\KaTeX$</a> in some way. I find it an expressive way to write formulas and math expressions when reviewing for tests. <code>after-dark</code> does not provide $\\KaTeX$ support by default, which is part of the reason I forked it.</p>\n<p>My preferred option for $\\KaTeX$ rendering would be server-side, as I don't plan on pushing very often (perhaps once per day) and Zola compilation is extremely quick. However, after doing some research into <a href=\"https://github.com/getzola/zola/pull/1073\" rel=\"noopener noreferrer\">previous attempts</a>, I decided it wasn't feasible for now. Perhaps in the future I'll take a stab at implementing it myself, but for now I'll settle for client-side.</p>\n<p><a href=\"https://katex.org/docs/browser.html\" rel=\"noopener noreferrer\">The $\\KaTeX$ docs</a> give a pretty good description on how to incorporate it into your website. In Tera, all you have to do is enclose those stylesheets/scripts into CSS/JS blocks, respectively. My inspiration came from <a href=\"https://github.com/getzola/after-dark/pull/22\" rel=\"noopener noreferrer\">this pull request</a>. I modified the standard <code>auto-render.min.js</code> script to add standard $\\KaTeX$ $ $ tags.</p>","contentMarkdown":"Making a website in the modern era is not easy to do for free. I did it using Zola, Github Pages, and Github Actions.\nI've always wanted to have a personal website where I can upload what I do on my local computer to access remotely and have the world see. But it always seemed like too much of a hassle to set up and I didn't have the capital to invest in a website that I didn't need. However, when I started going back to university in-person this year, I found it much easier to take notes by typing them instead of using OneNote as I was accustomed, as the amount of code I had to write was drastically increased. Needing a way to access them remotely with a nice view, I thought a blog would be a good way to do that in addition to all the other things I had always wanted a website for. So, I embarked on a journey to create a website.\n\n## Github Pages\n\nA website is no use unless we have somewhere to put it. [Github Pages](https://pages.github.com/) is a service offered by Github since 2008 that allows you to host your own website from a Github repository. You get one free website per Github account, which is called [username].github.io. All we have to do to enable it is create a repository named [username].github.io and enable Github Pages in the settings!\n\n```bash\n# should be above 2.28 to enable default branch name change\ngit --version\n\nmkdir [username].github.io\ncd [username].github.io\n\n# personal git config\ngit config --global user.name \"NAME\"\ngit config --global user.email \"EMAIL\"\ngit config --global init.defaultBranch \"main\"\ngit init\n\ngh repo create [username].github.io --public --source=. --remote-upstream\n```\n\nIf you're using [Visual Studio Code](https://code.visualstudio.com/) as your editor, there's a nicer way to do this than through the command line. After installing [the Github extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github), go to the Source Control button on the sidebar. There should be a button labeled \"Publish to Github\" which allows you to interactively initialize a Git repository in the current folder and publish it to Github.\n\n## Github Actions\n\nWe might have created our Github page, but we need a way to get all of the code from our repository to the website. This is called **deployment**. Luckily, we have a way to automatically deploy our website through **Github Actions**. [Github Actions](https://github.com/features/actions) is another service offered by Github since 2019 that gives you free CI in public repositories. Although the free tier is [fairly limited](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes) at 500 MB and 2000 minutes per month, it should be more than enough for a static blog that is not deployed very often.\n\nThere is an action automatically created for our Github page called `pages-build-deployment` which, as the name implies, builds and deploys the page you've created on push. The way that I organized my code, which is probably the simplest option, is that I hosted my code at the `main` branch and had a `gh-pages` branch that hosted the actual website which was built from the `main` branch. If you want to do the same, go to `Settings` -> `Pages` and make sure that the build target is the `gh-pages` branch at the root.\n\nFor now, this won't do anything because we don't have a `gh-pages` branch or anything in our `main` branch. So how do we *actually* make our website?\n\n## Zola\n\n[Zola](https://www.getzola.org/) is a static site generator written in [Rust](https://www.rust-lang.org/), and is one of the fastest out there. I decided to choose it for my website. If you'd prefer a different generator, this is where this guide diverges for you. There are plenty of tutorials for Hugo websites or others, but I have found a lack of Zola guides so I decided to create this.\n\nTo start, [install Zola on your system](https://www.getzola.org/documentation/getting-started/installation/). The documentation on the website is pretty stellar so I would recommend reading that to get a quick understanding on how to use Zola. I will explain the parts that I personally found difficult or unclear.\n\n```bash\nzola init\nzola build # unnecessary as serve will also automatically build it\nzola serve\n```\n\nNow you can see your new website at `127.0.0.1:1111`!\n\n## Zola Deployment\n\nAlthough we can build your website very simply on our local machine, it would be preferable to automatically build the website when we publish content so we don't have to mess around with all of that. The [Zola-approved way](https://www.getzola.org/documentation/deployment/github-pages/) to do this is by using [zola-deploy-action](https://github.com/shalzz/zola-deploy-action). All of you have to do is click the `New Workflow` button on the `Actions` page from your Github repository and follow the link to `set up a workflow yourself`, then copy-paste this into it:\n\n```yaml\n# On every push this script is executed\non: push\nname: Build and deploy GH Pages\njobs:\n  build:\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs/heads/main'\n    steps:\n      - name: checkout\n        uses: actions/checkout@v2\n      - name: build_and_deploy\n        uses: shalzz/zola-deploy-action@v0.14.1\n        env:\n          # Target branch\n          PAGES_BRANCH: gh-pages\n          # Provide personal access token\n          TOKEN: ${{ secrets.TOKEN }}\n```\n\nHowever, I wanted more configuration and control over my action. Github Actions operates using Jekyll by default, so unless you add a `.nojekyll` file to the build branch it will run unnecessary steps to build a Jekyll theme. In order to reduce complexity, I decided to make a similar action that adds that command. If you're comfortable with the workflow as provided, then skip the next section.\n\n## Creating a Github Action\n\nAn action of the type we want here consists of three files: `action.yaml`, `Dockerfile`, and `entrypoint.sh`. Let's break these down.\n\n- `action.yaml`: the configuration file that tells Github Actions what to do\n- `Dockerfile`: the configuration file for the Docker container that Github Actions will set up\n- `entrypoint.sh`: the shell script that will execute the commands we want\n\n`action.yaml` is simple. It should follow this general format:\n\n```yaml\n# action.yaml\nname: 'ACTION_NAME'\ndescription: 'DESC'\nauthor: 'NAME'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n```\n\nThe Dockerfile is more complex and has many more options. I kept mine simple to what is needed, you may have your own preference for Docker images.\n\n```Dockerfile\n# any Docker image is fine, I prefer debian\nfrom debian:stable-slim\nMAINTAINER NAME <EMAIL>\n\n# for github actions\nLABEL \"com.github.actions.name\"=\"ACTION_NAME\"\nLABEL \"com.github.actions.description\"=\"DESC\"\n\n# locale, I am in the U.S. so I use en_US\nENV LC_ALL C.UTF-8\nENV LANG en_US.UTF-8\nENV LANGUAGE en_US.UTF-8\n\n# standard apt-get + wget and git for getting and building\nRUN apt-get update && apt-get install -y wget git\n\n# get zola on the docker image\nRUN wget -q -O - \\\n\"https://github.com/getzola/zola/releases/download/v0.15.3/zola-v0.15.3-x86_64-unknown-linux-gnu.tar.gz\" \\\n| tar xzf - -C /usr/local/bin\n\nCOPY entrypoint.sh /entrypoint.sh\n\n# give the entrypoint executable permissions\nRUN chmod +x entrypoint.sh\nENTRYPOINT [\"/entrypoint.sh\"]\n```\n\n`entrypoint.sh` is where all the magic happens. Fundamentally, all that it does is call `zola build` on the `main` branch, which builds your website inside the `public` directory (you can configure this if you so wish). It then commits those website files to the `gh-pages` branch.\n\nWe need one more thing before we can create `entrypoint.sh`; a token. We need to authorize our action to be able to push to `gh-pages`. You can create a token by going to [this page](https://github.com/settings/tokens) and creating a new token with at least `repo` rights. You can add the token to your repository by going to `Settings` -> `Secrets` -> `Actions` and creating a new repository secret called `TOKEN` (or any other name you like).\n\nWith that token, this is the basic necessities for `entrypoint.sh`:\n\n```bash\n#!/bin/bash\nset -e\nset -o pipefail\n\nmain() {\n    git config --global url.\"https://\".insteadOf git://\n    git config --global url.\"$GITHUB_SERVER_URL/\".insteadOf \"git@github.com\":\n\n    # update git submodules (important if you have themes)\n    git submodule update --init --recursive\n\n    zola build\n\n    cd public\n\n    # if you want to add any commands do it here e.g. `touch .nojekyll`\n\n    git init\n    git config user.name \"GitHub Actions\"\n    git config user.email \"github-actions-bot@users.noreply.github.com\"\n    git add .\n\n    git commit -m \"Deploy ${GITHUB_REPOSITORY} to ${GITHUB_REPOSITORY}:gh-pages\"\n    git push --force \"https://${GITHUB_ACTOR}:${TOKEN}@github.com/${GITHUB_REPOSITORY}.git\" master:gh-pages\n}\n\nmain \"$@\"\n```\n\nWith all of these settings, this is how your workflow should look:\n\n```yaml\n# .github/workflows/main.yml\non: push\nname: Build and deploy GH Pages\njobs:\n  build:\n    runs-on: ubuntu-latest\n    if: github.ref == 'refs/heads/main'\n    steps:\n      - name: checkout\n        uses: actions/checkout@v2\n      - name: build-and-deploy\n        uses: ./ # wherever your action is in relation to the root of the repo\n        env:\n          TOKEN: ${{secrets.TOKEN}}\n```\n\n## Themes\n\nZola requires a [Tera](https://tera.netlify.app/) template to render your site for the base site `index.html` as well as `page.html` for page-specific settings. You can also use [Sass](https://sass-lang.com/) stylesheets if you enable it in your `config.toml`. **Themes** are a convenient way to have those built for you so you can get a website looking nice without excessive fiddling. I decided to use the [after-dark](https://github.com/getzola/after-dark) theme which is based on the Hugo theme of the same name. Since I wanted to make my own modifications to it, [I forked it](https://github.com/sharifhsn/after-dark) and added the changes I wanted. The easiest way to add a theme for Github pages is to use submodules:\n\n```bash\ngit submodule add https://github.com/getzola/after-dark.git themes/after-dark\n```\n\nThe deploy action will take care of updating the submodule as necessary. Just add the theme to your `config.toml` file and voila!\n\nAlthough I like the `after-dark` theme, I might change to a different theme or make my own in the future to accommodate my goals for this website. If that happens, I'll detail that process in another post.\n\n## $\\KaTeX$\n\nMost of the lecture notes I write incorporate [$\\KaTeX$](https://katex.org/) in some way. I find it an expressive way to write formulas and math expressions when reviewing for tests. `after-dark` does not provide $\\KaTeX$ support by default, which is part of the reason I forked it.\n\nMy preferred option for $\\KaTeX$ rendering would be server-side, as I don't plan on pushing very often (perhaps once per day) and Zola compilation is extremely quick. However, after doing some research into [previous attempts](https://github.com/getzola/zola/pull/1073), I decided it wasn't feasible for now. Perhaps in the future I'll take a stab at implementing it myself, but for now I'll settle for client-side.\n\n[The $\\KaTeX$ docs](https://katex.org/docs/browser.html) give a pretty good description on how to incorporate it into your website. In Tera, all you have to do is enclose those stylesheets/scripts into CSS/JS blocks, respectively. My inspiration came from [this pull request](https://github.com/getzola/after-dark/pull/22). I modified the standard `auto-render.min.js` script to add standard $\\KaTeX$ \\$ \\$ tags.","dataUrl":"https://sharifhsn.dev/api/posts/making-a-website.json","date":"2022-02-26","datePublished":"2022-02-26","description":"Making a website in the modern era is not easy to do for free. I did it using Zola, Github Pages, and Github Actions. I've always wanted to have a personal website where I can uplo…","site":"https://sharifhsn.dev","slug":"making-a-website","source":"Archive","sourceUrl":null,"tags":["zola","github actions","website","Meta"],"title":"Making a Website with Zola, Github Pages, and Github Actions","url":"https://sharifhsn.dev/blog/making-a-website/","version":"1","wordCount":1717}