<!DOCTYPE html>
<html class="theme-dark" lang="en
"
  prefix="og: https://ogp.me/ns#">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="https://static.luevano.xyz/images/icons/favicon.ico">
<title>Set up a Git server and cgit front-end -- Luévano's Blog</title>
  <meta name="description" content="How to create a Git server using cgit on a server running Nginx, on Arch. This is a follow up on post about creating a website with Nginx and Certbot."/>
<link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS">
    <!-- general style -->
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/style.css">
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/fork-awesome/css/fork-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/font-awesome/css/all.min.css">
    <!-- theme related -->
    <script type="text/javascript" src="https://static.luevano.xyz/scripts/theme.js"></script>
    <link id="theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/theme.css">
    <!-- misc functions-->
    <script type="text/javascript" src="https://static.luevano.xyz/scripts/return_top.js"></script>
    <!-- extra -->
    <!-- highlight support for code blocks -->
<script type="text/javascript" src="https://static.luevano.xyz/hl/highlight.min.js"></script>
<script type="text/javascript">
  hljs.initHighlightingOnLoad();
</script>
<link id="code-theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/hl/styles/nord.min.css">






    <!-- og meta -->
  <meta property="og:title" content="Set up a Git server and cgit front-end -- Luévano's Blog"/>
  <meta property="og:type" content="article"/>
  <meta property="og:url" content="https://blog.luevano.xyz/a/git_server_with_cgit.md"/>
  <meta property="og:image" content="https://static.luevano.xyz/images/b/default.png"/>
  <meta property="og:description" content="How to create a Git server using cgit on a server running Nginx, on Arch. This is a follow up on post about creating a website with Nginx and Certbot."/>
  <meta property="og:locale" content="en"/>
  <meta property="og:site_name" content="Luévano's Blog"/>
  </head>

  <body>
    <header>
<nav>
  <ul>
    <li>
      <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a>
    </li>

    <li>
      <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a>
    </li>

    <li>
      <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a>
    </li>

    <li><i class="fab fa-git" alt="Git"></i><span>Git</span>
      <ul>
        <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li>

        <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li>

        <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li>
      </ul>
    </li>

    <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span>
      <ul>
        <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li>
      </ul>
    </li>
  </ul>
</nav>

<button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button>

    </header>

    <main>
      <div class="return-top">
        <button class="return-top" onclick="returnTop()" id="returnTopButton">
        <i class="fas fa-arrow-up" alt="Return to top"></i>
        </button>
      </div>
  <h1>Set up a Git server and cgit front-end</h1>

  <p>My git server is all I need to setup to actually <em>kill</em> my other server (I&rsquo;ve been moving from servers on these last 2-3 blog entries), that&rsquo;s why I&rsquo;m already doing this entry. I&rsquo;m basically following <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server">git&rsquo;s guide on setting up a server</a> plus some specific stuff for <mark>btw i use</mark> Arch Linux (<a href="https://wiki.archlinux.org/index.php/Git_server#Web_interfaces">Arch Linux Wiki: Git server</a> and <a href="https://miracoin.wordpress.com/2014/11/25/step-by-step-guide-on-setting-up-git-server-in-arch-linux-pushable/">Step by step guide on setting up git server in arch linux (pushable)</a>).</p>
<p>Note that this is mostly for personal use, so there&rsquo;s no user/authentication control other than that of normal <code>ssh</code>. And as with the other entries, most if not all commands here are run as root unless stated otherwise.</p>
<h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">&para;</a></h2>
<div class="toc">
<ul>
<li><a href="#table-of-contents">Table of contents</a></li>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#git">Git</a></li>
<li><a href="#cgit">Cgit</a><ul>
<li><a href="#cgits-file-rendering">Cgit&rsquo;s file rendering</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<p>I might get tired of saying this (it&rsquo;s just copy paste, basically)&hellip; but you will need the same prerequisites as before (check my <a href="https://blog.luevano.xyz/a/website_with_nginx.html">website</a> and <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html">mail</a> entries), with the extras:</p>
<ul>
<li>(Optional, if you want a &ldquo;front-end&rdquo;) A <strong>CNAME</strong> for &ldquo;git&rdquo; and (optionally) &ldquo;www.git&rdquo;, or some other name for your sub-domains.</li>
<li>An SSL certificate, if you&rsquo;re following the other entries, add a <code>git.conf</code> and run <code>certbot --nginx</code> to extend the certificate.</li>
</ul>
<h2 id="git">Git<a class="headerlink" href="#git" title="Permanent link">&para;</a></h2>
<p><a href="https://wiki.archlinux.org/title/git">Git</a> is a version control system.</p>
<p>If not installed already, install the <code>git</code> package:</p>
<pre><code class="language-sh">pacman -S git
</code></pre>
<p>On Arch Linux, when you install the <code>git</code> package, a <code>git</code> user is automatically created, so all you have to do is decide where you want to store the repositories, for me, I like them to be on <code>/home/git</code> like if <code>git</code> was a &ldquo;normal&rdquo; user. So, create the <code>git</code> folder (with corresponding permissions) under <code>/home</code> and set the <code>git</code> user&rsquo;s home to <code>/home/git</code>:</p>
<pre><code class="language-sh">mkdir /home/git
chown git:git /home/git
usermod -d /home/git git
</code></pre>
<p>Also, the <code>git</code> user is &ldquo;expired&rdquo; by default and will be locked (needs a password), change that with:</p>
<pre><code class="language-sh">chage -E -1 git
passwd git
</code></pre>
<p>Give it a strong one and remember to use <code>PasswordAuthentication no</code> for <code>ssh</code> (as you should). Create the <code>.ssh/authorized_keys</code> for the <code>git</code> user and set the permissions accordingly:</p>
<pre><code class="language-sh">mkdir /home/git/.ssh
chmod 700 /home/git/.ssh
touch /home/git/.ssh/authorized_keys
chmod 600 /home/git/.ssh/authorized_keys
chown -R git:git /home/git
</code></pre>
<p>Now is a good idea to copy over your local SSH public keys to this file, to be able to push/pull to the repositories. Do it by either manually copying it or using <code>ssh</code>&lsquo;s built in <code>ssh-copy-id</code> (for that you may want to check your <code>ssh</code> configuration in case you don&rsquo;t let people access your server with user/password).</p>
<p>Next, and almost finally, we need to edit the <code>git-daemon</code> service, located at <code>/usr/lib/systemd/system/</code> (called <code>git-daemon@.service</code>):</p>
<pre><code class="language-ini">...
ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/home/git --enable=receive-pack
...
</code></pre>
<p>I just appended <code>--enable=receive-pack</code> and note that I also changed the <code>--base-path</code> to reflect where I want to serve my repositories from (has to match what you set when changing <code>git</code> user&rsquo;s home).</p>
<p>Now, go ahead and start and enable the <code>git-daemon</code> socket:</p>
<pre><code class="language-sh">systemctl start git-daemon.socket
systemctl enable git-daemon.socket
</code></pre>
<p>You&rsquo;re basically done. Now you should be able to push/pull repositories to your server&hellip; except, you haven&rsquo;t created any repository in your server, that&rsquo;s right, they&rsquo;re not created automatically when trying to push. To do so, you have to run (while inside <code>/home/git</code>):</p>
<pre><code class="language-sh">git init --bare {repo_name}.git
chown -R git:git {repo_name}.git
</code></pre>
<p><mark>Those two lines above will need to be run each time you want to add a new repository to your server</mark>. There are options to &ldquo;automate&rdquo; this but I like it this way.</p>
<p>After that you can already push/pull to your repository. I have my repositories (locally) set up so I can push to more than one remote at the same time (my server, GitHub, GitLab, etc.); to do so, check <a href="https://gist.github.com/rvl/c3f156e117e22a25f242">this gist</a>.</p>
<h2 id="cgit">Cgit<a class="headerlink" href="#cgit" title="Permanent link">&para;</a></h2>
<p><a href="https://wiki.archlinux.org/title/Cgit">Cgit</a> is a fast web interface for git.</p>
<p>This is optionally since it&rsquo;s only for the web application.</p>
<p>Install the <code>cgit</code> and <code>fcgiwrap</code> packages:</p>
<pre><code class="language-sh">pacman -S cgit fcgiwrap
</code></pre>
<p>Now, just start and enable the <code>fcgiwrap</code> socket:</p>
<pre><code class="language-sh">systemctl start fcgiwrap.socket
systemctl enable fcgiwrap.socket
</code></pre>
<p>Next, create the <code>git.conf</code> as stated in my <a href="https://blog.luevano.xyz/a/website_with_nginx.html">nginx setup entry</a>. Add the following lines to your <code>git.conf</code> file:</p>
<pre><code class="language-nginx">server {
    listen 80;
    listen [::]:80;
    root /usr/share/webapps/cgit;
    server_name {yoursubdomain}.{yourdomain};
    try_files $uri @cgit;

    location @cgit {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param QUERY_STRING $args;
        fastcgi_param HTTP_HOST $server_name;
        fastcgi_pass unix:/run/fcgiwrap.sock;
    }
}
</code></pre>
<p>Where the <code>server_name</code> line depends on you, I have mine setup to <code>git.luevano.xyz</code> and <code>www.git.luevano.xyz</code>. Optionally run <code>certbot --nginx</code> to get a certificate for those domains if you don&rsquo;t have already.</p>
<p>Now, all that&rsquo;s left is to configure <code>cgit</code>. Create the configuration file <code>/etc/cgitrc</code> with the following content (my personal options, pretty much the default):</p>
<pre><code class="language-apache">css=/cgit.css
logo=/cgit.png

enable-http-clone=1
# robots=noindex, nofollow
virtual-root=/

repo.url={url}
repo.path={dir_path}
repo.owner={owner}
repo.desc={short_description}
...
</code></pre>
<p>Where you can uncomment the <code>robots</code> line to not let web crawlers (like Google&rsquo;s) to index your <code>git</code> web app. And at the end keep all your repositories (the ones you want to make public), for example for my <a href="https://git.luevano.xyz/.dots"><em>dotfiles</em></a> I have:</p>
<pre><code class="language-apache">...
repo.url=.dots
repo.path=/home/git/.dots.git
repo.owner=luevano
repo.desc=These are my personal dotfiles.
...
</code></pre>
<p>Otherwise you could let <code>cgit</code> to automatically detect your repositories (you have to be careful if you want to keep &ldquo;private&rdquo; repos) using the option <code>scan-path</code> and setup <code>.git/description</code> for each repository. For more, you can check <a href="https://man.archlinux.org/man/cgitrc.5">cgitrc(5)</a>.</p>
<h3 id="cgits-file-rendering">Cgit&rsquo;s file rendering<a class="headerlink" href="#cgits-file-rendering" title="Permanent link">&para;</a></h3>
<p>By default you can&rsquo;t see the files on the site, you need a highlighter to render the files, I use <code>highlight</code>. Install the <code>highlight</code> package:</p>
<pre><code class="language-sh">pacman -S highlight
</code></pre>
<p>Copy the <code>syntax-highlighting.sh</code> script to the corresponding location (basically adding <code>-edited</code> to the file):</p>
<pre><code class="language-sh">cp /usr/lib/cgit/filters/syntax-highlighting.sh /usr/lib/cgit/filters/syntax-highlighting-edited.sh
</code></pre>
<p>And edit it to use the version 3 and add <code>--inline-css</code> for more options without editing <code>cgit</code>&lsquo;s CSS file:</p>
<pre><code class="language-sh">...
# This is for version 2
# exec highlight --force -f -I -X -S &quot;$EXTENSION&quot; 2&gt;/dev/null

# This is for version 3
exec highlight --force --inline-css -f -I -O xhtml -S &quot;$EXTENSION&quot; 2&gt;/dev/null
...
</code></pre>
<p>Finally, enable the filter in <code>/etc/cgitrc</code> configuration:</p>
<pre><code class="language-apache">source-filter=/usr/lib/cgit/filters/syntax-highlighting-edited.sh
</code></pre>
<p>That would be everything. If you need support for more stuff like compressed snapshots or support for markdown, check the optional dependencies for <code>cgit</code>.</p>

  <div class="page-nav">
    <span class="next">
      <a href="https://blog.luevano.xyz/a/new_blogging_system.html" alt="Next">
        <i class="fas fa-arrow-left" alt="Arrow left"></i>
        <span>Next</span>
      </a>
    </span>

    <span class="index">
      <a href="https://blog.luevano.xyz" alt="Index">
        <i class="fas fa-home" alt="Home"></i>
        <span>Index</span>
      </a>
    </span>

    <span class="previous">
      <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html" alt="Previous">
        <i class="fas fa-arrow-right" alt="Arrow right"></i>
        <span>Previous</span>
      </a>
    </span>
</div>


  <hr>
  <div class="article-info">
    <p>By David Luévano</p>
    <p>Created: Sun, Mar 21, 2021 @ 19:00 UTC</p>
      <p>Modified: Sat, Jun 03, 2023 @ 03:52 UTC</p>
    <div class="article-tags">
  <p>Tags:
<a href="https://blog.luevano.xyz/tag/@code.html">code</a>, <a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a>  </p>
</div>

  </div>
    </main>

    <footer>
<span>
  <i class="fas fa-address-card" alt="Contact"></i>
  <a href="https://blog.luevano.xyz/contact.html">Contact</a>
</span>

<span>
  <i class="fas fa-donate" alt="Donate"></i>
  <a href="https://blog.luevano.xyz/donate.html">Donate</a>
</span>

<span>
  <i class="fas fa-rss" alt="RSS"></i>
  <a target="_blank" href="https://blog.luevano.xyz/rss.xml">RSS</a>
</span>

<br>
<span class="created-with">
  <i class="fas fa-hammer" alt="Hammer"></i>
  Created with <a href="https://github.com/luevano/pyssg">pyssg</a>
</span>

<br>
<span class="copyright">
  Copyright <i class="far fa-copyright" alt="Copyright"></i> 2023 David Luévano Alvarado
</span>

    </footer>
  </body>
</html>