# Building and Hosting a site with Git
by Seth Kenlon

Creating a web site used to be both sublimely simple and a form of black
magic all at once. Back in the old days of Web 1.0 (that's not what
anyone actually called it), you could just open up any website, view its
source code, and reverse engineer the HTML, with all of its inline
styling and table-based layout, and you felt like a programmer after an
afternoon or two. But then there was the matter of getting the page
you'd create on the Internet, which meant dealing with servers and FTP
and web root directories and file permissions. While the modern web has
become far more complex since then, but self-publication can be just as
easy (or easier!) if you let Git help you out.

Introducing Hugo
================

[Hugo](http://gohugo.io) is an open source static site generator. Static
sites are what the Web used to be built upon (if you go back far enough,
it was *all* the Web was). There are several advantages to static sites:
they're relatively easy to write because you don't have to code them,
they're relatively secure because there's no code being executed on the
pages, and they can be quite fast because there's no processing
happening aside from transferring whatever you have on the page. Hugo
isn't the only static site generator out there.
[Grav](http://getgrav.org), [Pico CMS](http://picocms.org/),
[Jekyll](https://jekyllrb.com),
[Podwrite](https://slackermedia.info/podwrite), and many others provide
an easy way to create a full-featured website with minimal maintenance.
Hugo happens to be one with Gitlab integration built in, so you can
generate and host your website with just a free Gitlab account.

![](letsencrypt-site.jpg)

**Installing Hugo**

Hugo is cross-platform. Install instructions are available at
[gohugo.io/getting-started/installing](https://gohugo.io/getting-started/installing).

If you're on Linux or BSD, it's easiest to install Hugo from a software
repository or ports tree. The exact command varies depending on what
your distribution provides, but on Fedora or Red Hat:


   $ sudo dnf install hugo



Hugo has been installed. Confirm that you have installed it correctly by
opening a terminal and typing this command:

   $ hugo help

This prints all the options available for the `hugo` command. If you
don't see that, then you may have installed Hugo incorrectly, or else
you need to [add the command to your
path](https://opensource.com/article/17/6/set-path-linux).

Creating your site
==================

To build a Hugo site, you must have a specific directory structure. Use
`hugo` to generate this for you.


   $ hugo new site mysite



You now have a directory called `mysite`, and it contains the default
directories you need to build a Hugo website.

Your interface to get your site on the Internet is Git, so change
directory to your new `mysite` folder and initialize it as a Git
repository:


   $ cd mysite
   $ git init .



Hugo is pretty Git-friendly, so you can even use Git to install a theme
for your site. Unless you plan on developing the theme you're
installing, you can use the `--depth` option to clone just the latest
state of the theme's source:


   $ git clone --depth 1 \
   https://github.com/darshanbaral/mero.git\
   themes/mero



Now create some content for your site:


   $ hugo new posts/hello.md



Use your favourite text editor to edit the `hello.md` file in the
`content/posts` directory. Hugo accepts markdown files and converts them
to themed HTML files for you at publication time, so your content must
be in [markdown format](https://commonmark.org/help/).

If you want to include images in your post, create a folder called
`images` in the `static` directory. Place your images into this folder,
and reference them in your markup using the absolute path starting with
`/images`:


   ![A picture of a thing](/images/thing.jpeg)



**Theme**

You can find more themes at
[themes.gohugo.io](https://themes.gohugo.io/) but it's best to stay with
a basic theme whilst testing. The canonical Hugo test theme is
[Ananke](https://themes.gohugo.io/gohugo-theme-ananke/). Some themes
have complex dependencies, and others don't render pages the way you
might expect without complex configuration. The Mero theme used in this
example comes bundled with a detailed `config.toml` configuration file,
but for the sake of simplicity I'll only provide the basics here. Open
the file called `config.toml` in a text editor and add three
configuration parameters:


   languageCode = "en-us"
   title = "My website on the web"
   theme = "mero"

   [params]
     author = "Seth Kenlon"
     description = "My hugo demo"



**Preview**

You don't have to put anything on the Internet until you're ready to
publish. While you work, you can preview your site by launching the
local-only web server that ships with Hugo.


   $ hugo server --buildDrafts --disableFastRender



Open a web browser and navigate to <http://localhost:1313> to see your
work in progress.

Publishing with Git to Gitlab
=============================

To publish and host your site on Gitlab, you must create a repository
for the contents of your site.

To create a repository in Gitlab, click on the New Project button in
your Gitlab Projects page. Create an empty repository called
[yourGitlabUsername.gitlab.io](yourGitlabUsername.gitlab.io), replacing
`yourGitlabUsername` with your Gitlab user name or group name. You must
use this scheme as the name of your project. If you want to add a custom
domain later, you can.

Do not include a license or a README file (since you've already started
a project locally, adding these now would make pushing your data to
Gitlab more complex, and you can always add them later).

Once the empty repository on Gitlab has been created, add it as the
remote location for your local copy of your Hugo site, which is already
a Git repository:


   $ git remote add origin [email protected]:skenlon/mysite.git



Create a Gitlab site configuration file called `.gitlab-ci.yml` and
enter these options:


   image: monachus/hugo

   variables:
     GIT_SUBMODULE_STRATEGY: recursive

   pages:
     script:
     - hugo
     artifacts:
       paths:
       - public
     only:
     - master



The `image` parameter defines a containerized image that will serve your
site. The other parameters are instructions telling Gitlab's servers
what actions to execute when you push new code to your remote
repository. For more information on Gitlab's CI/CD (Continuous
Integration and Delivery) options, see
[docs.gitlab.com](https://docs.gitlab.com/ee/ci/#overview).

**Excludes**

Your Git repository is configured, the commands to build your site on
Gitlab's servers are set, and your site ready to publish. For your first
Git commit, you must take a few extra precautions so that you're not
version controlling files you don't intend to version control.

First, add the `/public` directory that Hugo creates when building your
site to your `.gitignore` file. You don't need to manage the finished
site in Git; all you need to track are your source Hugo files.


   $ echo "/public" >> .gitignore



It's not supported to maintain a Git repository within a Git repository
without creating a Git submodule. For the sake of keeping this exercise simple, move the embedded `.git` directory so
that the theme is just a theme.

Note that you *must* add your theme files to your Git repository so that
Gitlab has access to the theme. Without committing your theme files,
your site cannot successfully build.


   $ mv themes/mero/.git ~/.local/share/Trash/files/



Alternately, use a `trash` command such as
[Trashy](http://slackermedia.info/trashy):


   $ trash themes/mero/.git



Now you can add all the contents of your local project directory to Git,
and push it to Gitlab:


   $ git add .
   $ git commit -m 'hugo init'
   $ git push -u origin HEAD



Go live with Gitlab
===================

Once your code has been pushed to Gitlab, take a look at your project
page. An icon indicates that Gitlab is processing your build. It might
take several minutes the first time you push your code, so be patient.
However, don't be *too* patient, because the icon doesn't always update
reliably.

![](hugo-gitlab-cicd.jpg)

While you're waiting for Gitlab to assemble your site, go to your
project settings. In your project settings, find the Pages panel. Once
your site's ready, its URL will be provided for you. The URL is
[youGitlabUsername.gitlab.io/yourProjectName](youGitlabUsername.gitlab.io/yourProjectName).
Navigate to that address to view the fruits of your labour.

![](hugo-demo-site.jpg)

If your site fails to assemble correctly, Gitlab provides you insight
into the CI/CD pipeline logs. Review the error message for an indication
of what went wrong.

Git and the web
===============

Hugo (or Jekyll or similar) is just one way to leverage Git as your web
publishing tool. With server-side Git hooks, you can design your own
Git-to-WWW pipeline with minimal scripting. With the community edition
of Gitlab, you can self host your own Gitlab instance, or you can use an
alternative like [Gitolite](http://gitolite.com) or
[Gitea](http://gitea.io), and use this article as mere inspiration for a
custom solution. Have fun!