<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-07-16T17:15:27+00:00</updated><id>/feed.xml</id><title type="html">Stéphane Genaud</title><subtitle>Stéphane Genaud&apos;s Personal Page (professional). Papers, Projects and Teaching.</subtitle><author><name>Prof. S. Genaud</name><email>genaud _at_ unistra.fr</email><uri>https://en.unistra.fr</uri></author><entry><title type="html">Publish a website to gitlab-pages</title><link href="/utilities/2025/08/22/Deploy-website-to-gitlab-pages.html" rel="alternate" type="text/html" title="Publish a website to gitlab-pages" /><published>2025-08-22T07:00:05+00:00</published><updated>2025-08-22T07:00:05+00:00</updated><id>/utilities/2025/08/22/Deploy-website-to-gitlab-pages</id><content type="html" xml:base="/utilities/2025/08/22/Deploy-website-to-gitlab-pages.html"><![CDATA[<p>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.</p>

<p>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).<br />
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.</p>

<h2 id="gitlab-and-cicd">GitLab and CI/CD</h2>

<p>With GitLab, the automation process can be implemented through the
CI/CD (continuous integration/continuous development) feature. 
A <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code> 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 <em>runner</em>, 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.</p>

<h2 id="project-naming-scheme">Project Naming Scheme</h2>

<p>What name should I give to my project on GitLab?</p>

<p>Well, let us first explain the naming scheme used by Pages, as the final URL depends on it.</p>

<p>When a GitLab instance is deployed, the admin configures the <em>Pages
domain</em> (<code class="language-plaintext highlighter-rouge">pagesdomain</code>). At Unistra, this is <code class="language-plaintext highlighter-rouge">*.pages.unistra.fr</code>. 
(More details on default domain names
<a href="https://docs.gitlab.com/user/project/pages/getting_started_part_one/">here</a>).</p>

<p>The final URL depends on the type of GitLab pages, determined by the project name
and membership (user or group) for this project.<br />
Assuming you have created a project <code class="language-plaintext highlighter-rouge">project</code>, that <code class="language-plaintext highlighter-rouge">user</code> is your gitlab username 
and that (optionally) you have shared the project with a <code class="language-plaintext highlighter-rouge">group</code>, the naming will be the following:</p>

<table>
  <thead>
    <tr>
      <th>Type of GitLab Pages</th>
      <th>Project path</th>
      <th>Website URL</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>User pages</td>
      <td><code class="language-plaintext highlighter-rouge">user/user.pagesdomain</code></td>
      <td><code class="language-plaintext highlighter-rouge">https://user.pagesdomain</code></td>
    </tr>
    <tr>
      <td>Group pages</td>
      <td><code class="language-plaintext highlighter-rouge">group/group.pagesdomain</code></td>
      <td><code class="language-plaintext highlighter-rouge">https://group.pagesdomain</code></td>
    </tr>
    <tr>
      <td>Project pages owned by a user</td>
      <td><code class="language-plaintext highlighter-rouge">user/project.pagesdomain</code></td>
      <td><code class="language-plaintext highlighter-rouge">https://user.pagesdomain/project</code></td>
    </tr>
    <tr>
      <td>Project pages owned by a group</td>
      <td><code class="language-plaintext highlighter-rouge">group/project.pagesdomain</code></td>
      <td><code class="language-plaintext highlighter-rouge">https://group.pagesdomain/project</code></td>
    </tr>
  </tbody>
</table>

<p>As an example, for my personal website (that I do not share with a group) 
I will create a blank project named <code class="language-plaintext highlighter-rouge">genaud.pages.unistra.fr</code>.</p>

<h2 id="local-repository">Local Repository</h2>

<p>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.</p>

<p>Once you have told git to register your local directory with <code class="language-plaintext highlighter-rouge">git init</code>,
you should link it to this project on the remote repository with:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git remote add origin git@git.unistra.fr:genaud/genaud.pages.unistra.fr.git 
</code></pre></div></div>
<p>Subsequently, <code class="language-plaintext highlighter-rouge">git commit</code> and <code class="language-plaintext highlighter-rouge">git push</code> will upload your local files, 
and the CI/CD <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code> will be triggered.</p>

<h2 id="cicd-to-publish-a-website">CI/CD to publish a website</h2>

<p>In our context, the <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code> will build the website and take advantage
of <a href="https://docs.gitlab.com/user/project/pages/"><em>GitLab Pages</em></a>. 
GitLab Pages will run a webserver<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> 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.</p>

<p>Notice also that this webserver will run in a Docker container.</p>

<p>So, what should this <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code> contain? 
Briefly (refer to this <a href="https://docs.gitlab.com/topics/build_your_application/">documentation</a> 
for complete explanations), we have to specify a <em>pipeline</em> of <em>jobs</em> to execute:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">image:</code> which base Docker image to use for the container running the webserver.</li>
  <li><code class="language-plaintext highlighter-rouge">before_script:</code> specifies which additional software should be installed. 
 If you use a website generator, you should download and install it in this stage.</li>
  <li><code class="language-plaintext highlighter-rouge">pages:</code> 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.</li>
</ul>

<p>An example of <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code> for a Jekyll-generated site is shown below:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">image</span><span class="pi">:</span> <span class="s">ruby:3.2-bullseye</span>   <span class="c1"># choose the Ruby version you use locally</span>

<span class="na">variables</span><span class="pi">:</span>
  <span class="na">JEKYLL_ENV</span><span class="pi">:</span> <span class="s">production</span>
  <span class="na">BUNDLE_PATH</span><span class="pi">:</span> <span class="s">vendor/bundle</span>   <span class="c1"># keep gems inside repo cache</span>
  <span class="na">BUNDLE_FROZEN</span><span class="pi">:</span> <span class="s2">"</span><span class="s">true"</span>        <span class="c1"># forces bundler to use Gemfile.lock, no version drift</span>

<span class="na">cache</span><span class="pi">:</span>
  <span class="na">paths</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">vendor/bundle</span>

<span class="na">before_script</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">apt-get update -qq &amp;&amp; apt-get install -y build-essential libffi-dev nodejs</span>
  <span class="pi">-</span> <span class="s">gem install bundler -v "$(tail -1 Gemfile.lock | awk '{print $2}')" || gem install bundler</span>
  <span class="pi">-</span> <span class="s">bundle install</span>

<span class="na">pages</span><span class="pi">:</span>
  <span class="na">script</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">bundle exec jekyll build -d public</span>
  <span class="na">artifacts</span><span class="pi">:</span>
    <span class="na">paths</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">public</span>
  <span class="na">only</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">main</span>
</code></pre></div></div>

<p>In the <code class="language-plaintext highlighter-rouge">pages:</code> job, <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code> produces the html pages (the <em>artifact</em>), 
which are stored in a <code class="language-plaintext highlighter-rouge">public</code> directory. The <code class="language-plaintext highlighter-rouge">paths:</code> (<code class="language-plaintext highlighter-rouge">pages.artifacts.page</code>)  explictly sets
the location where the runner can get the html pages. Note that from GitLab 17.10 and onwards, this
<code class="language-plaintext highlighter-rouge">public</code> should be automatically appended if not explictly specified.</p>

<p>A second implicit job is the <code class="language-plaintext highlighter-rouge">pages:deploy</code> job, automatically run by GitLab Pages to
start the container and the webserver on the runner.</p>

<h2 id="where-to-see-the-website">Where to see the website?</h2>

<p>Once the deployment is achieved, you can see from the gitlab webGUI</p>
<blockquote>
  <p><strong>Deploy &gt; Pages</strong></p>
</blockquote>

<p>the exact URL build to access the site,
for instance <code class="language-plaintext highlighter-rouge">https://genaud-pages-unistra-fr-genaud-218c22c91d6fd2db6a47f35cddd0c738.pages.unistra.fr</code></p>

<p>However, a redirection mechanism is in place to give you a permanent URL that redirects to this runner.
The URL will be as <a href="#project-naming-scheme">explained previously</a>, 
for instance <code class="language-plaintext highlighter-rouge">https://genaud.pages.unistra.fr</code>.</p>

<h2 id="gitlab-settings">GitLab settings</h2>

<p>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:</p>
<blockquote>
  <p><strong>Settings &gt; General</strong>, expand <strong>Visibility, project features, permissions</strong>,</p>
</blockquote>

<p>and</p>
<ul>
  <li>in top frame, <strong>Public Visibility</strong> choose ‘Public’ from the pulldown menu,</li>
  <li>in the <code class="language-plaintext highlighter-rouge">container registry</code>section below, turn on the  <strong>Pages</strong> 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.</li>
</ul>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Note that this webserver will refuse to execute server-side code, hence your site should be static HTML. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Prof. S. Genaud</name><email>genaud _at_ unistra.fr</email><uri>https://en.unistra.fr</uri></author><category term="utilities" /><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">Moved to Unistra again</title><link href="/jekyll/update/2025/08/18/Back-to-Unistra.html" rel="alternate" type="text/html" title="Moved to Unistra again" /><published>2025-08-18T15:24:05+00:00</published><updated>2025-08-18T15:24:05+00:00</updated><id>/jekyll/update/2025/08/18/Back-to-Unistra</id><content type="html" xml:base="/jekyll/update/2025/08/18/Back-to-Unistra.html"><![CDATA[<p>I’ll officially be back at Unistra starting from September.
The ENSIIE adventure stops at that point.</p>]]></content><author><name>Prof. S. Genaud</name><email>genaud _at_ unistra.fr</email><uri>https://en.unistra.fr</uri></author><category term="jekyll" /><category term="update" /><summary type="html"><![CDATA[I’ll officially be back at Unistra starting from September. The ENSIIE adventure stops at that point.]]></summary></entry></feed>