Gitea is a self-hosted, open-source Git service similar to GitHub, but lightweight, free, and perfect for personal or local setups.
While the official Gitea installation guide is simple, the process you'll see here might seem a bit extra - and that's because I wanted something very specific.
Let's put it this way: I wanted to run my own local github.com, completely offline.
My top priority was to host everything locally on my own network, where the host and client machines could communicate both wirelessly (through a Wi-Fi router) and directly through a LAN cable (peer-to-peer).
I set it up on both Windows and Linux. But let me be real here: if you have the option, use Linux. Windows is a pain in the ass. Often, it feels like fighting the OS instead of working with it.
Honestly, after doing this setup, I hate Windows even more than before - and I already hated it plenty.
That said, I had to do this on both because I use two backup machines - one running Windows 10 and the other Fedora Linux.
Before setting this up, I used to sync data from my main machine (also running Fedora) to those backups using FTP and FileZilla. It worked, but it was tedious - I had to manually track every single change until I synced them.
That's when I thought: why not use Git for this?
I just didn't want anything in the cloud. So setting up my own self-hosted Git server locally made perfect sense.
It's a major security best practice to run services like Gitea under a dedicated user account, not as an administrator/root.
You must be logged in to the administrator user account to perform the following:
-
Press
Win + R, typelusrmgr.msc, and pressEnter. -
Right-click on Users and select New User.
-
Create a user named git.
- Set a strong password.
- Uncheck User must change password.
- Check Password never expires.
-
Click Create then Close.
Now, sign out from the current administrator account and login to the git user account for the rest of the setup.
-
Download and run the installer from the official Git for Windows website.
-
Select the following options during installation:
- Choosing the default editor used by Git: Use the Nano editor by default.
- Adjusting your PATH environment: Git from the command line and also from 3rd-party software.
- Choosing HTTPS transport backend: Use the OpenSSL library.
- Configuring the line ending conversions: Checkout Windows-style, commit Unix-style line endings.
- Configuring the terminal emulator to use with Git Bash: Use MinTTY (the default terminal of MSYS2).
- Choose the default behaviour of
git pull: Only ever fast-forward. - Choose a credential helper: Git Credential Manager.
- Finish the installation.
-
Create a folder for Gitea, e.g.,
C:\gitea. -
Find the latest version for your OS type here. Usually it's
amd64, so the one you need would be:gitea-<version>-gogit-windows-4.0-amd64.exe. -
Download it and place it in the
C:\giteafolder. -
Rename the file to
gitea.exe.
This will start Gitea server automatically on boot.
-
Create a service
Open Git Bash (Run as administrator) and run:
sc create gitea binPath= "C:\gitea\gitea.exe web --config C:\gitea\custom\conf\app.ini" start= auto(We'll use Git Bash as our default terminal to run commands in this entire guide, but only Run as administrator when mentioned explicitly).
-
Press
Windowskey and search for Services, right-click it and select Run as administrator. -
Search for the service named gitea, right-click it and click on Properties.
-
Go to the Log On tab → select This account → click Browse...
- Type your Windows username (i.e., git) → click Check Names → click OK.
- Enter the password you set for the git user twice.
-
Go to the Recovery tab
- For First failure, select Restart the Service (do the same for Second failure and Subsequent failures as well).
- Set Reset fail count after value to
0days. - Set Restart service after value to
1minutes. - Close the window by clicking OK.
-
Right-click on the gitea service again and click Start.
Important
In case, the service does not auto-start on boot, run the following command as mentioned here:
sc config gitea start= delayed-autoGo to http://localhost:3000 on your browser and you'll be presented with an Initial Configuration page from Gitea.
We'll use the bare minimum configuration at this point and leave the advanced configuration for the later steps:
- Database Type: SQLite3
- Site Title: GitShah (use whatever name you want or keep the default one)
- Check Enable Update Checker
- Click Install Gitea
Wait until the installation finishes and redirects you to the Register page.
Do not register for now and close the browser's tab.
-
For LAN
We'll have to set a static IP on both the client and server machines, which, in my case, is Fedora and Windows, respectively.
Follow the Configure Network Settings section from here for each machine.
-
For WiFi
In the case of WiFi, you only need to set a static IP on the server machine.
First you need to find your WiFi router's IP using the command:
ipconfig | grep Default.Let's assume it's
192.168.100.1like below:$ ipconfig | grep Default Default Gateway . . . . . . . . . : 192.168.100.1
which means, you can use the static IP within the same range e.g.,
192.168.100.x, wherexcould be any number from2to254.Just to be consistent with my server's LAN IP, I'll be using
192.168.100.7.Follow the same Configure Network Settings > On Windows 10 section from here, but right-click on the Wi-Fi adapter instead of Ethernet and enter the following values under Internet Protocol Version 4 (TCP/IPv4) > Properties:
IP address: 192.168.100.7 Subnet mask: 255.255.255.0 Default gateway: 192.168.100.1 Preferred DNS server: 192.168.100.1
For the domain, I'll be using gitshah.com, use whatever you like.
-
On WiFi router
Login to your WiFi router's admin panel and find the Static DNS (or similar) settings and add:
gitshah.com → 192.168.100.7 www.gitshah.com → 192.168.100.7For example, my Huawei Router has below settings:
-
On Windows server machine
Open Git Bash (Run as administrator) and run:
nano /c/Windows/System32/drivers/etc/hosts
Add line:
127.0.0.1 gitshah.com www.gitshah.com
Save and close the file (
Ctrl+X,Y,Enter). -
On Fedora client machine
Since we want
gitshah.comto be accessible on both LAN and WiFi - and we prefer LAN (because it's faster and has lower latency) when both are connected - we'll add both IPs in the/etc/hostsfile like this:192.168.200.7 gitshah.com www.gitshah.com # via LAN 192.168.100.7 gitshah.com www.gitshah.com # via WiFi
Now here's where it gets annoying: some applications and browsers (like Google Chrome) only use the first occurrence of a domain in
/etc/hostsand completely ignore any subsequent entries for the same domain. Others - likecurl,ping, or even Firefox - are smarter and just work fine.This means that in our case,
gitshah.comwill only resolve via LAN, since it's listed first.One way to handle this is to keep the LAN line commented out by default and manually toggle it - uncomment when LAN is connected, comment when it's not. Works fine, but it's repetitive and annoying as hell.
Another approach is to use something like mDNS (
dnsmasqor similar), but that's way too much machinery for something this simple. It adds multiple moving parts, and you'll have to modify each connection profile too. That's just not worth it for a small local setup like this.Personally, I think sticking with the plain old
/etc/hostsfile is far simpler and works right out of the box. If you're using Firefox, just keep both entries uncommented - it'll resolve whichever connection is active, no complaints.But if you're stuck with Google Chrome (like me), you'll quickly realize how much of a pain it is to manually toggle those entries every time your LAN cable connects or disconnects.
So yeah, we'll automate this with a simple NetworkManager dispatcher script - it's straightforward, reliable, and doesn't depend on any specific app or browser behavior.
-
Add domain mapping in
/etc/hostsOpen the file:
sudo nano /etc/hosts
Add:
#192.168.200.7 gitshah.com www.gitshah.com # via LAN 192.168.100.7 gitshah.com www.gitshah.com # via WiFi
It's important to keep the order of the IPs as above to try LAN first if it's connected.
-
Create a dispatcher script
Create a new shell script:
sudo mkdir -p /etc/NetworkManager/dispatcher.d sudo nano /etc/NetworkManager/dispatcher.d/99-gitshah-lan-monitor.sh
Put this inside:
#!/bin/bash IFACE="$1" STATE="$2" HOSTS_FILE="/etc/hosts" LAN_MARKER="via LAN" if [ "$IFACE" = "enp0s31f6" ]; then case "$STATE" in up) # Enable LAN line (remove #) sed -i "/$LAN_MARKER/s/^#//" "$HOSTS_FILE" logger -t gitshah-lan-monitor "LAN is UP → enabled LAN entry in $HOSTS_FILE" ;; down) # Disable LAN line (add # at start) sed -i "/$LAN_MARKER/s/^/#/" "$HOSTS_FILE" logger -t gitshah-lan-monitor "LAN is DOWN → disabled LAN entry in $HOSTS_FILE" ;; esac fi
Replace
enp0s31f6with your LAN interface (ip linkwill tell you).Make it executable:
sudo chmod +x /etc/NetworkManager/dispatcher.d/99-gitshah-lan-monitor.sh
-
Restart NetworkManager
sudo systemctl restart NetworkManager
Now, every time your LAN interface (i.e.,
enp0s31f6, in my case) goes up or down, NetworkManager will automatically toggle (uncomment/comment) the line ending withvia LANin/etc/hosts.You can also see the messages in your logs whenever the script triggers:
journalctl -t gitshah-lan-monitor
-
Open Git Bash and run the following commands:
-
Create a Root CA
Create a private key for your CA:
openssl genrsa -out gitshahCA.key.pem 4096
Create a self-signed CA certificate (valid 10 years):
openssl req -x509 -new -nodes -key gitshahCA.key.pem -sha256 -days 3650 \ -out gitshahCA.cert.pem \ -subj "/C=PK/ST=Sindh/L=Karachi/O=GitShahCA/OU=Dev/CN=GitShah Root CA" -
Create a Server Key + CSR
Make a server private key:
openssl genrsa -out gitshah.key.pem 2048
Make a config file for your SANs:
# Open a new file nano san.cnf # Paste the following, then save and close the file [req] default_bits = 2048 default_md = sha256 prompt = no distinguished_name = req_distinguished_name req_extensions = req_ext [req_distinguished_name] CN = gitshah.com [req_ext] subjectAltName = @alt_names [alt_names] DNS.1 = gitshah.com DNS.2 = www.gitshah.com
Generate a certificate signing request (CSR):
openssl req -new -key gitshah.key.pem -out gitshah.csr.pem -config san.cnf
-
Sign the CSR with your Root CA
openssl x509 -req -in gitshah.csr.pem -CA gitshahCA.cert.pem -CAkey gitshahCA.key.pem \ -CAcreateserial -out gitshah.cert.pem -days 3650 -sha256 -extfile san.cnf -extensions req_ext
While still in the Git Bash from the previous step, run the following commands:
-
Copy the Certificate and Key Files
mkdir /c/gitea/custom/https cp gitshah.cert.pem gitshah.key.pem /c/gitea/custom/https
-
Update
app.iniOpen the file:
nano /c/gitea/custom/conf/app.ini
Go to the
[server]block and add/modify the following:PROTOCOL = https CERT_FILE = C:/gitea/custom/https/gitshah.cert.pem KEY_FILE = C:/gitea/custom/https/gitshah.key.pem DOMAIN = gitshah.com HTTP_PORT = 443 ROOT_URL = https://gitshah.com/ START_SSH_SERVER = true SSH_DOMAIN = gitshah.com SSH_PORT = 2222
Save and close the file (
Ctrl+X,Y,Enter). -
Restart the Service
Open a new Git Bash (Run as administrator) and run:
sc stop gitea sc start gitea
(Or you can open the Services application as an administrator, find and right-click on your gitea service and then click Restart).
-
On Windows server machine
- Press
Windowskey → typemmc→ right-click on it and select Run as administrator → enter admin password (if prompts) then click Yes. - Go to File → Add/Remove Snap-in.
- Select Certificates from Available snap-ins (left-pane) → click Add → select Computer account → Local computer → click Finish then OK.
- Expand Certificates (Local Computer) → expand Trusted Root Certification Authorities → right-click Certificates.
- Select → All Tasks → Import.
- Import your CA certificate (gitshahCA.cert.pem) → click Next.
- Keep Place all certificates in the following store selected and make sure Certificate store has Trusted Root Certification Authorities selected.
- Complete the wizard.
- Press
-
On Fedora client machine
-
Install Root CA into Fedora trust store
sudo cp gitshahCA.cert.pem /etc/pki/ca-trust/source/anchors/ sudo update-ca-trust
-
Verify
curl -v https://gitshah.com
If your service is running with that cert,
curlshould connect without complaining about an untrusted certificate.
-
-
Restart your browser to apply.
Now, you should be able to access your Gitea server web interface using both https://gitshah.com and https://www.gitshah.com.
When you register your first account - it becomes admin.
-
Go to https://gitshah.com and click on the Register button on the top-right corner and register an account.
-
After you're signed in, click on your username on the top-right corner, click Settings > Profile > find User visibility option and set it to Private.
We'll only use the admin account for Gitea server management or if there's a need to manage other users and their repositories - but we won't create repositories/organizations from this account.
For a regular use, we'll register a user account, just like you would on GitHub/GitLab, and then create and manage repositories/organizations, etc.
Optional:
-
After you're signed in, if you configured optional mailer settings yourself in the fifth step (Initial Gitea Configuration) above, you can activate your account by clicking on your username on the top-right corner, click Settings > Account > under Manage Email Addresses section, click Send Activation.
-
You'll receive an activation link on your email (check spam if not), but it may not activate your account when you are already signed in (it's a bug on Gitea's end), so you'll have to sign out first and then use the activation link to activate your account.
See the official documentation for the recommended way of updating to a new version, which includes creating a backup before updating, otherwise, follow the steps below:
Open Git Bash (Run as administrator) and run:
-
Stop the service
sc stop gitea
-
Upgrade Gitea binary
- Find the latest version for your OS type here, as you did in the third step (Download Gitea) above.
- Download it and rename the file to
gitea.exe. - Replace the existing
gitea.exein theC:\giteafolder with the new one.
-
Start the service
sc start gitea
For troubleshooting purposes, you can see live Gitea logs using the following:
-
Update Gitea configuration
# Open Gitea config file nano /c/gitea/custom/conf/app.ini # Go to the [log] block and change `MODE` from `console` to `file` MODE = file
Save and close the file (
Ctrl+X,Y,Enter). -
Restart the service
Open Git Bash (Run as administrator) and run:
sc stop gitea sc start gitea
-
See live logs
tail -f /c/gitea/log/gitea.log
As per the documentation, the default max size of each file is 50 MB and 5 files per upload.
Note
This only applies to the file upload via the Gitea's web interface and not push via command-line - it has no limit.
To increase these limits:
-
Update Gitea configuration
# Open Gitea config file nano /c/gitea/custom/conf/app.ini # Add the following [repository.upload] FILE_MAX_SIZE = 10240 # 10 GB per file MAX_FILES = 20000 # 20,000 files per upload
Save and close the file (
Ctrl+X,Y,Enter). -
Restart the service
Open Git Bash (Run as administrator) and run:
sc stop gitea sc start gitea
The following are some of the repository settings I like to have for an ease of use. See the full list here.
-
Update Gitea configuration
# Open Gitea config file nano /c/gitea/custom/conf/app.ini # Go to the [repository] block and add the following DEFAULT_BRANCH = master # Default branch name of all repositories. DEFAULT_PUSH_CREATE_PRIVATE = false # Default private when creating a new repository with push-to-create. ENABLE_PUSH_CREATE_USER = true # Allow users to push local repositories to Gitea and have them automatically created for a user. ENABLE_PUSH_CREATE_ORG = true # Allow users to push local repositories to Gitea and have them automatically created for an org.
Save and close the file (
Ctrl+X,Y,Enter). -
Restart the service
Open Git Bash (Run as administrator) and run:
sc stop gitea sc start gitea