Publish a website to gitlab-pages
Published:
Suppose you want to publish and update your website regularly, but you don’t want to remember all the system operations needed, like copying the files onto the computer that runs the webserver, etc.
An interesting option is to manage your website as a git repository, and setup an automatic process to have it published by a Git hosting platform such as GitHub or GitLab (I will focus on the latter).
In this way, each time you commit and push a modification, a script can be triggered to perform all the steps required to update the online version of your site — for example, rebuilding it entirely with a static site generator and and starting or restarting a web server to serve the new content.
GitLab and CI/CD
With GitLab, the automation process can be implemented through the CI/CD (continuous integration/continuous development) feature. A .gitlab-ci.yml in the root of your repository describes the operations to be performed after the modifications have been pushed to the remote repository. These operations are executed by a runner, that is an independent machine that accepts requests from GitLab to execute the operations. In a usual development process, this CI/CD feature is generally used to compile the freshly committed version of the source code and to run some non-regression tests.
Project Naming Scheme
What name should I give to my project on GitLab?
Well, let us first explain the naming scheme used by Pages, as the final URL depends on it.
When a GitLab instance is deployed, the admin configures the Pages domain (pagesdomain). At Unistra, this is *.pages.unistra.fr. (More details on default domain names here).
The final URL depends on the type of GitLab pages, determined by the project name and membership (user or group) for this project.
Assuming you have created a project project, that user is your gitlab username and that (optionally) you have shared the project with a group, the naming will be the following:
| Type of GitLab Pages | Project path | Website URL |
|---|---|---|
| User pages | user/user.pagesdomain | https://user.pagesdomain |
| Group pages | group/group.pagesdomain | https://group.pagesdomain |
| Project pages owned by a user | user/project.pagesdomain | https://user.pagesdomain/project |
| Project pages owned by a group | group/project.pagesdomain | https://group.pagesdomain/project |
As an example, for my personal website (that I do not share with a group) I will create a blank project named genaud.pages.unistra.fr.
Local Repository
I assume here that you write your website on your local computer, which you then push to the gitlab remote repository. The name of the directory on your local computer (where you build your website) does not matter. However, the remote repository name which you attach to this local directory influences the final URL where it will be visible.
Once you have told git to register your local directory with git init, you should link it to this project on the remote repository with:
git remote add origin git@git.unistra.fr:genaud/genaud.pages.unistra.fr.git
Subsequently, git commit and git push will upload your local files, and the CI/CD .gitlab-ci.yml will be triggered.
CI/CD to publish a website
In our context, the .gitlab-ci.yml will build the website and take advantage of GitLab Pages. GitLab Pages will run a webserver1 on the GitLab-provided infrastructure, provide the corresponding URL and offer a control on the visibility of the website (through the project settings on GitLab), for instance public or only visible to gitlab members belonging to a group.
Notice also that this webserver will run in a Docker container.
So, what should this .gitlab-ci.yml contain? Briefly (refer to this documentation for complete explanations), we have to specify a pipeline of jobs to execute:
image:which base Docker image to use for the container running the webserver.before_script:specifies which additional software should be installed. If you use a website generator, you should download and install it in this stage.pages:which is a pre-defined job name that tells GitLab what to do for the website publishing: if a script has to be run and where the result should go.
An example of .gitlab-ci.yml for a Jekyll-generated site is shown below:
image: ruby:3.2-bullseye # choose the Ruby version you use locally
variables:
JEKYLL_ENV: production
BUNDLE_PATH: vendor/bundle # keep gems inside repo cache
BUNDLE_FROZEN: "true" # forces bundler to use Gemfile.lock, no version drift
cache:
paths:
- vendor/bundle
before_script:
- apt-get update -qq && apt-get install -y build-essential libffi-dev nodejs
- gem install bundler -v "$(tail -1 Gemfile.lock | awk '{print $2}')" || gem install bundler
- bundle install
pages:
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- main
In the pages: job, bundle exec jekyll build produces the html pages (the artifact), which are stored in a public directory. The paths: (pages.artifacts.page) explictly sets the location where the runner can get the html pages. Note that from GitLab 17.10 and onwards, this public should be automatically appended if not explictly specified.
A second implicit job is the pages:deploy job, automatically run by GitLab Pages to start the container and the webserver on the runner.
Where to see the website?
Once the deployment is achieved, you can see from the gitlab webGUI
Deploy > Pages
the exact URL build to access the site, for instance https://genaud-pages-unistra-fr-genaud-218c22c91d6fd2db6a47f35cddd0c738.pages.unistra.fr
However, a redirection mechanism is in place to give you a permanent URL that redirects to this runner. The URL will be as explained previously, for instance https://genaud.pages.unistra.fr.
GitLab settings
In order for all the precedent description to work, you must authorize a couple of things. From your GitLab WebUI, go to the settings of your project:
Settings > General, expand Visibility, project features, permissions,
and
- in top frame, Public Visibility choose ‘Public’ from the pulldown menu,
- in the
container registrysection below, turn on the Pages toglle and choose “Everyone With Access”, otherwise visitors would have to log in the gitlab instance and could see it only if they are members of the group.
-
Note that this webserver will refuse to execute server-side code, hence your site should be static HTML. ↩