<!DOCTYPE html>
<html lang="en">
  <head>
    <base href="https://static.luevano.xyz/">
    <meta charset="utf-8">
    <title>Luévano's Blog</title>
    <link rel="icon" href="fa/svgs/solid/dragon.svg">

    <!-- general style -->
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <link rel="stylesheet" type="text/css" href="fa/css/all.min.css">

    <!-- highlight support for code blocks -->
    <script type="text/javascript" src="hl/highlight.min.js"></script>
    <script type="text/javascript">hljs.initHighlightingOnLoad();</script>

    <!-- theme related -->
    <script type="text/javascript" src="scripts/theme.js"></script>
    <link id="theme-css" rel="stylesheet" type="text/css" href="css/dark.css">
    <link id="code-theme-css" rel="stylesheet" type="text/css" href="hl/styles/solarized-dark.min.css">
  </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><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>

      <div class="theme-switch-container">
        <i class="fas fa-sun"></i>
        <label class="switch theme">
          <input id="theme-switch" type="checkbox" onclick="toggleTheme()">
          <span class="slider round"></span>
        </label>
        <i class="fas fa-moon"></i>
      </div>
    </header>

    <main>
<h1>Create a git server and setup cgit web app (on Nginx)</h1>

<p>My git server is all I need to setup to actually <em>kill</em> my other server (I've been moving from servers on these last 2-3 blog entries), that's why I'm already doing this entry. I'm basically following <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server">git's guide on setting up a server</a> plus some specific stuff for (btw i use) 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's no user/authentication control other than that of SSH. Also, most if not all commands here are run as root.</p>

<h2>Prerequisites</h2>

<p>I might get tired of saying this (it's just copy paste, basically)&#8230; but similar 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):</p>

<ul>
<li>(This time, optional) A domain name if you want to have a &#8220;front end&#8221; to show your repositories. Got mine on <a href="https://www.epik.com/?affid=da5ne9ru4">Epik</a> (affiliate link, btw).

<ul>
<li>With a <strong>CNAME</strong> for &#8220;git&#8221; and (optionally) &#8220;www.git&#8221;, or some other name for your sub-domains.</li>
</ul></li>
<li>A VPS or somewhere else to host. I'm using <a href="https://www.vultr.com/?ref=8732849">Vultr</a> (also an affiliate link).

<ul>
<li><code>ssh</code> configured.</li>
<li>(Optionally, if doing the domain name thingy) With <code>nginx</code> and <code>certbot</code> setup and running.</li>
<li>Of course, <code>git</code> already installed (it should be a must have always).</li>
</ul></li>
</ul>

<h2>git server</h2>

<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 &#8220;normal&#8221; user. So, create the <code>git</code> folder (with corresponding permissions) under <code>/home</code> and set the <code>git</code> user'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 &#8220;expired&#8221; 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>'s built in <code>ssh-copy-id</code> (for that you may want to check your <code>ssh</code> configuration in case you don'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'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're basically done. Now you should be able to push/pull repositories to your server&#8230; except, you haven't created any repository in your server, that's right, they're not created automatically when trying to push. To do so, you have to do the following sequence (assuming you're &#8220;<code>cd</code>'ed&#8221; into the <code>/home/git</code> directory):</p>

<pre><code class="language-sh">mkdir {repo_name}.git
cd {repo_name}.git
</code></pre>

<p>Those two lines above will need to be run each time you want to add a new repository to your server (yeah, kinda lame&#8230; although there are options to &#8220;automate&#8221; this, 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.), which is detailed <a href="https://gist.github.com/rvl/c3f156e117e22a25f242">here</a>.</p>

<h2>cgit</h2>

<p>This bit is optional if you only wanted a git server (really easy to set up), this is so you can have a web application. This is basically a copy paste of <a href="https://wiki.archlinux.org/index.php/Cgit#Nginx">Arch Linux Wiki: Cgit</a> so you can go there and get more in-depth configurations.</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, the way I configure <code>nginx</code> is creating a separate file <code>{module}.conf</code> (<code>git.conf</code> in this case) under <code>/etc/nginx/sites-available</code> and create a symlink to <code>/etc/nginx/sites-enabled</code> as stated in my <a href="https://blog.luevano.xyz/a/website_with_nginx.html"><code>nginx</code> 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't have already.</p>

<p>Now, all that'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
source-filter=/usr/lib/cgit/filters/syntax-highlighting-edited.sh
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 let web crawlers (like Google'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 &#8220;private&#8221; repos) using the option <code>scan-path</code> and setup <code>.git/description</code> for each repository. I will add more to my actual configuration, but for now it is useful as it is. For more, you can check <a href="https://man.archlinux.org/man/cgitrc.5">cgitrc(5)</a>.</p>

<p>Finally, if you want further support for highlighting, other compressed snapshots or support for markdown, checkout the optional dependencies for <code>cgit</code> and also the Arch Wiki goes in detail on how to setup highlighting with two different packages.</p>

<div class=timestamp>
<hr>
<p>Created: Sat, Mar 20, 2021 @ 22:58 MST; modified: Sun, Mar 21, 2021 @ 12:00 MST</p>
</div>
    </main>

    <footer>
      <i class="fas fa-envelope" alt="Email"></i>
      Email
      <a href="mailto:david@luevano.xyz">
        david@luevano.xyz
      </a>
      <br>

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

      <i class="fas fa-donate" alt="Donate"></i>
      <a href="https://luevano.xyz/donate">Donate</a>
      <a href="https://paypal.me/dlvna"><i class="fab fa-paypal" alt="Paypal"></i></a>
    </footer>
  </body>
</html>