Gitea¶
Gitea is a self-hosted software development service similar to GitHub, Bitbucket and GitLab. The IOTstack implementation runs as a pair of containers using a MariaDB database as the back-end.
references¶
environment variables¶
Environment variables need to be set in several stages:
-
Before you start the container for the first time, you should define the following environment variables. If you make a mistake or change your mind later, the best course of action is to start over from a clean slate:
-
GITEA_DB_NAME
is the name of the database that Gitea (the service) will use to store its information in MariaDB. Example:echo "GITEA_DB_NAME=gitea" >>~/IOTstack.env
If omitted, defaults to "gitea".
-
GITEA_DB_USER
is the name of the user that Gitea (the service) will use to authenticate with MariaDB. Example:echo "GITEA_DB_USER=gitea" >>~/IOTstack.env
If omitted, defaults to "gitea".
-
GITEA_DB_PASSWORD
is the password associated with the above user. Example:$ echo "GITEA_DB_PASSWORD=$(uuidgen)" >>~/IOTstack.env
If omitted, the container will not start.
-
GITEA_DB_ROOT_PASSWORD
is the administative password for the MariaDB service. Keep in mind that thegitea_db
service is dedicated to Gitea. You can run other MariaDB instances in parallel. They will not interfere with each other and neither will they share data or credentials. Example:$ echo "GITEA_DB_ROOT_PASSWORD=$(uuidgen)" >>~/IOTstack.env
If omitted, the container will not start. See note below.
You (the human user) will never need to know the username and passwords set here. You will not need to use these values in practice.
-
-
After you have set the environment variables listed above, start the container:
$ cd ~/IOTstack $ docker compose up -d gitea
If this is the first time you have launched Gitea, docker compose will also build and run the
gitea_db
service.You can expect to see the following warnings:
WARN[0000] The "GITEA_SECRET_KEY" variable is not set. Defaulting to a blank string. WARN[0000] The "GITEA_INTERNAL_TOKEN" variable is not set. Defaulting to a blank string.
Those are reminders to execute these commands:
$ echo "GITEA_SECRET_KEY=$(docker exec gitea gitea generate secret SECRET_KEY)" >>~/IOTstack/.env $ echo "GITEA_INTERNAL_TOKEN=$(docker exec gitea gitea generate secret INTERNAL_TOKEN)" >>~/IOTstack/.env
After that command has run, start the container again:
$ docker compose up -d gitea
The warning message will go away.
See Managing Deployments With Environment Variables for more information.
-
The
GITEA_ROOT_URL
environment variable should be set to the URL that the user uses to reach the Gitea service. If you use a proxy host such as Nginx then this would be the URL you present to the proxy. For example:$ echo "GITEA_ROOT_URL=https://gitea.my.domain.com" >>~/IOTstack.env
Alternatively, if you connect directly to the host on which the service is running, the URL will be that of the host plus the external port of the Gitea container. For example:
$ echo "GITEA_ROOT_URL=http://host.my.domain.com:7920" >>~/IOTstack.env
If omitted, defaults to null in which case the container will make a best-efforts determination (which is unlikely to be correct). You will also see this warning:
WARN[0000] The "GITEA_ROOT_URL" variable is not set. Defaulting to a blank string.
You can change this variable whenever you like. Simply edit the value in
~/IOTstack/.env
and apply the change by running:$ docker compose up -d gitea
See Gitea Server for more information.
-
By default, Gitea expects to communicate using the HTTP protocol. If you want Gitea to switch to HTTPS, you need to do the following:
-
Generate a self-signed certificate:
$ docker exec gitea bash -c 'cd /data/git ; gitea cert --host gitea --ca'
-
Uncomment the following environment variables in the service definition:
environment: ... # - GITEA__server__KEY_FILE=/data/git/key.pem # - GITEA__server__CERT_FILE=/data/git/cert.pem
These variables tell Gitea where to find the X.509 certificate and matching private key that were generated in the first step.
-
swap the comments on the
test
lines in thehealthcheck
clause:healthcheck: test: ["CMD-SHELL", "curl -sf4 -o /dev/null http://gitea:3000"] # test: ["CMD-SHELL", "curl -sf4 --cacert $$GITEA__server__CERT_FILE -o /dev/null https://gitea:3000"]
In other words, the final result should look like this:
healthcheck: # test: ["CMD-SHELL", "curl -sf4 -o /dev/null http://gitea:3000"] test: ["CMD-SHELL", "curl -sf4 --cacert $$GITEA__server__CERT_FILE -o /dev/null https://gitea:3000"]
-
Tell Gitea to enable HTTPS:
$ echo "GITEA_WEB_PROTOCOL=https" >>~/IOTstack/.env
-
Recreate the container:
$ cd ~/IOTstack $ docker compose up -d gitea
If everything has gone according to plan, Gitea will be expecting HTTPS traffic and will perform SSL authentication using the key and certificate generated in the first step.
Notes:
-
The certificate has a one-year lifetime. It can be regenerated at any time by re-running the command provided earlier. You could, for example, embed it in a
cron
job, like this:5 0 1 1,7 * docker exec gitea bash -c 'cd /data/git ; gitea cert --host gitea --ca' >/dev/null 2>&1
In words, run the command "at five minutes after midnight on the first of January and the first of July".
-
Gitea also supports LetsEncrypt. See using ACME with Let's Encrypt.
-
database root password¶
At the time of writing (April 2025), the MariaDB instance was not respecting the environment variable being used to pass the root password into the container.
You can ensure that the root password is set by running the following command:
$ docker exec gitea_db bash -c 'mariadb-admin -u root password $MYSQL_ROOT_PASSWORD'
If this command returns an error, it means that the root password was already set (presumably because Issue 163 has been resolved).
If this command succeeds without error, it means that the root password was not set but is now set.
Also notice that you did not need to know or copy/paste the root password to run the above command. It was sufficient to know the name of the environment variable containing the database root password.
default ports¶
The IOTstack implementation listens on the following ports:
- 7920 the Gitea graphical user interface
- 2222 the SSH passthrough service
getting started¶
Use your browser to connect to the Gitea service, either:
-
directly:
http://«host»:7920
where
«host»
is:- an IP address (eg 192.168.1.10)
- a hostname (eg
iot-hub
- a domain name (eg
iot-hub.my.domain.com
) - a multicast domain name (eg
iot-hub.local
)
-
indirectly, via a reverse proxy:
https://gitea.my.domain.com
This assumes that the reverse proxy redirects the indirect form (using HTTPS) to one of the direct forms (using either HTTP or HTTPS).
Click on the Register button to create an account for yourself.
After that, please rely on the Gitea documentation.
launch times¶
When you start the gitea
service, docker compose auto-starts the gitea_db
service (a MariaDB aka MySQL implementation). The database service can take some time to start and that, in turn, affects the availability of the gitea
service.
The time it takes for the gitea
service to become fully available depends on your hardware (CPU speed, RAM, SD/HD/SSD). As an example, the gitea
service takes about 30 seconds to become available on a 4GB Raspberry Pi 4 with SSD.
You may get strange error messages if you attempt to connect to gitea
while it is still coming up.
The moral is: be patient!
starting over from a clean slate¶
Proceed as follows:
$ cd ~/IOTstack
$ docker compose down gitea gitea_db
$ sudo rm -rf ./volumes/gitea
$ docker compose up -d gitea
container maintenance¶
You can maintain the Gitea container with normal pull
commands:
$ cd ~/IOTstack
$ docker compose pull gitea
$ docker compose up -d gitea
$ docker system prune -f
The Gitea_DB container needs special handling:
$ cd ~/IOTstack
$ docker-compose build --no-cache --pull gitea_db
$ docker compose up -d gitea_db
$ docker system prune -f
migrating existing repositories¶
The simplest approach to migrating an existing repository into Gitea is:
- Start with an existing clone of the repository you want to migrate;
- Convert the existing clone to a "bare" repository;
- Copy the "bare" repository into Gitea's persistent store; and
- Use the Gitea GUI to adopt it.
existing clone¶
Let's assume you have an existing clone of a repository named "my-project" at the path:
~/my-repos/my-project
convert to bare¶
To convert that existing clone to a "bare" repository:
$ mkdir ~/bare
$ cd ~/bare
$ git clone --bare ~/my-repos/my-project
The result will be a folder at the path:
~/bare/my-project.git
Note:
- If you already have a "bare" repository stored somewhere then the only thing you are likely to need to do is to rename the directory to have the
.git
extension.
The bare clone will probably have inherited the remote URL(s) that were associated with the original cloning process. Those don't actually cause any harm but they can be confusing so it is a good idea to get rid of them:
$ cd my-project.git
$ git remote -v
origin «pathOrURLTo»/my-project (fetch)
origin «pathOrURLTo»/my-project (push)
$ git remote remove origin
This example only had one remote ("origin"). Some projects have multiple remotes (eg "upstream") so keep executing the git remote remove «remote»
command until all remotes have been removed.
copy to Gitea's persistent store¶
Assuming you have been doing all this work on a computer which is not where Gitea is running, the next step is to move the my-project.git
folder onto the host where Gitea is running. How you do that is up to you. For example:
- the
scp -r
command †; - the
sftp
command plus theput -r
command †; - file-sharing protocols such as SAMBA or SSHFS; or
-
"sneaker-net" via a thumb drive.
† in each case, the
-r
(recursive) is needed to copy the directory and its contents
On the host where Gitea is running, I'm going to assume that the bare repository is at:
~/my-project.git
Move into the Gitea persistent store:
$ cd ~/IOTstack/volumes/gitea/data/git/repositories/«user»/
where «user»
is your username as known to Gitea.
Move the bare repository into this scope:
$ mv ~/my-project.git .
Note:
- There has been no mention thus far of ownership and permissions. That's because the Gitea container runs as userID 1000. Inside the container, that's the username "git". Outside the container, userID 1000 is the first user defined on the Linux system and is the account that the majority of Linux users login under. You will only have to be concerned about ownership and permissions if you depart from this norm.
adopt the repository¶
Go to the Gitea GUI and login to your account. From the main menu, choose "Settings".
In the left hand panel, click "Repositories". If all has gone well, my-project
will be present in the list, associated with Adopt Files and Delete buttons. Click Adopt Files, then click Yes to adopt pre-existing files.
The end result is a private repository. If you want it to be public, click on the name of the newly-adopted repository in the list, then click Settings. Scroll to the bottom of the page into the "Danger Zone" and click Make Public followed by Yes.