332 lines
8.5 KiB
Markdown
Executable File
332 lines
8.5 KiB
Markdown
Executable File
---
|
|
title: "Self-Hosting Git with Gitea: Your Own GitHub Alternative"
|
|
description: A comprehensive guide to setting up Gitea - a lightweight, self-hosted Git service that gives you full control over your code repositories.
|
|
pubDate: 2025-04-19
|
|
updatedDate: 2025-04-18
|
|
category: Services
|
|
tags:
|
|
- gitea
|
|
- git
|
|
- self-hosted
|
|
- devops
|
|
- kubernetes
|
|
heroImage: /blog/images/posts/prometheusk8.png
|
|
---
|
|
|
|
If you're a developer like me who values ownership and privacy, you've probably wondered if there's a way to get the convenience of GitHub or GitLab without handing over your code to a third party. Enter Gitea - a painless, self-hosted Git service written in Go that I've been using for my personal projects for the past year.
|
|
|
|
Let me walk you through setting up your own Gitea instance and show you why it might be the perfect addition to your development workflow.
|
|
|
|
## Why Gitea?
|
|
|
|
First, let's talk about why you might want to run your own Git server:
|
|
|
|
- **Complete control**: Your code, your server, your rules.
|
|
- **Privacy**: Keep sensitive projects completely private.
|
|
- **No limits**: Create as many private repositories as you want.
|
|
- **Lightweight**: Gitea runs smoothly on minimal hardware (even a Raspberry Pi).
|
|
- **GitHub-like experience**: Familiar interface with issues, pull requests, and more.
|
|
|
|
I've tried several self-hosted Git solutions, but Gitea strikes the perfect balance between features and simplicity. It's like the Goldilocks of Git servers - not too heavy, not too light, just right.
|
|
|
|
## Getting Started with Gitea
|
|
|
|
### Option 1: Docker Installation
|
|
|
|
The easiest way to get started with Gitea is using Docker. Here's a simple `docker-compose.yml` file to get you up and running:
|
|
|
|
```yaml
|
|
version: "3"
|
|
|
|
services:
|
|
gitea:
|
|
image: gitea/gitea:latest
|
|
container_name: gitea
|
|
environment:
|
|
- USER_UID=1000
|
|
- USER_GID=1000
|
|
- GITEA__database__DB_TYPE=postgres
|
|
- GITEA__database__HOST=db:5432
|
|
- GITEA__database__NAME=gitea
|
|
- GITEA__database__USER=gitea
|
|
- GITEA__database__PASSWD=gitea_password
|
|
restart: always
|
|
volumes:
|
|
- ./gitea:/data
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
ports:
|
|
- "3000:3000"
|
|
- "222:22"
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- gitea
|
|
|
|
db:
|
|
image: postgres:14
|
|
container_name: gitea-db
|
|
restart: always
|
|
environment:
|
|
- POSTGRES_USER=gitea
|
|
- POSTGRES_PASSWORD=gitea_password
|
|
- POSTGRES_DB=gitea
|
|
volumes:
|
|
- ./postgres:/var/lib/postgresql/data
|
|
networks:
|
|
- gitea
|
|
|
|
networks:
|
|
gitea:
|
|
external: false
|
|
```
|
|
|
|
Save this file and run:
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
Your Gitea instance will be available at `http://localhost:3000`.
|
|
|
|
### Option 2: Kubernetes Deployment
|
|
|
|
For those running a Kubernetes cluster (like me), here's a basic manifest to deploy Gitea:
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: gitea-data
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: gitea
|
|
labels:
|
|
app: gitea
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: gitea
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: gitea
|
|
spec:
|
|
containers:
|
|
- name: gitea
|
|
image: gitea/gitea:latest
|
|
ports:
|
|
- containerPort: 3000
|
|
- containerPort: 22
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /data
|
|
env:
|
|
- name: USER_UID
|
|
value: "1000"
|
|
- name: USER_GID
|
|
value: "1000"
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: gitea-data
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: gitea
|
|
spec:
|
|
type: ClusterIP
|
|
ports:
|
|
- port: 3000
|
|
targetPort: 3000
|
|
name: web
|
|
- port: 22
|
|
targetPort: 22
|
|
name: ssh
|
|
selector:
|
|
app: gitea
|
|
```
|
|
|
|
Apply it with:
|
|
|
|
```bash
|
|
kubectl apply -f gitea.yaml
|
|
```
|
|
|
|
## Initial Configuration
|
|
|
|
After installation, you'll be greeted with Gitea's setup page. Here are the settings I recommend:
|
|
|
|
1. **Database Settings**: If you followed the Docker Compose example, your database is already configured.
|
|
|
|
2. **General Settings**:
|
|
- Set your site title (e.g., "LaForceIT Git")
|
|
- Disable user registration unless you're hosting for multiple people
|
|
- Enable caching to improve performance
|
|
|
|
3. **Admin Account**: Create your admin user with a strong password.
|
|
|
|
My configuration looks something like this:
|
|
|
|
```ini
|
|
[server]
|
|
DOMAIN = git.laforce.it
|
|
SSH_DOMAIN = git.laforce.it
|
|
ROOT_URL = https://git.laforce.it/
|
|
DISABLE_SSH = false
|
|
SSH_PORT = 22
|
|
|
|
[service]
|
|
DISABLE_REGISTRATION = true
|
|
REQUIRE_SIGNIN_VIEW = true
|
|
|
|
[security]
|
|
INSTALL_LOCK = true
|
|
```
|
|
|
|
## Integrating with Your Development Workflow
|
|
|
|
Now that Gitea is running, here's how I integrate it into my workflow:
|
|
|
|
### 1. Adding Your SSH Key
|
|
|
|
First, add your SSH key to Gitea:
|
|
|
|
1. Go to Settings > SSH / GPG Keys
|
|
2. Click "Add Key"
|
|
3. Paste your public key and give it a name
|
|
|
|
### 2. Creating Your First Repository
|
|
|
|
1. Click the "+" button in the top right
|
|
2. Select "New Repository"
|
|
3. Fill in the details and initialize with a README if desired
|
|
|
|
### 3. Working with Your Repository
|
|
|
|
To clone your new repository:
|
|
|
|
```bash
|
|
git clone git@your-gitea-server:username/repo-name.git
|
|
```
|
|
|
|
Now you can work with it just like any Git repository:
|
|
|
|
```bash
|
|
cd repo-name
|
|
echo "# My awesome project" > README.md
|
|
git add README.md
|
|
git commit -m "Update README"
|
|
git push origin main
|
|
```
|
|
|
|
## Advanced Gitea Features
|
|
|
|
Gitea isn't just a basic Git server - it has several powerful features that I use daily:
|
|
|
|
### CI/CD with Gitea Actions
|
|
|
|
Gitea recently added support for Actions, which are compatible with GitHub Actions workflows. Here's a simple example:
|
|
|
|
```yaml
|
|
name: Go Build
|
|
on: [push, pull_request]
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.20'
|
|
- name: Build
|
|
run: go build -v ./...
|
|
- name: Test
|
|
run: go test -v ./...
|
|
```
|
|
|
|
### Webhooks for Integration
|
|
|
|
I use webhooks to integrate Gitea with my deployment pipeline. Here's how to set up a simple webhook:
|
|
|
|
1. Navigate to your repository
|
|
2. Go to Settings > Webhooks > Add Webhook
|
|
3. Select "Gitea" or "Custom" depending on your needs
|
|
4. Enter the URL of your webhook receiver
|
|
5. Choose which events trigger the webhook
|
|
|
|
### Mirror Repositories
|
|
|
|
One of my favorite features is repository mirroring. I use this to keep a backup of important GitHub repositories:
|
|
|
|
1. Create a new repository
|
|
2. Go to Settings > Mirror Settings
|
|
3. Enter the URL of the repository you want to mirror
|
|
4. Set the sync interval
|
|
|
|
## Security Considerations
|
|
|
|
When self-hosting any service, security is a top priority. Here's how I secure my Gitea instance:
|
|
|
|
1. **Reverse Proxy**: I put Gitea behind Traefik with automatic SSL certificates.
|
|
|
|
2. **2FA**: Enable two-factor authentication for your admin account.
|
|
|
|
3. **Regular Backups**: I back up both the Gitea data directory and the database daily.
|
|
|
|
4. **Updates**: Keep Gitea updated to the latest version to get security fixes.
|
|
|
|
Here's a sample Traefik configuration for Gitea:
|
|
|
|
```yaml
|
|
apiVersion: traefik.containo.us/v1alpha1
|
|
kind: IngressRoute
|
|
metadata:
|
|
name: gitea
|
|
namespace: default
|
|
spec:
|
|
entryPoints:
|
|
- websecure
|
|
routes:
|
|
- match: Host(`git.yourdomain.com`)
|
|
kind: Rule
|
|
services:
|
|
- name: gitea
|
|
port: 3000
|
|
tls:
|
|
certResolver: letsencrypt
|
|
```
|
|
|
|
## Why I Switched from GitHub to Gitea
|
|
|
|
People often ask me why I bother with self-hosting when GitHub offers so much for free. Here are my reasons:
|
|
|
|
1. **Ownership**: No sudden changes in terms of service affecting my workflow.
|
|
2. **Privacy**: Some projects aren't meant for public hosting.
|
|
3. **Learning**: Managing my own services teaches me valuable skills.
|
|
4. **Integration**: It fits perfectly with my other self-hosted services.
|
|
5. **Performance**: Local Git operations are lightning-fast.
|
|
|
|
## Wrapping Up
|
|
|
|
Gitea has been a fantastic addition to my self-hosted infrastructure. It's reliable, lightweight, and provides all the features I need without the complexity of larger solutions like GitLab.
|
|
|
|
Whether you're a privacy enthusiast, a homelab tinkerer, or just someone who wants complete control over your code, Gitea is worth considering. The setup is straightforward, and the rewards are significant.
|
|
|
|
What about you? Are you self-hosting any of your development tools? Let me know in the comments!
|
|
|
|
---
|
|
|
|
_This post was last updated on January 18, 2024 with information about Gitea Actions and the latest configuration options._ |