> The full list of articles is in [llms.txt](https://docs.f3cloud.com/llms.txt). Every page has a Markdown version: add .md to its address. This page as Markdown: [https://docs.f3cloud.com/en/docker/gitea-installation.md](https://docs.f3cloud.com/en/docker/gitea-installation.md).

# Gitea on a VPS – your own Git server in Docker, SSH, backups and updates

Installing Gitea on a VPS with Docker Compose. Your own Git server with a web interface, the initial setup, an administrator, a repository, working over HTTP and over SSH on port 2222, closed registration, colleagues and permissions, backups with the gitea dump command, restoring, updating and common errors. Tested on Debian 12 with Gitea 28.2.0.

A Git server of your own is useful when you do not want to hand your code to someone else's service, or when a project needs its own access rules. **Gitea** is a lightweight open-source program that turns a VPS into such a server. It stores repositories, shows them in the browser, manages accounts and permissions, and on top of that offers issues and pull requests. At the same time it takes only 100 to 160 MB of memory on the server. In this article we will run Gitea in Docker, go through the initial setup, create an administrator and a repository, connect over HTTP and over SSH, close registration, add a colleague, set up backups and look at updating. We repeated every step on a test server with Debian 12, and the Gitea version at the time of testing was **28.2.0**.

***

## How a Git server on Gitea works

Git itself does not need a special server. Every copy of a project on your computer already holds the whole history of changes, and after `git clone` the `git log` command shows all the earlier commits. The server only has to be a shared place where participants send their changes and pick up other people's. Gitea creates exactly such a place. It keeps repositories in a folder on disk, maintains the list of users, decides who may read and who may write, and also draws the web pages with code, history and issues. Information about users and repositories is stored in a database, and in our setup it is an ordinary SQLite file inside the same folder, so a separate database server is not needed.

You can reach Gitea in two ways. The first goes over HTTP to port 3000, like an ordinary page in the browser. Every operation requires a login and password, and as long as the address starts with `http://` and not `https://`, they travel over the network unencrypted. We checked this on the test server. While `git push` was running, we recorded the traffic with the tcpdump program, and the `Authorization: Basic` header with the login data was visible in the stream in plain text. The second way goes over SSH. You create a pair of keys once, add the public part to your Gitea profile, the private part stays on your computer, and from then on Git confirms your identity with the key, without a password. For this, Gitea's own SSH server runs inside the container on the container's port 22. Port 22 of the VPS itself is already taken by your SSH login, so we will publish the container's port under the number 2222, and Git will need to connect to exactly that one.

The rest depends on where Gitea keeps its data. Everything that changes during work lies in one folder, `/opt/gitea/data`. There you will find the settings file `app.ini`, the `gitea.db` database, the repositories themselves in the `git/repositories` folder and the SSH server keys in the `ssh` folder. The container itself stores nothing important. It can be deleted and created again from the image, and the data will stay in place. So updating Gitea comes down to changing the image, and a backup comes down to saving the data from this folder. SQLite is enough for a small team, and we will work with it. For a server with a large number of users, the official Gitea documentation describes a variant with PostgreSQL.

> **Why version 28 and not 1.27.**
>
> In older instructions you will come across Gitea tags like 1.27. The last release with that numbering was 1.27.3, and the next one came out as 28.0.0. Version 28.2.0 was current at the time of our testing, and that is exactly the one we used.

***

## What you need

* **A server** with Debian 12 or Ubuntu 24.04, for example the **DE-RZ9-1** plan. Gitea hardly loads the server at all. On ours the container with SQLite took from 100 to 160 MB of memory at different times, and the image took about 260 MB of disk space. The space for repositories depends on your projects. If you do not have a server yet, order one using the [guide](https://docs.f3cloud.com/en/client-area/order-vps.md).
* **Docker and Docker Compose**. How to install them is described in the article about [Docker](https://docs.f3cloud.com/en/docker/docker-installation.md). We had Docker 29.9.2 and Compose 5.6.1.
* **An SSH connection**, for example via [Termius](https://docs.f3cloud.com/en/vps/termius-connection.md). Commands on the server are run as `root`.
* **Free ports 3000 and 2222**. Port 22 stays reserved for your login to the server.
* **Git on your computer**. We tested with Git 2.39.5.

***

## Step 1. Run Gitea in Docker

Create a folder for Gitea and a Compose file. This folder will hold both the file itself and all the data.

```bash
mkdir -p /opt/gitea
cd /opt/gitea
nano docker-compose.yml
```

Paste the configuration below into the file. Save it with <kbd>Ctrl</kbd> + <kbd>O</kbd>, then <kbd>Enter</kbd>, and exit the editor with <kbd>Ctrl</kbd> + <kbd>X</kbd>.

```yaml
services:
  gitea:
    image: docker.gitea.com/gitea:28.2.0
    container_name: gitea
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
    volumes:
      - ./data:/data
    ports:
      - "3000:3000"
      - "2222:22"
```

Here is what it all means.

* `image` points to the official Gitea image. The version number is written explicitly, so the update happens when you decide to do it.
* `USER_UID` and `USER_GID` set the user that Gitea runs as inside the container. According to the documentation, the default is 1000.
* `./data:/data` mounts the `data` folder next to the file. The database, repositories and settings will end up in it.
* `"3000:3000"` opens the web interface, and `"2222:22"` opens Gitea's SSH server on port 2222.
* `restart: always` makes Docker start the container after the server reboots. More about this in the article about [Docker](https://docs.f3cloud.com/en/docker/docker-installation.md).

Start the container and look at its state.

```bash
docker compose up -d
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
```

The first start downloads the image. For us it took about three seconds. The list should show a `gitea` line with the status **Up**.

<figure><img src="https://docs.f3cloud.com/img/gitea-compose.png" alt="The docker-compose.yml file, running docker compose up -d and the gitea container with the status Up and ports 3000 and 2222"><figcaption><p>The Gitea container is running, ports 3000 and 2222 are published</p></figcaption></figure>

> **Ports open without UFW.**
>
> We checked from another computer that ports 3000 and 2222 respond even though UFW has no rules for them at all. Docker publishes ports with its own rules, and they take effect before the UFW rules. This is covered in detail in the article about [Docker](https://docs.f3cloud.com/en/docker/docker-installation.md), and at the end of this article we show how to hide the web port from the internet.

***

## Step 2. Go through the initial setup

> **Do not leave the setup page open.**
>
> Until you click the install button, the page is available to anyone who knows the address and port, and any visitor can fill it in themselves, right down to the administrator account. Go through the setup right after starting the container.

Open `http://server-IP:3000` in your browser. The **Initial Configuration** page will appear. Most fields are already filled in correctly, so only a few need changing.

1. In the **Database Settings** block, keep the type **SQLite3** and the path `/data/gitea/gitea.db`. This is a path inside the container, and on the server the file will end up in the `/opt/gitea/data/gitea` folder.
2. In the **Site Title** field, enter your own name or leave it as it is.
3. In the **SSH Server Port** field, replace 22 with **2222**. This way Gitea will show in the clone addresses the port that we opened to the outside. Inside the container the SSH server still listens on 22, and Gitea takes this into account on its own.
4. The **Gitea Website URL** field already contains the address you used to open the page, for example `http://server-IP:3000/`. Check it.
5. Tick **Only administrators can create user accounts (no self-registration)**. Then only a person created by the administrator will be able to register on your server.

<figure><img src="https://docs.f3cloud.com/img/gitea-install-form.png" alt="The Gitea Initial Configuration page with the SQLite3 database, SSH port 2222, the site address and the self-registration ban ticked"><figcaption><p>SSH port 2222 and the registration ban, everything else is left at the defaults</p></figcaption></figure>

There are two more checkboxes nearby.

* **Require sign-in to view pages** hides the pages with the list of repositories from guests. We turned it on as a test, and the repository overview page sent a visitor who was not logged in to the sign-in form. It is useful if the server is only for your own people.
* **Enable update checker** is left at the default.

Now create the administrator.

6. At the bottom of the page, expand **Optional Settings** and open the **Administrator Account Settings** block.
7. Think up an **Administrator Username**, enter an **Email Address** and type the password twice. The mailbox can be any, because Gitea does not send emails until you set up mail. Choose a long and complex password. In our test the installer accepted even a three-character password, which means it will not protect you from a weak one.

<figure><img src="https://docs.f3cloud.com/img/gitea-install-admin.png" alt="The Administrator Account Settings block with the fields for username, email address, password and password confirmation"><figcaption><p>The administrator account is created right on the installation page</p></figcaption></figure>

8. Click the <kbd>Install Gitea</kbd> button at the bottom of the page. After a few seconds you will find yourself on a Gitea page, already signed in to your account.

The settings are written to the `/opt/gitea/data/gitea/conf/app.ini` file, and we will edit it from time to time later.

***

## Step 3. Set the server address in app.ini

The setup page has no field for a domain, so Gitea wrote `DOMAIN = localhost` and `SSH_DOMAIN = localhost` into the file. We checked what this leads to. On the repository page the SSH address started with `ssh://git@localhost:2222/…`, and you cannot connect with it from another computer. Let us fix the two lines.

```bash
cd /opt/gitea
nano data/gitea/conf/app.ini
```

In the `[server]` block, replace `localhost` with the server's IP address in the `DOMAIN` and `SSH_DOMAIN` lines. Do not touch the `SSH_PORT = 2222` and `SSH_LISTEN_PORT = 22` lines. The first sets the port that is shown in the addresses, and the second is the SSH server port inside the container. Save the file and check the result.

```bash
grep -n -E "DOMAIN|ROOT_URL|SSH_PORT|SSH_LISTEN" data/gitea/conf/app.ini
```

Then restart the container so that Gitea reads the file again.

```bash
docker restart gitea
```

<figure><img src="https://docs.f3cloud.com/img/gitea-domain.png" alt="The result of grep on app.ini, the DOMAIN, SSH_DOMAIN and ROOT_URL lines with the server address, SSH_PORT equal to 2222, SSH_LISTEN_PORT equal to 22, then docker restart gitea"><figcaption><p>The addresses now contain the server's IP address, which is hidden in the screenshot</p></figcaption></figure>

When the server gets a domain, you write it into the same lines and into `ROOT_URL`, as described in the section about the domain and HTTPS.

***

## Step 4. Create a repository

Click the **+** icon in the top right corner and choose **New Repository**.

1. In the **Repository Name** field, enter `my-project`.
2. Tick **Make repository private**. This box is not ticked by default, and the repository would end up public.
3. In the **Description** field, write a few words about the project if you like.
4. Tick **Initialize Repository**. Gitea will immediately create the first commit with a README file, so there will be something to clone.
5. Click <kbd>Create Repository</kbd>.

<figure><img src="https://docs.f3cloud.com/img/gitea-repo-create.png" alt="The New Repository form with the name my-project and the private repository and initialization boxes ticked"><figcaption><p>A private repository with a first commit</p></figcaption></figure>

On the repository page, click the blue <kbd>Code</kbd> button. The window that opens has two tabs with clone addresses, **HTTP** and **SSH**. We will start with the first one.

<figure><img src="https://docs.f3cloud.com/img/gitea-clone-http.png" alt="The my-project repository page, the Code window with the HTTP tab and the clone address"><figcaption><p>The clone address over HTTP, the server address in the screenshot is replaced</p></figcaption></figure>

***

## Step 5. Clone the repository and push changes over HTTP

Before the first commit, Git has to know who you are. Run these two commands once on your computer, substituting your own name and email.

```bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
```

Now clone the repository, add a file to it and send the changes to the server. Take the address from the **Code** window. The repository is private, so Git will ask for **Username** and **Password** twice. Enter the administrator's login and password. The password is not shown as you type, and that is normal.

```bash
# Clone the repository over HTTP
git clone http://server-IP:3000/gitadmin/my-project.git
cd my-project

# Add a file and commit the change
echo "print(1)" > hello.py
git add hello.py
git commit -m "Add hello.py"

# Push the commit to the server
git push
```

We ran these commands on the server itself under a separate user, and on your computer the result will be the same.

<figure><img src="https://docs.f3cloud.com/img/gitea-git-http.png" alt="git clone over HTTP with a login and password prompt, the hello.py commit and git push to the main branch"><figcaption><p>Cloning and pushing over HTTP, the server address is hidden</p></figcaption></figure>

After `git push`, open the repository page in the browser. The `hello.py` file is already there, and the history shows two commits.

> **The password over HTTP is not protected.**
>
> An address like `http://server-IP:3000` encrypts neither the password nor the code. For work on real projects, use SSH, which is described in the next step, or put a domain with HTTPS in front of Gitea.

***

## Step 6. Connect SSH on port 2222

Over SSH, Git does not ask for a password and does not send it over the network. First you need a pair of keys. If you already have a key, you can skip the creation step, and keys are covered in more detail in the article about [SSH keys](https://docs.f3cloud.com/en/vps/security/ssh-keys.md).

1. Create a key on your computer. You can simply press <kbd>Enter</kbd> for all three questions, but if the key lives on a laptop, it is safer to set a passphrase.

   ```bash
   ssh-keygen -t ed25519 -C "me@example.com"
   ```

2. Print the public part of the key on the screen. This is the file ending in `.pub`. Do not show the private file `id_ed25519`, the one without an ending, to anyone, and do not paste it anywhere.

   ```bash
   cat ~/.ssh/id_ed25519.pub
   ```

<figure><img src="https://docs.f3cloud.com/img/gitea-ssh-keygen.png" alt="Creating a key with ssh-keygen -t ed25519 and printing the public key with cat"><figcaption><p>The key is created, the public part is printed on the screen</p></figcaption></figure>

3. In Gitea, open the profile menu in the top right corner, choose **Settings** and then **SSH / GPG Keys**. In the **Manage SSH Keys** block, click <kbd>Add Key</kbd>.
4. In the **Key Name** field, enter any clear name, for example "My computer". In the **Content** field, paste the whole line printed by the `cat` command, from `ssh-ed25519` to the email at the end.
5. Click <kbd>Add Key</kbd>. Gitea will reply with a message that the key has been added.

<figure><img src="https://docs.f3cloud.com/img/gitea-ssh-key-add.png" alt="The SSH / GPG Keys page, the form for adding a key with a name and the contents of the public key"><figcaption><p>Only the public part of the key is pasted into the field</p></figcaption></figure>

Now go back to the repository page, open the **Code** window and switch to the **SSH** tab. The address starts with `ssh://git@` and contains the server's IP address and port 2222.

<figure><img src="https://docs.f3cloud.com/img/gitea-clone-ssh.png" alt="The Code window on the SSH tab with the address ssh://git@IP:2222/gitadmin/my-project.git"><figcaption><p>The clone address over SSH with port 2222</p></figcaption></figure>

Clone the repository using this address. On the first connection SSH will ask whether to trust the server's key. This is a normal question on any first connection, so answer `yes`.

```bash
# Clone over SSH, port 2222 is part of the address
git clone ssh://git@server-IP:2222/gitadmin/my-project.git my-project-ssh
cd my-project-ssh

# Change a file and push the change
echo "SSH works" >> README.md
git commit -am "Update README"
git push
```

This time there was no password prompt, and `hello.py` from the previous step was already in the clone.

<figure><img src="https://docs.f3cloud.com/img/gitea-git-ssh.png" alt="git clone over SSH with confirmation of the server key, a commit and git push without a password prompt"><figcaption><p>Cloning and pushing over SSH, the server address is hidden</p></figcaption></figure>

You can also quickly check that the key is accepted without any repository. The `ssh -p 2222 git@server-IP` command replies with a line like **Hi there, gitadmin! You've successfully authenticated with the SSH key named …** and says that it gives no access to the Gitea command line. This is not a login to the server, only a check of the key.

***

## Step 7. Add a colleague and check that registration is closed

Open `http://server-IP:3000/user/sign_up` in your browser without signing in to an account. If you ticked the registration ban on the installation page, Gitea will answer with the message **Registration is disabled. Please contact your site administrator.**

If the box was left unticked, fix the setting by hand. Open `/opt/gitea/data/gitea/conf/app.ini`, find the `DISABLE_REGISTRATION` line in the `[service]` block and set it to `true`. After `docker restart gitea`, registration will be closed. We switched this line both ways, and the registration page changed accordingly. The `REQUIRE_SIGNIN_VIEW = true` line mentioned in step 2 is turned on the same way.

Now let us add a colleague. Accounts are created by the administrator.

1. Open the profile menu and choose **Site Administration**.
2. In the left menu, open **Identity & Access**, then **User Accounts**, and click <kbd>Create User Account</kbd>.
3. Fill in **Username**, **Email Address** and **Password**. It is better to leave the **Require user to change password (recommended)** checkbox turned on.
4. Click <kbd>Create User Account</kbd>.

<figure><img src="https://docs.f3cloud.com/img/gitea-new-user.png" alt="The Create User Account form in Gitea Site Administration with a username, email and password"><figcaption><p>The administrator creates an account for a colleague</p></figcaption></figure>

Give your colleague the temporary password. They need to sign in once through the browser, and Gitea itself will offer to set a new password. Until that is done, Git over HTTP answers with an error, and we got this reply on the test server.

```text
remote: Update your password
fatal: Authentication failed for 'http://server-IP:3000/gitadmin/my-project.git/'
```

The new user cannot see your private repository yet. Open the repository, choose **Settings** in the three-dot menu, then **Collaborators**. Start typing the colleague's name, pick them from the suggestion and click <kbd>Add Collaborator</kbd>. Gitea will confirm the addition, and the access level will be **Write** by default.

<figure><img src="https://docs.f3cloud.com/img/gitea-collaborator.png" alt="Repository settings, the Collaborators section, the user mike added with the Write permission"><figcaption><p>The collaborator is added and is allowed to read and write</p></figcaption></figure>

After that we cloned the repository as the colleague and pushed a commit to it, and everything went through without errors.

***

## Backups

Gitea has an official **gitea dump** command. It collects a single archive with the database, repositories and settings. The archive contains the `app.ini` file, the `data` folder with attachments and the SQLite file, the `repos` folder with the repositories and the `gitea-db.sql` file with a copy of the database. The SSH server keys are not in the archive, and we checked this. When we restored a copy on a clean container, it had different keys than the original. If the keys change, SSH will start complaining about a changed server key for everyone who has already connected to the server. That is why the script below saves the `ssh` folder as a separate archive.

The Gitea documentation advises stopping the service while copying so that the data is consistent. The script works on a running container, and in our test the copy restored fine. If you have a large team, run it at night.

Create the script.

```bash
nano /opt/gitea/backup.sh
```

```bash
#!/bin/sh
# Gitea backup (the official gitea dump plus the SSH server keys)
set -e
cd /opt/gitea
STAMP=$(date +%F-%H%M)
mkdir -p backups

# Archive with the database, repositories and settings, built in /tmp inside the container
docker exec -u git -w /tmp gitea gitea dump -q -c /data/gitea/conf/app.ini -f /tmp/gitea-dump.zip
docker cp -q gitea:/tmp/gitea-dump.zip backups/gitea-dump-$STAMP.zip
docker exec gitea rm /tmp/gitea-dump.zip

# The SSH server keys are not part of the archive, so we save them separately
tar czf backups/gitea-ssh-$STAMP.tar.gz -C data ssh

# Keep the 7 latest copies
ls -1t backups/gitea-dump-*.zip | tail -n +8 | xargs -r rm
ls -1t backups/gitea-ssh-*.tar.gz | tail -n +8 | xargs -r rm
```

The `-u git` option runs the command as the user Gitea works under, and `-w /tmp` sets the working folder, as the documentation advises, to avoid permission errors while the archive is built. The `-q` option leaves only warnings in the output. Make the script executable and run it.

```bash
chmod +x /opt/gitea/backup.sh
/opt/gitea/backup.sh
ls -lh /opt/gitea/backups
```

On our server the script finished in less than a second.

<figure><img src="https://docs.f3cloud.com/img/gitea-backup.png" alt="Running backup.sh and the list of the backups folder with the gitea-dump archive and the gitea-ssh archive"><figcaption><p>The archive with the data and a separate archive with the SSH server keys</p></figcaption></figure>

To make the copies run by themselves, add a job to cron with the `crontab -e` command. The line below runs the script every night at 03:00. How the schedule works is explained in the article about [cron](https://docs.f3cloud.com/en/linux/cron-linux.md).

```bash
0 3 * * * /opt/gitea/backup.sh
```

We checked that the scheduler runs the script. When the job ran every minute, new archives appeared without errors. Copies on the same server will not help if the server itself is lost, so download the `backups` folder to your own computer from time to time, for example with the [rsync](https://docs.f3cloud.com/en/linux/rsync-linux.md) command.

***

## Restoring from a backup

We tested restoring on a separate clean container with the same configuration. The order of actions on a new server is as follows. First install Docker and create `/opt/gitea/docker-compose.yml` from step 1. Then, if you saved the SSH server keys, unpack them before the first start. We checked that in this case the new container has the same key fingerprint as the old one.

```bash
mkdir -p /opt/gitea/data
tar xzf gitea-ssh-DATE.tar.gz -C /opt/gitea/data
cd /opt/gitea
docker compose up -d
```

Copy the archive into the container and unpack the data into place. We use `cp -a` and not `mv`, because the `conf` folder already exists in the new container.

```bash
docker cp gitea-dump-DATE.zip gitea:/tmp/gitea-dump.zip
docker exec gitea sh -c "cd /tmp && unzip -q gitea-dump.zip -d restore && cp -a restore/data/. /data/gitea/ && cp -a restore/repos/. /data/git/repositories/ && chown -R git:git /data"
```

Finally, recreate the Git hooks, as the documentation advises, and restart the container.

```bash
docker exec -u git gitea gitea -c /data/gitea/conf/app.ini admin regenerate hooks
docker restart gitea
```

After this, the old administrator password worked, the repository history was preserved and a new commit was pushed without errors.

***

## Updating Gitea

The Gitea version is written in `docker-compose.yml`, so updating takes three actions. Make a backup beforehand, because when the minor or major version changes, Gitea changes the database structure, and you can no longer go back to the old version without a copy. This is stated in the Gitea documentation. Before updating, look at the list of changes on the [releases page](https://github.com/go-gitea/gitea/releases), where incompatible changes are marked.

First make a copy and open the Compose file.

```bash
cd /opt/gitea
./backup.sh
nano docker-compose.yml
```

In the `image` line, replace the version number with the new one and save the file. Then download the image and recreate the container. The data in the `data` folder is not affected.

```bash
docker compose pull
docker compose up -d
```

We tested this order on a copy of the server, updating it from version 28.1.0 to 28.2.0. In the example in the screenshot the number is replaced with the `sed` command, and the result is the same as when editing in nano. After the update the API showed the new version, and the repository and the account stayed in place.

<figure><img src="https://docs.f3cloud.com/img/gitea-update.png" alt="Replacing the image tag 28.1.0 with 28.2.0 in docker-compose.yml, docker compose pull, docker compose up -d and the gitea container with the status Up"><figcaption><p>Updating from 28.1.0 to 28.2.0, the container and folder names are adjusted to match the main installation</p></figcaption></figure>

The version is also visible in the bottom line of any Gitea page, next to the **Powered by Gitea** label.

***

## Domain and HTTPS

While Gitea is open by IP address and port 3000, it has no encryption. When you need a proper address, attach a domain to the server following the article about a [domain for a VPS](https://docs.f3cloud.com/en/vps/domain-to-vps.md), put the [nginx](https://docs.f3cloud.com/en/web/nginx-installation.md) web server in front of Gitea and issue a [free certificate](https://docs.f3cloud.com/en/web/lets-encrypt-ssl-nginx-apache.md). We do not cover the nginx configuration for Gitea itself here.

In Gitea itself you then need to fix the addresses in `app.ini`. In the `[server]` block these are the `ROOT_URL`, `DOMAIN` and `SSH_DOMAIN` lines, and you write the domain in them instead of the IP address.

To make the web interface visible only through the web server, publish port 3000 only on the server's internal address. In the Compose file, replace the `"3000:3000"` line with this one.

```yaml
      - "127.0.0.1:3000:3000"
```

We checked that after `docker compose up -d` port 3000 stops responding from outside, while on the server itself and through an SSH tunnel the page still opens. Port 2222 stays open, because it is needed for Git over SSH.

***

## Useful commands

```bash
docker compose ps                 # container status, run it in /opt/gitea
docker logs gitea                 # Gitea log
docker restart gitea              # restart Gitea
docker compose down               # remove the container, the data in ./data stays

# List of users
docker exec -u git gitea gitea admin user list

# A new password for a user, for example if the administrator password is lost
docker exec -u git gitea gitea admin user change-password --username gitadmin --password NEW_PASSWORD --must-change-password=false

# Create an administrator from the command line
docker exec -u git gitea gitea admin user create --admin --username name --password PASSWORD --email me@example.com --must-change-password=false
```

A password typed on the command line ends up in the shell command history. That is why after such a change you should sign in to Gitea and set a permanent password in the profile settings.

***

## Frequently asked questions

<details>

<summary>The SSH clone address contains localhost</summary>

The setup page wrote `DOMAIN = localhost` and `SSH_DOMAIN = localhost` into `app.ini`. We got the address `ssh://git@localhost:2222/…`. Fix both lines as shown in step 3 and restart the container.

</details>

<details>

<summary>git@server-IP: Permission denied (publickey).</summary>

The server does not know your key. We got this error when we tried to clone a repository over SSH before adding the key to Gitea.

1. Make sure that the **SSH / GPG Keys** page in your Gitea profile holds the public part of exactly the key you connect with.
2. Check that you added the contents of the file ending in `.pub` and not the private key.
3. If you have several keys, specify the right one with the `ssh -i` option.

</details>

<details>

<summary>ssh: connect to host server-IP port 2222: Connection refused</summary>

Nothing is answering on the port. We got this error when we stopped the container with the `docker stop gitea` command. Check the state with the `docker compose ps` command and start the container with the `docker start gitea` command. If the container is running but the connection hangs without a reply, a firewall on the way to the server is blocking the port. With HTTP in the same case, Git reports **Failed to connect to server-IP port 3000 after 0 ms: Couldn't connect to server**.

</details>

<details>

<summary>remote: Failed to authenticate user</summary>

The login or password is wrong. Git showed us the following two lines when we entered a wrong password.

```text
remote: Failed to authenticate user
fatal: Authentication failed for 'http://server-IP:3000/gitadmin/my-project.git/'
```

Check the login and password you use for the web interface. If the password is lost, set a new one with the `gitea admin user change-password` command, which is in the Useful commands section.

</details>

<details>

<summary>remote: Update your password</summary>

The account has the requirement to change the password turned on, and the user has not yet signed in through the browser even once. Ask them to open Gitea in the browser, sign in and set a new password, as in step 7.

</details>

<details>

<summary>remote: Repository not found</summary>

We got this error after entering the password correctly, when the address had a typo in the repository name. On the next line Git writes **fatal: repository … not found**. Compare the address with what the **Code** window shows. The same error appears for a colleague who has not been added as a collaborator of a private repository.

</details>

<details>

<summary>Author identity unknown</summary>

Git does not know whose name to put on the commit. We got this message on the first `git commit` for a clean user. Run the two commands from step 5, `git config --global user.name` and `git config --global user.email`, and repeat the commit.

</details>

<details>

<summary>Registration is disabled. Please contact your site administrator.</summary>

A colleague is trying to register on their own, but registration is closed. This is by design. Create an account for them in Site Administration, as in step 7.

</details>

***

## Our resources

**Telegram channel:** [https://t.me/f3cloud_news](https://t.me/f3cloud_news)\
**F3 Cloud:** [https://f3cloud.com](https://f3cloud.com/en)
