Kituwa IT · Self-hosting guides

Install Gitea with Docker Compose

Self-hosted Git forge with built-in CI

gitCIforges

Gitea is a single-binary git forge — repositories, issues, pull requests, wiki, releases, packages, and built-in CI — that you can run on a Pi. It is the sane middle ground between GitHub and running your own Gerrit.

Category
Dev & data
License
MIT
Needs
Postgres (or SQLite)
Image
gitea/gitea

What it is

Push over HTTPS or SSH, get a normal web UI, and let Gitea Actions run your CI from workflow files in .gitea/workflows/. It also serves as an npm, Maven, PyPI and container registry, which quietly removes the need for three more services.

Before you start

  • Decide HTTPS vs SSH-only access. The default is SSH on a non-standard host port (2222), which avoids fighting whatever's already on port 22.
  • For real projects, use Postgres. SQLite is fine for a handful of repos but serialises writes and gets slow in ways that are annoying to diagnose.
  • If you're migrating from GitHub, import repos with gitea dump / the web importer and keep the master → main rename out of the first week.

1 — Create the directories

Command / configuration
mkdir -p ~/services/gitea/{data,pgdata}
cd ~/services/gitea

2 — Write the compose file

Command / configuration
services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    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: CHANGE_ME
      GITEA__server__DOMAIN: git.example.com
      GITEA__server__ROOT_URL: https://git.example.com/
      GITEA__server__SSH_DOMAIN: git.example.com
      GITEA__server__SSH_PORT: 2222
      GITEA__server__START_SSH_SERVER: "true"
      GITEA__server__LFS_START_SERVER: "true"
      GITEA__service__DISABLE_REGISTRATION: "true"
      GITEA__service__REQUIRE_SIGNIN_VIEW: "true"
      GITEA__service__ENABLE_NOTIFY_MAIL: "false"
      GITEA__actions__ENABLED: "true"
    volumes:
      - ./data:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "2222:22"

  db:
    image: postgres:16-alpine
    container_name: gitea-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: CHANGE_ME
      POSTGRES_DB: gitea
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U gitea"]
      interval: 10s
      timeout: 5s
      retries: 5
Env var names are GITEA__section__KEYDouble underscores mean nesting. GITEA__server__ROOT_URL maps to [server] ROOT_URL in app.ini. If a value seems ignored, check the underscores before you assume a bug.

3 — Start it

Command / configuration
docker compose up -d
docker compose logs -f gitea | grep -i "listen\|error"

4 — First-run setup

  1. Register the first user at http://yourhost:3000 — it becomes the admin. Registration is already closed for everyone after that.
  2. Confirm SSH is really working before you rely on it: git remote add origin ssh://git@git.example.com:2222/you/repo.git then git push. A permissions error here almost always means the git user inside the container can't read ./data.
  3. Drop a sample workflow into .gitea/workflows/test.yml and confirm a runner picks it up under Actions. The bundled runner is fine for a home server.
  4. Set up Settings → Repository → Default Branch and turn on branch protection on main so people can't force-push straight to it.

5 — Back it up

Command / configuration
docker exec -u git gitea gitea dump -c /tmp/gitea-dump.zip
# repositories are in ./data/gitea/repositories — back that up too
tar -czf gitea-repos.tgz ./data/gitea/repositories

Help when you need it

Want help getting this running?

We can help with a supported Linux host, application setup, migration or troubleshooting. Contact us to confirm the software, scope and scheduling before ordering.

Related guides

← Browse all 30 guides · Back to top