(WRITING): Working on the new article for Gitea.

Just missing the last step about Cloudflared. That will be a long one.
This commit is contained in:
Hayden Hargreaves 2025-05-21 22:32:52 -07:00
parent 1178d77ba1
commit 2563dc3ce3
2 changed files with 343 additions and 0 deletions

View File

@ -0,0 +1,343 @@
Date: 2025/05/??
Desc: Rolling your own version control is not as hard as it sounds. This step by step guide will take you from 0 to 60!
# Self Hosted Git Server: How to
<img src="/journal/gitea-logo.png" alt="Jet Brains Logo" style="background-color: white; border-radius: 15px; padding: 10px; margin-inline: 10px; margin-block: 2.5%; max-width: 300px; max-width: 95%;">
<br>
###### Author: Hayden Hargreaves
###### Published: 05/??/2025
## Background
Version control is one the most powerful tools used by develops, and Git is the most widely adopted
"flavor" **version control system** (vsc). However, when it comes to hosting Git, everyone does it a
little differently. Most people use **[GitHub](https://github.com)** or even [GitLab](https://about.gitlab.com). Large companies typically host their
own for an added layer of safety and security. That is exactly what this guide will cover, on a smaller
scale of course!
But before we dig into the details, what exactly does it mean to *roll your own version control* or *host
your own git server*? Well its simple, we are going to use a server of our own to deploy an application
that serves as a web-UI and *hub* for our Git repositories. Before you freak out, we are not going to
actually write any code or build the application, there are countless open-source options available for
**free** that "home-labbers" such as myself. In this guide, we will be using [Gitea](https://about.gitea.com) due to its ease of use
and strong support.
*NOTE: As an added benefit, it was written in Go and is accepting contributions!*
## Requirements
There are only a few things you will need to roll your own Git server. The most important is a server, duh!
This can be a virtual private server (VPS), an EC2 instance from AWS, or your own hardware. Whatever you have
will work, but my recommendation is to purchase your own hardware. I have a large server built of old gaming
PC parts, but even a simple **[Raspberry Pi](https://www.raspberrypi.com)** will due!
Once you have a server and root access (you will need to create and modify a user) you are about 99% there!
I assume that because you are reading this you have a personal computer. You will need SSH access to your
server via a personal computer. This article will walk you through using **[Ansible](https://docs.ansible.com)** to configure your
server (which requires SSH access). **This guide assumes you are using a Debian or Ubuntu based Linux distro.**
Finally, the last "requirement" is optional, but highly recommended: a personal domain and a [Cloudflare](https://www.cloudflare.com)
account. Regardless of whether you have a domain or not, you will be able to access your Git server from
your local network. But, if you want access remotely securely, it is best to get your hands on a domain.
Using Cloudflare allows us access to their [tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/) which will allow us to expose local ports safely.
More details regarding these tunnels will come later.
*NOTE: There are other ways to access your server remotely without Cloudflare tunnels, but I will not cover that here.*
## Preview
Before continuing, please make sure you have everything you need to get started. Following these steps,
**in order** will allow you to go from 0 to self hosting your server with relative ease!
1. **Install docker-compose:** We will be running the server in a docker container
2. **Create the *git* user:** Creating a new user will allow you to access the server using the git user
3. **Configure docker-compose:** This is the easiest way to install Gitea
4. **Configure the server:** The server can be configured via the web UI
5. **Configure SSH access:** The magic begins to happen here
6. **Install Cloudflared and setup DNS routing:** This is the final step that ties the bow on the whole system
### Disclaimer
It is assumed that you already have a basic understanding of Ansible and have a basic config setup. As this
is not an Ansible guide, I will not go into much detail there. However, many of these commands are easy to
understand and can be used as normal shell commands.
For those who have ansible already configured on their system, we will be using the common **roles** pattern for
directories and files. A directory structure that looks something like this will yield the best results:
```bash
.
├── ansible.cfg
├── inventory
│   ├── group_vars
│   │   └── main.yml
│   ├── hosts.yml
│   └── host_vars
│   └── gophernest.yml
├── playbooks
│   ├── common_setup.yml
│   └── docker_apps.yml
├── requirements.yml
└── roles
├── cloudflared
│   ├── files
│   │   ├── 3c522d3a-5f24-4645-b4ca-695c66e05ef3.json
│   │   ├── cert.pem
│   │   └── cloudflared
│   ├── handlers
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   ├── templates
│   │   └── config.yml.j2
│   └── vars
│   └── main.yml
├── docker
│   ├── handlers
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   └── vars
│   └── main.yml
└── git
   ├── README.md
   ├── tasks
   │   └── main.yml
   ├── templates
   │   └── docker-compose.yml.j2
   └── vars
   └── main.yml
```
File paths will be provided at each step, if you are following along, you can use the structure above to create
an exact copy. **RECOMMENDED!**
<br>
## Install Docker Compose
The first requirement is to ensure that docker compose is installed. This can be done by updating the
`roles/docker/tasks/main.yml` file to contain the following task.
```yaml
# roles/docker/tasks/main.yml
...
- name: Install Docker Compose
get_url:
url: https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 # Modify system accordingly
dest: /usr/local/bin/docker-compose
mode: '0755'
become: true
tags:
- docker
- compose
```
Also, make sure you have a working installation of Docker on your system. Those not using Ansible can reference
the [docs](https://docs.docker.com/compose/install/) which provide a distro-specific installation guide.
You can test that this has worked successfully by running the docker compose command:
```bash
docker-compose --version
```
<br>
## Create the Git User
Now its time to create the user that will handle the server and manage the data. It is best practice to create
a new user with permission only for this application, to follow the [principal of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege). This can
be done very easily by updating the `roles/git/tasks/main.yml` file to contain the following tasks:
```yaml
# roles/git/tasks/main.yml
...
- name: Create git user
user:
name: git
password: "{{ GIT_USER_PASSWORD }}"
shell: /bin/bash
state: present
become: true
tags:
- git
- user
- name: Add git user to the required groups
user:
name: git
groups: sudo,docker
append: yes
state: present
become: true
tags:
- git
- groups
```
The password can be set directly here, or you can update the `roles/git/vars/main.yml` file to contain an entry
for the password. Ansible knows to look here when we use the syntax provided above.
```yaml
# roles/git/vars/main.yml
...
GIT_USER_PASSWORD: "super secret password" # use `mkpasswd -m sha-512 'password'`
```
For non Ansible users, this can be done with the typical Linux commands:
```bash
useradd -m -s /bin/bash git
passwd git
usermod -aG sudo git
usermod -aG docker git
```
<br>
## Configure Docker Compose
We will now create the required docker-compose file to start the application. The file should be placed in the
new *git* users home directory, `/home/git/docker-compose.yml`. This can be done with a single task in the same
playbook as previous.
```yaml
# roles/git/tasks/main.yml
...
- name: Copy docker-compose file to the server
template:
src: docker-compose.yml.j2
dest: /home/git/docker-compose.yml
owner: git
group: git
mode: "0644"
become: true
tags:
- git
- docker
```
In order for this to work, we must also provide the `docker-compose.yml.j2` file in the `templates` directory.
```yaml
# roles/git/templates/docker-compose.yml.j2
networks:
gitea:
external: false
services:
server:
image: docker.gitea.com/gitea:1.23.8
container_name: gitea
environment:
- USER=git
- USER_UID=1001 # As the git user, run `id` to get UID and GID values
- USER_GID=1002
restart: always # Allows the container to start when the server boots
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "4000:3000"
- "222:22" # Adjust the host ports as necessary, host:container
```
To do this manually, simply create a file `/home/git/docker-compose.yml` with the content in the above template.
## Configure the Server
We will use the Gitea web-UI to configure the server, but first we must start the server. With ansible, we can
create the following task in the same location as the previous tasks (starting to notice a trend I hope).
```yaml
# roles/git/tasks/main.yml
...
- name: Start Docker compose application
community.docker.docker_compose_v2:
files: /home/git/docker-compose.yml
project_src: /home/git
state: present
pull: always
become: true
tags:
- git
- start
```
Or you can run the docker compose command from the git users home directory `/home/git`:
```bash
docker-compose up -d # Use -d if you want it to run in the background, as a daemon
```
Now you can access our server locally using the local address of your server on port 4000 (or whatever you set
in the docker compose file). For example, `http://192.168.1.2:4000`. You should see a configuration wizard, if
so, you are almost done!
Feel free to customize these settings as you see fit, but ensure you follow the provided directions.
- Do not change the port's, http or ssh, these are internal ports! To change the external ports, update the hosts
ports in the docker container.
- Leave the user as git, we set this up for a reason!
- Disable the **self registration** toggle in the advanced settings section (at the bottom).
<br>
## Configure Local Access
Your Git server is live! You have made it through the hardest part, the rest is easy. Access your server via HTTP
works but it's not the best but it works. So, now we will configure our local system to use [SSH key authentication](https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server).
First you will need an SSH key, but I will leave that up to you to figure out.
Once you have your key, you need to add it to your Gitea server. The process is very similar to added an SSH key to
GitHub, **Settings > SSH/GPG Keys > Add Key**. Then paste the content of your `*.pub` file into the content field.
Finally, we need to configure our local machine to use this key when we access our Git server. Update your `.gitconfig`
file to contain an entry similar to this:
```sshconfig
Host gitea # Update as needed
Port 222 # Update as needed
User git
HostName 192.168.1.2 # Use your address here, we will change this later
IdentityFile ~/.ssh/key
```
Much of these details will change when we setup our server to run on our domain, but for now, give them a try
and adjust them accordingly.
When you attempt to clone a repo (for example) you will use the URL:
```bash
git clone git@gitea:<username>/<repo>.git
```
Notice, we use **gitea** here as the host. Since this is how we configured our config to route to our server.
<br>
#### Side Note: Local Access
If you would only like access to this server from your local network then you can stop at this step.
<br>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB