What actually is Git? For many developers it's synonymous with Github, Gitlab or that internal Bitbucket instance you have to deal with that only half works.
Funnily enough, it's simpler than that. It's a tool to interact with some specific folder structures and file specifications to allow you to version control your files that can live anywhere. Yes, you can have remote repos stored in Dropbox if you really wanted to! You don't need Github, Gitlab, Bitbucket, self-hosted Gitea or any of that. You can keep it simple and that's what I wanted to do.
The Setup
Raspberry Pi 3B+
my NAS
Hetzner VPS
https://tangled.org
Simple right?!?
Ok, there's a lot more going on than just chucking all of your code on Github here, but the concepts are simple.
The big picture
I wanted to keep my private repos really private and feel like I have data ownership over my public repositories so they never leave my local network.
My public repositories get pushed to a VPS that hosts a Tangled Knot.
The Raspberry Pi
This is my source of truth for all of my code public and private. It's the main storage for all of my repositories.
The setup is simple! A user account named git that uses git shell and some git-shell-command scripts that make my life easier and a simple global git hook for my public repositories.
One of my requirements when I set out to start this was that I wanted to make it as easy as possible to setup new repositories that can either be public or private.
I played with a bunch of solutions, but ultimately landed on ssh git@pi new-repo
What the hell is that command? It's one of my git-shell-commands that gives me an interactive prompt to create a new repo public or private.
#!/bin/bash
# this script allows the creation of new repos over ssh on git server
# public repos will get a knot.conf containing the remote
# private repos will just exist on the server
# USAGE:
# ssh git@<host> new-repo
# - follow the prompts
echo "oh look you are starting a project you won't finish again."
echo "What is your projects name?"
read PROJECT_NAME
if [[ $PROJECT_NAME!=*.git ]]; then
PROJECT_NAME="${PROJECT_NAME}.git"
fi
echo "What's the mirror repo remote url?(leave blank if private)"
read REMOTE_URL
git --bare init "${PROJECT_NAME}"
if [[ $REMOTE_URL ]]; then
touch "${PROJECT_NAME}/knot.conf"
echo "${REMOTE_URL}" >> "${PROJECT_NAME}/knot.conf"
fi
echo "git url: ${USER}@${HOSTNAME}:${PROJECT_NAME}"
if [[ $REMOTE_URL ]]; then
echo "public repo: ${REMOTE_URL}"
fi
#vim: filetype=bashThis script creates the git bare repo. If it's a public repo it creates a knot.conf file that simply contains the remote repository URL so the global post-receive hook can mirror the repository.
The other big requirement was backups. No one wants to lose their code! I toyed around with a few ideas here but ultimately landed on mounting an NFS share and creating cron jobs to do hourly rsync backups and daily gzip of the hourly backups.
# m h dom mon dow command
0 * * * * rsync -avH --delete /home/git/*.git /mnt/backup/hourly
30 0 * * * tar -czf /mnt/backup/daily.`date +\%u`.tar.gz /mnt/backup/hourlyThe NAS - for backups
My NAS mainly houses back-ups and Minecraft at the moment, so it was a great candidate for back-ups. I'll probably kick myself down the road for not having some robust 3-2-1 backup solution. However, this feels strong enough.
All of my repos live on my laptop, my PC, the pi and backed up to 2 MIRRORED 6TB hard drives in my NAS. If EVERY one of those fails at the same time, I feel like I deserved it. All of my public repos are further mirrored on a VPS running a Tangled Knot.
git.treybastian.com (knot.treybastian.com)
The final piece of the puzzle. Somewhere to host the public code, that no one really cares about, but if someone stumbles upon it they can use it freely, well, license depending. I think everything is MIT though so fairly freely.
Tangled like most open source projects makes it really easy to self host their knot server if you have a little knowledge of Docker, which most people these days who are wanting to self-host do.
I have to be difficult. I don't use Docker on my VPS's I find it a little heavier than I necessarily need. I've run lots of Docker in production and it is helpful when you need it, I just don't need it at the moment.
Lucky the documentation that I've now linked 3 times in this post has instructions for manual setup. They are super awesome and even include the systemd service config to make it super painless.
https://tangled.org/treybastian.com
But... hey wait a minute, that screenshot shows something else??
Why yes, yes it does. I setup Cgit too because I like it! It's not necessary by any means. Heck even this tangled knot server isn't necessary if you want to use tangled you can use their knot. That's the power of the atproto ecosystem.
Thank you for reading, writing like this is fairly new to me so I'd appreciate any and all feedback you have for me in the comments.