Installing Gitea on Docker

What is Gitea?

Gitea is a painless self-hosted Git service and probably the most lightweight alternative to GitHub, GitLab and other similar platforms. A self-hosted solution for developers and teams seeking total control over their repos — Add more privacy to your code management with Gitea. Gitea provides an issue tracking system, pull requests management and with such clean interface it makes a faster development. Gitea has got you covered, whether you're working in isolation or as part of a much larger team

NOTE

All the code blocks you are about to see are docker-compose.yml
The different chapters will add code (labeled with +) and remove code (labeled with -)
The base code that will be used is the one from the Basics chapter

Installation with Docker (rootless)

Gitea maintains automatically updated Docker Images under its Docker Hub Organization. You could always use latest stable tag or just another service update up the docker images.

The rootless image offers Git protocol through Gitea internal SSH and does not use OpenSSH.

This reference setup walks users through via docker-compose but the installation of docker-compose is out of the scope of this documentation.
You can check our Docker and Portainer guide here.

Basics

The simplest setup creates a volume and a network and starts the gitea/gitea:latest-rootless image as a service. Since there is no database available, one can be initialized using SQLite3.

Create a directory for data and config:

mkdir -p gitea/{data,config}
cd gitea
touch docker-compose.yml

Then paste the following content into a file named docker-compose.yml:

version: "2"

services:
  server:
    image: gitea/gitea:1.22.3-rootless
    restart: always
    volumes:
      - ./data:/var/lib/gitea
      - ./config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:2222"
Note that the volume should be owned by the user/group with the UID/GID specified in the config file. By default Gitea in docker will use uid:1000 gid:1000. If needed you can set ownership on those folders with the following command
  • sudo chown 1000:1000 config/ data/
Not providing the right permissions to the volume can cause the container to not start.

For a stable release version you may use :latest-rootless, :1-rootless or a specific version such as :1.22.3-rootless but in case you are interested in the newest development version, :nightly-rootless would be the appropriate tag. In case you would like to run the last commit from a release branch you may use :1.x-nightly-rootless tag, where x is the minor version of Gitea. E.g. :1.16-nightly-rootless.

Custom Port

To bind the integrated SSH and the web server to a different port, modify the port section. It's typical to only change the host port while keeping the container ports unchanged:

version: "2"

services:
  server:
    image: gitea/gitea:1.22.3-rootless
    restart: always
    volumes:
      - ./data:/var/lib/gitea
      - ./config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "80:3000"
      - "22:2222"

MySQL database

To start both Gitea and MySQL apply these changes.We are adding the gitea database and creating the gitea user:

version: "2"

services:
  server:
    image: gitea/gitea:1.22.3-rootless
     environment:
       - GITEA__database__DB_TYPE=mysql
       - GITEA__database__HOST=db:3306
       - GITEA__database__NAME=gitea
       - GITEA__database__USER=gitea
       - GITEA__database__PASSWD=gitea
    restart: always
    volumes:
      - ./data:/var/lib/gitea
      - ./config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:2222"
     depends_on:
       - db
 
   db:
     image: mysql:8
     restart: always
     environment:
       - MYSQL_ROOT_PASSWORD=gitea
       - MYSQL_USER=gitea
       - MYSQL_PASSWORD=gitea
       - MYSQL_DATABASE=gitea
     volumes:
       - ./mysql:/var/lib/mysql

PostgreSQL database

Same thing as above but with PostgresQL instead. We are adding the gitea database and creating the gitea user.

version: "2"

services:
  server:
    image: gitea/gitea:1.22.3-rootless
    environment:
       - GITEA__database__DB_TYPE=postgres
       - GITEA__database__HOST=db:5432
       - GITEA__database__NAME=gitea
       - GITEA__database__USER=gitea
       - GITEA__database__PASSWD=gitea
    restart: always
    volumes:
      - ./data:/var/lib/gitea
      - ./config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:2222"
     depends_on:
      - db
 
   db:
     image: postgres:14
     restart: always
     environment:
       - POSTGRES_USER=gitea
       - POSTGRES_PASSWORD=gitea
       - POSTGRES_DB=gitea
     volumes:
       - ./postgres:/var/lib/postgresql/data
Change the user and passowrd to something personalized and secure.

Named volumes

To utilize named volumes instead of host volumes, specify and use the named volume in the docker-compose.yml configuration. This adjustment will automatically create the necessary volume. You won't have to concern yourself with permissions when using named volumes; Docker will handle that for you.

version: "2"

 volumes:
   gitea-data:
     driver: local
   gitea-config:
     driver: local

services:
  server:
    image: gitea/gitea:1.22.3-rootless
    restart: always
    volumes:
      - gitea-data:/var/lib/gitea
      - gitea-config:/etc/gitea
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:2222"
MySQL or PostgreSQL containers will need to be created separately.

Startup

From July 2023 Compose V1 stopped receiving updates. It's also no longer available in new releases of Docker Desktop.

Compose V2 is included with all currently supported versions of Docker Desktop. Please use V2 to do below operations.

To launch gitea do docker compose up -d
You can do docker ps to see if gitea started properly
Everything else can be managed through portainer but if you don't want to use portainer or docker desktop you can do docker compose down and this will shut down the whole stack

And thats about it!
You can now open a browser and navigate to http://server-ip:3000 and there you just follow the simple installation wizard and everything should be working from that point on.

Installation with Docker

The setup is just slighty modified version of the rootless docker setup so i won't bother you with all the explanations again.
Here is the rundown

Basics

This is the basic setup without a DB (one can be initialized using SQLite3)
Note that the volume must be owned by the user/group with the UID/GID stated in the config file

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.22.3
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"

Ports

This is to bind the integrated OpenSSH daemon and the webserver to a different port
Usually you only change the host port and keep the container ports like they are

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.22.3
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8080:3000"
      - "2221:22"

MySQL database

This starts gitea with MySQL database.We are adding the gitea database and creating the gitea user.

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.22.3
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=mysql
      - GITEA__database__HOST=db:3306
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=gitea
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

  db:
    image: mysql:8
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=gitea
      - MYSQL_DATABASE=gitea
    networks:
      - gitea
    volumes:
      - ./mysql:/var/lib/mysql

PostgreSQL database

Same thing as MySQL but with PostgreSQL.We are adding the gitea database and creating the gitea user:

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.22.3
    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
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
     depends_on:
      - db

   db:
     image: postgres:14
     restart: always
     environment:
       - POSTGRES_USER=gitea
       - POSTGRES_PASSWORD=gitea
       - POSTGRES_DB=gitea
     networks:
       - gitea
     volumes:
       - ./postgres:/var/lib/postgresql/data

Named volumes

To use named volumes instead of the host volumes change the config accordingly

version: "3"

networks:
  gitea:
    external: false

volumes:
  gitea:
    driver: local

services:
  server:
    image: gitea/gitea:1.22.3
    container_name: gitea
    restart: always
    networks:
      - gitea
    volumes:
      - gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
MySQL or PostgreSQL containers will need to be created separately.

Startup

From July 2023 Compose V1 stopped receiving updates. It's also no longer available in new releases of Docker Desktop.

Compose V2 is included with all currently supported versions of Docker Desktop. Please use V2 to do below operations.

To launch gitea do docker compose up -d
You can do docker ps to see if gitea started properly
Everything else can be managed through portainer but if you don't want to use portainer or docker desktop you can do docker compose down and this will shut down the whole stack

And thats about it!
You can now open a browser and navigate to http://server-ip:3000 and there you just follow the simple installation wizard and everything should be working from that point on.