feat(software/hosting-a-git-server): complete
This commit is contained in:
parent
731ad1f1f8
commit
87e2851324
4 changed files with 181 additions and 0 deletions
137
posts/software/hosting-a-git-server.html
Normal file
137
posts/software/hosting-a-git-server.html
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/styles/common.css" />
|
||||
<link rel="stylesheet" href="/styles/post.css" />
|
||||
<link rel="icon" type="image/webp" href="/public/logo.webp" />
|
||||
<link href="/public/prism/prism.css" rel="stylesheet" />
|
||||
<link href="/public/prism/prism-theme.css" rel="stylesheet" />
|
||||
<script defer src="/public/prism/prism.js"></script>
|
||||
<title>hosting a git server</title>
|
||||
</head>
|
||||
<body class="graph-background">
|
||||
<site-header></site-header>
|
||||
<main class="main">
|
||||
<div class="post-container">
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">hosting a git server</h1>
|
||||
<p class="post-meta">
|
||||
<time datetime="2025-05-7">7/05/2025</time>
|
||||
</p>
|
||||
</header>
|
||||
<article class="post-article">
|
||||
<h2>why</h2>
|
||||
<p>
|
||||
No reason. Perhaps to host personal files in the future. AWS's
|
||||
<a href="" target="_blank">micro free tier</a> is great, too.
|
||||
</p>
|
||||
<h2>what</h2>
|
||||
<ul>
|
||||
<li>Write my own git web ui</li>
|
||||
<li>Support clones from my own website</li>
|
||||
<li>Host private files on my git ui</li>
|
||||
</ul>
|
||||
<h2>the process</h2>
|
||||
<ol>
|
||||
<p>
|
||||
I detail self-hosting a git server on an AWS t2.micro instance
|
||||
("free" for 1 year) as of May 2025.
|
||||
<a
|
||||
href="https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols"
|
||||
target="_blank"
|
||||
>Git's instructions</a
|
||||
>
|
||||
were vastly outdated so hopefully this saves a lucky reader some
|
||||
time.
|
||||
</p>
|
||||
<li>
|
||||
Create the ec2 instance with setup wizard and add {in,out}bound
|
||||
rules for {SSH,HTTP,HTTPS,your ip} in the wizard security group.
|
||||
</li>
|
||||
<li>
|
||||
Use an elastic ip (free) to address public ip
|
||||
reassigning—this is a bother when ssh'ing (new verb?) into
|
||||
the box locally and/or configuring an Apache HTTP server.
|
||||
</li>
|
||||
<li>Understand bare git repositories and the ssh protocol.</li>
|
||||
<li>
|
||||
Configure an keypair and ssh in (the official instructions are
|
||||
fine for this). I moved it to <code>~/.ssh</code> and added an
|
||||
alias in <code>~/.ssh/config</code> for convenience. Clone a repo
|
||||
on the server to test.
|
||||
</li>
|
||||
<li>
|
||||
Set up a git daemon for <code>git://</code> protocol cloning at
|
||||
your own risk.
|
||||
</li>
|
||||
<li>Set up an Apache HTTPD server.</li>
|
||||
<li>
|
||||
Configure file permissions for the new user:
|
||||
<ol>
|
||||
<li><code>sudo chown -R git:git /srv/git</code></li>
|
||||
<li><code>sudo chgrp -R apache /srv/git</code></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>
|
||||
To deal with "dubious ownership" issues when cloning with HTTPS, I
|
||||
needed to add <b>exactly</b> the following configuration to
|
||||
<code>/etc/gitconfig</code>.
|
||||
<i>No group permission finagling will work</i>! Git only allows
|
||||
cloning repositories that are owned by the user. If you wish to
|
||||
clone via SSH with, say, user A, this same user must also be
|
||||
employed by your HTTP server to clone the files (customize
|
||||
HTTPD/whatever you're using accordingly).
|
||||
</li>
|
||||
<div class="code" data-file="gitconfig.git"></div>
|
||||
<li>
|
||||
Security-wise, set up TLS/HTTPS with
|
||||
<a href="https://letsencrypt.org/" target="_blank"
|
||||
>Let's Encrypt</a
|
||||
>. Further, only allow authorized people to actually
|
||||
<i>push</i> to the server. The following is my HTTPD configuration
|
||||
file
|
||||
<code>/etc/apache/conf.d/git-server.conf</code>
|
||||
hosting the web ui at the root and clone urls at
|
||||
<code>/git</code>:
|
||||
</li>
|
||||
<div class="code" data-file="git-server.apacheconf"></div>
|
||||
<li>
|
||||
There are a variety of choices for web ui, including
|
||||
<a href="https://git.zx2c4.com/cgit/" target="_blank">cgit</a>,
|
||||
<a href="https://git-scm.com/docs/gitweb" target="_blank">gitweb</a>
|
||||
(I do not recommend this—the scripts are ancient and require
|
||||
manual tuning), and some even heavier options that allow for
|
||||
further customization. I am not a fan of viewing code on the web,
|
||||
so you cannot in
|
||||
<a href="https://git.barrettruth.com" target="_blank"
|
||||
>my custom ui</a
|
||||
>. I spin up a simple python server to walk the projects in
|
||||
<code>/srv/git</code> and configured a systemd service to run it
|
||||
in the ec2 box:
|
||||
</li>
|
||||
<div class="code" data-file="git-server-ui.systemd">
|
||||
</div>
|
||||
</ol>
|
||||
<h2>lessons</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<b>It feels great to do things yourself</b>: I used GPT-4o for
|
||||
linux server command help, that was about it
|
||||
</li>
|
||||
<li>
|
||||
<b>Always ask "what is this?" before using something</b>: this
|
||||
would've saved me hours of realizing a 12 year old perl script
|
||||
should not have been running my git ui.
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
<site-footer></site-footer>
|
||||
<script src="/scripts/common.js"></script>
|
||||
<script src="/scripts/post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Git Server UI
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=apache
|
||||
WorkingDirectory=/srv/git/git-server-ui
|
||||
ExecStart=/root/.local/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 --chdir /srv/git wsgi:app
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<VirtualHost *:443>
|
||||
ServerName <servername>
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/<servername>/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/<servername>/privkey.pem
|
||||
|
||||
SetEnv GIT_PROJECT_ROOT /srv/git
|
||||
SetEnv REMOTE_USER $REDIRECT_REMOTE_USER
|
||||
|
||||
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
|
||||
|
||||
<Directory "/usr/libexec/git-core">
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
Require all granted
|
||||
AllowOverride None
|
||||
</Directory>
|
||||
|
||||
<Files "git-http-backend">
|
||||
AuthType Basic
|
||||
AuthName "Git Access"
|
||||
AuthUserFile /srv/git/.htpasswd
|
||||
Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#)
|
||||
Require valid-user
|
||||
</Files>
|
||||
ProxyPassMatch ^/git/ !
|
||||
ProxyPreserveHost On
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
</VirtualHost>
|
||||
2
public/code/software/hosting-a-git-server/gitconfig.git
Normal file
2
public/code/software/hosting-a-git-server/gitconfig.git
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[safe]
|
||||
directory = *
|
||||
Loading…
Add table
Add a link
Reference in a new issue