Installing a Gitea server on FreeBSD

Learn how to install a Gitea server in a jail on a FreeBSD host. Configure the Gitea service to work without a reverse proxy.

Prerequisites

  • A MariaDB server, which can be the same as your Gitea server or a separate host.
  • You need an SSL certificate—such as the ones from Let’s Encrypt—to configure access over HTTPS.

Creating ZFS datasets

You can store the repositories in a specific ZFS dataset on your FreeBSD server, which can make it easier to perform some administrative tasks, such as backups.

To create the dataset, run the following command in the FreeBSD host:

zfs create tank/repositories

The previous command creates a dataset named repositories in the tank pool.

Preparing the jail

The instructions in this post host the app server in a jail on FreeBSD. To learn why we use jails for this purpose, check the Application server section of our self-hosted architecture post.

In this section, you’ll perform the following tasks:

  • Create a jail.
  • Configure networking on the jail.
  • Install the prerequisite packages.

Run the commands from a session in your FreeBSD host.

To create a jail:

  1. Fetch or update the release version of FreeBSD for jail usage:
    iocage fetch --release 11.3-RELEASE
    
  2. Create a jail named gitea:
    iocage create --name gitea --release 11.3-RELEASE
    

To configure networking on the jail:

  1. Configure the IP address. The following example sets the IP address to 192.168.1.123 using a subnet mask of 24 bits on the em0 interface. The command uses the CIDR notation.
    iocage set ip4_addr="em0|192.168.1.123/24" gitea
    
  2. Configure the default router. The following example sets the default router to 192.168.1.1:
    iocage set defaultrouter=192.168.1.1 gitea
    

Start the jail and open a session to complete the rest of the tasks in this section:

iocage start gitea
iocage console gitea

Install the following packages:

  • ca_root_nss
  • git
  • openssl
  • gitea
pkg update
pkg install --yes ca_root_nss git openssl gitea

Create the folder in the jail where you are going to mount the dataset. Assign the git user as the owner:

mkdir -p /mnt/repositories
chown -R git:git /mnt/repositories

Close the session in the jail so you can mount the datasets from your FreeBSD session:

exit

Mount the datasets on the jail:

  1. Use the following command to stop the jail:
    iocage stop gitea
    
  2. Mount the files dataset on the folder created in the previous section:
    iocage fstab gitea --add /tank/repositories /mnt/repositories nullfs rw 0 0
    
  3. Restart the jail:
    iocage start gitea
    

Creating the database

Gitea requires a database server, you can use MySQL / MariaDB, PostgreSQL, MSSQL, or SQLite. This guide uses a MariaDB server to host the database. For information on how to install a MariaDB server, see [Installing a MariaDB server on FreeNAS][1].

Once you have the MariaDB server installed, create a user and database:

  1. Open a session on your MariaDB server:
    iocage console mariadb-server
    
  2. Once in the MariaDB server, open a connection to the database engine:
    mysql -u root -p
    
  3. Create a database user named gitea. Make sure to replace localhost with the hostname of the Gitea server and db-user-password with a strong password:
    CREATE USER 'gitea'@'localhost' IDENTIFIED BY 'db-user-password';
    

    If your MariaDB server is [configured with access over TLS][8] you can append REQUIRE SSL to the previous command to make sure that the communication between the servers is encrypted.

  4. Create the database with the utf8mb4 character set and unicode_ci collation:
    CREATE DATABASE gitea CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
    
  5. Grant permissions to the user on the database:
    GRANT ALL ON gitea.* TO 'gitea'@'localhost';
    FLUSH PRIVILEGES;
    

    Make sure to replace localhost with the hostname of the Gitea server.

  6. Close the database connection:
    exit
    

Allow the git user to bind to the HTTPS port

Since the Gitea service runs under the git user, it must be allowed to bind to the HTTPS port. This allows Gitea to run without a reverse proxy. To allow the user to bind to the HTTPS port:

  • Configure a port ACL rule on the host.
  • Set the securelevel property of the jail to -1.
  • Configure the reserved ports on the jail.

To configure the port ACL rule on the host:

  1. Enable the mac_portacl module by adding the following line to /boot/loader.conf:
    mac_portacl_load="YES"
    
  2. Get the id of the jail’s git user:
    iocage exec gitea -- id -u git
    
  3. Configure the rule by adding the following line to /etc/sysctl.conf:
    security.mac.portacl.rules=uid:git-user-id:tcp:443
    

    Replace git-user-id with the value from the previous step.

  4. Restart the host.

To set the security level on the jail to -1, run the following command from the FreeBSD host:

iocage set securelevel=-1 gitea

To configure the reserved ports on the jail:

  1. Configure the reservedhigh property to a value lower than 443 by adding the following line to /etc/sysctl.conf:
    net.inet.ip.portrange.reservedhigh=442
    
  2. Restart the jail.

Configure the service

Open a session on the gitea jail:

iocage console gitea
  1. Copy the crt and key files of your certificate to /usr/local/etc/gitea/cert in the jail.
  2. Generate a 64 byte pseudo-random string to use as the INTERNAL_TOKEN value in the service configuration:
    openssl rand -base64 64
    
  3. Generate a 32 byte pseudo-random string to use as the JWT_SECRET value in the service configuration:
    openssl rand -base64 32
    
  4. Configure Gitea by editing /usr/local/etc/gitea/conf/app.ini. Pay special attention to the following attributes:
    [database]
    DB_TYPE  = mysql
    HOST     = database_host:database_port # port usually is 3306
    NAME     = database_dbname
    PASSWD   = `database_password`
    USER     = database_user
    
    [repository]
    ROOT        = /mnt/repositories
    
    [server]
    DOMAIN           = your_domain
    HTTP_ADDR        = 0.0.0.0
    HTTP_PORT        = 443
    ROOT_URL         = https://%(DOMAIN)s/
    START_SSH_SERVER = true
    CERT_FILE        = cert/your_certificate.crt
    KEY_FILE         = cert/your_certificate.key
    PROTOCOL         = https
    
    [security]
    INSTALL_LOCK   = true
    INTERNAL_TOKEN = ABCDEF # 64-byte string from the previous step
    SECRET_KEY     = any_password_of_your_choosing
    
    [oauth2]
    JWT_SECRET = ABCDEF # 32-byte string from the previous step
    
  5. Configure the gitea service startup and restart the service:
    sysrc gitea_enable=yes
    service gitea onestart
    

Go to https://your_domain to see the welcome page of your Gitea server.