Self-Hosted Git Server with Gitea: Manage Your Embedded Projects Locally

Self-Hosted Git Server with Gitea: Manage Your Embedded Projects Locally

Excerpt: Tired of pushing your firmware code to public Git repositories or relying on cloud services like GitHub and GitLab? Hosting your own Git server with Gitea is a lightweight, privacy-friendly solution that fits perfectly in your home server environment. In this guide, we’ll walk through how to self-host Gitea using Docker on an Ubuntu-based home server—ideal for embedded developers working on ESP32, STM32, or nRF52 firmware projects.


Why Self-Host a Git Server for Embedded Projects?

Whether you're developing firmware for a smart home sensor, custom industrial controller, or prototyping IoT devices, version control is essential. But:

  • You may want full control and privacy over your firmware code.
  • You might be working in an air-gapped environment.
  • Or maybe you just want to learn and experiment with DevOps on your own terms.

That’s where Gitea shines—an open-source, painless, fast, and lightweight GitHub/GitLab alternative that works great even on low-powered machines.


What You’ll Need

  • A PC or laptop running Ubuntu Server or Desktop
  • Docker and Docker Compose installed
  • A stable local network or home server environment
  • Optional: A domain name for easier access

Step 1: Install Docker and Docker Compose

First, make sure Docker is installed by following official documentation

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo usermod -aG docker $USER

Log out and back in to apply group changes.


Step 2: Create Gitea Docker Setup

Create a directory for your Gitea setup:

mkdir -p ~/docker/gitea
cd ~/docker/gitea

Create the following docker-compose.yml file:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
       - USER_UID=1000
       - USER_GID=1000
    restart: always
    volumes:
       - ./gitea:/data
    ports:
       - "3000:3000"   # Web interface
       - "222:22"      # SSH for Git
    networks:
       - gitea

networks:
  gitea:
    driver: bridge

Step 3: Launch Gitea

Run:

docker compose up -d

Then open your browser and go to http://<your-server-ip>:3000

You should see the Gitea installation screen.


Step 4: Gitea Initial Configuration

Fill in the following fields:

  • Database Type: SQLite (simple setup) or MySQL/PostgreSQL if you prefer
  • Repository Root Path: /data/git/gitea-repositories
  • SSH Server Domain: <your-server-ip>
  • SSH Port: 222
  • Gitea HTTP Port: 3000
  • Log Path: /data/log

Admin user:

  • Pick a username like admin
  • Choose a secure password and enter your email

Click Install Gitea.


Step 5: Create a Repository

  • Login as admin
  • Click on New Repository
  • Name it (e.g., esp32-sensor)
  • Choose Private if you don’t want it public
  • Add a .gitignore and README.md if needed

Step 6: Clone and Push Your Embedded Project

On your development machine (e.g., laptop or VS Code environment):

git clone ssh://git@<your-server-ip>:222/yourusername/esp32-sensor.git
cd esp32-sensor

Then add your firmware source code, commit, and push:

git add .
git commit -m "Initial commit"
git push origin main

Step 7: Configure SSH Keys for Secure Access

On your client/dev machine:

ssh-keygen -t ed25519

Copy the contents of ~/.ssh/id_ed25519.pub, then:

  • Log in to Gitea
  • Go to Settings → SSH / GPG Keys
  • Paste and save the public key

Now you can push/pull without entering a password.


Step 8: Backups and Data Persistence

All data is stored in the ~/docker/gitea/gitea directory:

  • Repositories
  • User data
  • Configuration

You can create backups using tar or a dedicated volume snapshot system:

tar -czf gitea-backup-$(date +%F).tar.gz ~/docker/gitea/gitea

Consider backing up this to an external drive or remote server.


Bonus: Access Gitea with a Domain Name

If you have a domain name (e.g., git.mylab.local) and run a reverse proxy (like Nginx or Caddy), you can expose Gitea securely with HTTPS.

For example, with Caddy:

git.mylab.local {
    reverse_proxy localhost:3000
}

This way you can access https://git.mylab.local from any device on your network.


Use Cases for Embedded Projects

  1. Collaborate with teammates on firmware projects.
  2. Host OTA update binaries as release artifacts.
  3. Track hardware-specific branches for ESP32, STM32, and NRF52.
  4. Integrate with CI tools to build and test firmware automatically.
  5. Keep your IP secure without relying on third-party cloud services.

Conclusion

Self-hosting a Git server using Gitea is an excellent way to modernize your embedded development workflow. It gives you control, privacy, and flexibility—all while running efficiently on your Ubuntu home server using Docker.

Next up, we’ll explore integrating Gitea with CI pipelines to automatically build firmware for ESP32 and STM32 using PlatformIO, ESP-IDF, or STM32CubeIDE.