<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohammad Altaleb</title>
    <description>The latest articles on DEV Community by Mohammad Altaleb (@mohammadaltaleb).</description>
    <link>https://dev.to/mohammadaltaleb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F124465%2Ff830e09b-1cf3-4e33-9765-2af819299b6e.jpg</url>
      <title>DEV Community: Mohammad Altaleb</title>
      <link>https://dev.to/mohammadaltaleb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohammadaltaleb"/>
    <language>en</language>
    <item>
      <title>Serving a Git repository over HTTP</title>
      <dc:creator>Mohammad Altaleb</dc:creator>
      <pubDate>Mon, 13 May 2019 11:03:15 +0000</pubDate>
      <link>https://dev.to/mohammadaltaleb/serving-a-git-repository-over-http-35ff</link>
      <guid>https://dev.to/mohammadaltaleb/serving-a-git-repository-over-http-35ff</guid>
      <description>&lt;p&gt;A while ago, I was assigned the task of researching how to serve a Git repository over HTTP. The tutorials and documentations I've found were either messy or incomplete.&lt;/p&gt;

&lt;p&gt;After a painful process, I got it to work. But, unfortunately a decision was made to use a different approach to serve the repo.&lt;/p&gt;

&lt;p&gt;I didn't want to just throw the effort away. So, here's a blog post about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The setup
&lt;/h1&gt;

&lt;p&gt;We'll use &lt;a href="https://httpd.apache.org"&gt;Apache&lt;/a&gt; web server to serve the repository, and we'll install it on an &lt;a href="http://releases.ubuntu.com/16.04/"&gt;Ubuntu 16.04.5&lt;/a&gt; machine (&lt;a href="https://aws.amazon.com/ec2/"&gt;AWS EC2&lt;/a&gt; instance in my case).&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Let's start by installing Git and Apache&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install git-core
sudo apt-get install apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Creating the repo
&lt;/h1&gt;

&lt;p&gt;For this tutorial, we will create a new Git repository in the documents root (&lt;strong&gt;/var/www/html&lt;/strong&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /var/www/html
mkdir git
cd git
mkdir reponame
cd reponame
git init --bare
chgrp -R www-data /var/www/html/git
chown -R www-data /var/www/html/git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to allow other people to push to the repo, open the file named &lt;strong&gt;config&lt;/strong&gt; which was added to the repository by Git and append the following to it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[http]
    receivepack = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Authentication
&lt;/h1&gt;

&lt;p&gt;We only want authenticated users to access the repo. So, first we'll create a dummy bash script named &lt;strong&gt;auth.sh&lt;/strong&gt; in (&lt;strong&gt;/usr/local/bin/&lt;/strong&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /usr/local/bin/
touch auth.sh
chmod 755 auth.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script will check a given username and password and exit with &lt;strong&gt;0&lt;/strong&gt; code if they are correct or &lt;strong&gt;1&lt;/strong&gt; otherwise.&lt;br&gt;
The content of the script is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;read &lt;/span&gt;user
&lt;span class="nb"&gt;read &lt;/span&gt;password

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be able to use our script with Apache, we should install the package &lt;a href="https://packages.ubuntu.com/xenial/libapache2-mod-authnz-external"&gt;libapache2-mod-authnz-external&lt;/a&gt; that allows authentication against external services&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get install libapache2-mod-authnz-external
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we'll make sure the authentication module is enabled&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a2enmod authnz_external
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configuring Apache
&lt;/h1&gt;

&lt;p&gt;create an Apache configuration file with the name &lt;strong&gt;httpd.conf&lt;/strong&gt; in (&lt;strong&gt;/etc/apache2/&lt;/strong&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /etc/apache2/
touch httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content of &lt;strong&gt;httpd.conf&lt;/strong&gt; should be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&amp;lt;&lt;span class="n"&gt;VirtualHost&lt;/span&gt; *:&lt;span class="m"&gt;80&lt;/span&gt;&amp;gt;

    &lt;span class="n"&gt;SetEnv&lt;/span&gt; &lt;span class="n"&gt;GIT_PROJECT_ROOT&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;www&lt;/span&gt;/&lt;span class="n"&gt;html&lt;/span&gt;/&lt;span class="n"&gt;git&lt;/span&gt;
    &lt;span class="n"&gt;SetEnv&lt;/span&gt; &lt;span class="n"&gt;GIT_HTTP_EXPORT_ALL&lt;/span&gt;
    &lt;span class="n"&gt;SetEnv&lt;/span&gt; &lt;span class="n"&gt;REMOTE_USER&lt;/span&gt;=$&lt;span class="n"&gt;REDIRECT_REMOTE_USER&lt;/span&gt;

    &lt;span class="n"&gt;DocumentRoot&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;www&lt;/span&gt;/&lt;span class="n"&gt;html&lt;/span&gt;
    &amp;lt;&lt;span class="n"&gt;Directory&lt;/span&gt; &lt;span class="s2"&gt;"/var/www/html"&lt;/span&gt;&amp;gt;
        &lt;span class="n"&gt;Options&lt;/span&gt; &lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="n"&gt;Includes&lt;/span&gt; &lt;span class="n"&gt;Indexes&lt;/span&gt; &lt;span class="n"&gt;FollowSymLinks&lt;/span&gt;
        &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;allow&lt;/span&gt;,&lt;span class="n"&gt;deny&lt;/span&gt;
        &lt;span class="n"&gt;Allow&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="n"&gt;AllowOverride&lt;/span&gt; &lt;span class="n"&gt;All&lt;/span&gt;
    &amp;lt;/&lt;span class="n"&gt;Directory&lt;/span&gt;&amp;gt;


    &lt;span class="n"&gt;ScriptAliasMatch&lt;/span&gt; \
        &lt;span class="err"&gt;"&lt;/span&gt;(?&lt;span class="n"&gt;x&lt;/span&gt;)^/&lt;span class="n"&gt;git&lt;/span&gt;/(.*/(&lt;span class="n"&gt;HEAD&lt;/span&gt; | \
        &lt;span class="n"&gt;info&lt;/span&gt;/&lt;span class="n"&gt;refs&lt;/span&gt; | \
        &lt;span class="n"&gt;objects&lt;/span&gt;/(&lt;span class="n"&gt;info&lt;/span&gt;/[^/]+ | \
        [&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;-&lt;span class="n"&gt;f&lt;/span&gt;]{&lt;span class="m"&gt;2&lt;/span&gt;}/[&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;-&lt;span class="n"&gt;f&lt;/span&gt;]{&lt;span class="m"&gt;38&lt;/span&gt;} | \
        &lt;span class="n"&gt;pack&lt;/span&gt;/&lt;span class="n"&gt;pack&lt;/span&gt;-[&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;-&lt;span class="n"&gt;f&lt;/span&gt;]{&lt;span class="m"&gt;40&lt;/span&gt;}\.(&lt;span class="n"&gt;pack&lt;/span&gt;|&lt;span class="n"&gt;idx&lt;/span&gt;)) | \
        &lt;span class="n"&gt;git&lt;/span&gt;-(&lt;span class="n"&gt;upload&lt;/span&gt;|&lt;span class="n"&gt;receive&lt;/span&gt;)-&lt;span class="n"&gt;pack&lt;/span&gt;))$&lt;span class="err"&gt;"&lt;/span&gt; \
        &lt;span class="s2"&gt;"/usr/lib/git-core/git-http-backend/$1"&lt;/span&gt;

    &lt;span class="n"&gt;Alias&lt;/span&gt; /&lt;span class="n"&gt;git&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;www&lt;/span&gt;/&lt;span class="n"&gt;html&lt;/span&gt;/&lt;span class="n"&gt;git&lt;/span&gt;

    &amp;lt;&lt;span class="n"&gt;Directory&lt;/span&gt; /&lt;span class="n"&gt;usr&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;git&lt;/span&gt;-&lt;span class="n"&gt;core&lt;/span&gt;&amp;gt;
        &lt;span class="n"&gt;Options&lt;/span&gt; +&lt;span class="n"&gt;ExecCGI&lt;/span&gt; -&lt;span class="n"&gt;MultiViews&lt;/span&gt; +&lt;span class="n"&gt;SymLinksIfOwnerMatch&lt;/span&gt;
        &lt;span class="n"&gt;AuthType&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt;
        &lt;span class="n"&gt;AuthName&lt;/span&gt; &lt;span class="s2"&gt;"Restricted"&lt;/span&gt;
        &lt;span class="n"&gt;AuthBasicProvider&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt;
        &lt;span class="n"&gt;AuthExternal&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;
        &lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;-&lt;span class="n"&gt;user&lt;/span&gt;
    &amp;lt;/&lt;span class="n"&gt;Directory&lt;/span&gt;&amp;gt;

    &amp;lt;&lt;span class="n"&gt;Directory&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;www&lt;/span&gt;/&lt;span class="n"&gt;html&lt;/span&gt;/&lt;span class="n"&gt;git&lt;/span&gt;&amp;gt;
        &lt;span class="n"&gt;Options&lt;/span&gt; +&lt;span class="n"&gt;ExecCGI&lt;/span&gt; +&lt;span class="n"&gt;Indexes&lt;/span&gt; +&lt;span class="n"&gt;FollowSymLinks&lt;/span&gt;
        &lt;span class="n"&gt;Allowoverride&lt;/span&gt; &lt;span class="n"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;AuthType&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt;
        &lt;span class="n"&gt;AuthName&lt;/span&gt; &lt;span class="s2"&gt;"Restricted"&lt;/span&gt;
        &lt;span class="n"&gt;AuthBasicProvider&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt;
        &lt;span class="n"&gt;AuthExternal&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;
        &lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;-&lt;span class="n"&gt;user&lt;/span&gt;
    &amp;lt;/&lt;span class="n"&gt;Directory&lt;/span&gt;&amp;gt;

    &lt;span class="n"&gt;AddExternalAuth&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; /&lt;span class="n"&gt;usr&lt;/span&gt;/&lt;span class="n"&gt;local&lt;/span&gt;/&lt;span class="n"&gt;bin&lt;/span&gt;/&lt;span class="n"&gt;auth&lt;/span&gt;.&lt;span class="n"&gt;sh&lt;/span&gt;
    &lt;span class="n"&gt;SetExternalAuthMethod&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;

&amp;lt;/&lt;span class="n"&gt;VirtualHost&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open &lt;strong&gt;/etc/apache2/apache2.conf&lt;/strong&gt; file and comment out the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IncludeOptional sites-enabled/*.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, add the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Include /etc/apache2/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable &lt;strong&gt;mod_cgi&lt;/strong&gt;, &lt;strong&gt;mod_alias&lt;/strong&gt; and &lt;strong&gt;mod_env&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a2enmod cgi alias env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, update the repo and restart Apache&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /var/www/html/git/reponame
git update-server-info

service apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Testing
&lt;/h1&gt;

&lt;p&gt;On your machine, clone the repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone http://{SERVER_DOMAIN}/git/reponame/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add something to the repo and commit it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch test.txt
git add test.txt 
git commit -m "test commit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push the changes to the remote repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's about it. If the clone and push succeed, it means we successfully served our repository.&lt;/p&gt;

</description>
      <category>git</category>
      <category>http</category>
      <category>apache</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
