Source: IA Book Images via Flickr

There are many reasons for wanting to host your own repositories. I won’t go into the arguments for or against, but simply present a way to get your own “forge” with code respositories, ticket system, wiki and forum up and running quickly and securely. There are a few assumptions to this guide: that you are running a server with a Systemd-based Linux distribution and the apt package manager, such as Debian or Ubuntu; and that you are comfortable using Fossil as your SCM system.

Here are the steps involved:

  1. Create a (sub-)domain for the forge.
  2. Install Guix.
  3. Make a user service file.
  4. Install and configure Nginx.

Create a Domain

Create an A record for your desired domain or subdomain and have it resolve to the public IP address of your server. The specifics of how this works depend on your domain registrar or DNS provider.

Below I assume that you are using the subdomain code.example.net.

Install Guix

Installing Guix is quick and easy. Consult the guide and run the recommended installer script as root, followed by guix pull.

Then create the file /etc/profile.d/guix.sh with the following contents:

GUIX_PROFILE="$HOME/.guix-profile"
source "$GUIX_PROFILE/etc/profile"
GUIX_LOCPATH=$GUIX_PROFILE/lib/locale
export GUIX_LOCPATH
PATH="$HOME/.config/guix/current/bin${PATH:+:}$PATH"
export PATH
export SSL_CERT_DIR="$GUIX_PROFILE/etc/ssl/certs"
export SSL_CERT_FILE="$GUIX_PROFILE/etc/ssl/certs/ca-certificates.crt"
export GIT_SSL_CAINFO="$SSL_CERT_FILE"

The full power of Guix is now available to users on your system.

Create User Service

As a regular (unprivileged) user on your server, create a directory where you want to store your repositories. This should be in a place on your filesystem that is regularly backed up so you don’t lose your hosted repositories in the event of data loss. I will assume that you are putting them in a directory called repos in your user’s home.

Next, as that same user, create a file in ~/.local/share/systemd/user/ called fossil.service with the following contents:

[Unit]
Description=Fossil user server
After=network.target

[Service]
WorkingDirectory=%h/repos
ExecStart=guix environment --ad-hoc -N --container fossil -- fossil server . --scgi --repolist --localhost --port 8081
Restart=always
RestartSec=5

[Install]
WantedBy=sockets.target
WantedBy=multi-user.target

What does this do? It tells Systemd to run a Fossil server in simple CGI (scgi) mode, exposing a list of all repositories. For added security, it runs this server in a restricted environment. That’s what the guix environment stuff is about.

Once you’ve created this file, run the following commands to ensure that this user service is run:

$ systemctl --user daemon-reload
$ systemctl --user enable fossil
$ systemctl --user start fossil

You can now run systemctl --user status fossil to check whether the service is indeed running.

By default, user services are only run while the user they are associated with has an active session. Since you want your forge to be accessible even when your user isn’t logged in, you will need to run loginctl enable-linger <user> as root.

Configure Nginx

If you haven’t already, install the Nginx web server by running apt install nginx. In addition, you should install Certbot with the Nginx plugin for Certbot so you can get free SSL certificates for your forge: apt install certbot python-certbot-nginx.

Next, as root, create the file /etc/nginx/sites-available/code.example.net with the following contents:

server {
    server_name code.example.net;

    location / {
        include scgi_params;
        scgi_param SCRIPT_NAME "";
        scgi_pass 127.0.0.1:8081;
    }
}

Enable this configuration by running ln -s ../sites-available/code.example.net in /etc/nginx/sites-enabled. Still as root, run nginx -t to make sure you made no mistakes in the configuration. If it checks out, run systemctl reload nginx. Next, run certbot --nginx -d code.example.net to enable HTTPS for your subdomain. This will automatically create the required certificate, compliments of Let’s Encrypt, and make a few changes to the configuration file you just created. These changes will be marked with comments.

Certbot can periodically renew certificates for you so you don’t wind up with expired certificates. Consult the documentation for how to set that up.

Forge Ahead!

At this point you are ready to go. Install Fossil by running guix package -i fossil, then create a repository in ~/repos to test your setup by running fossil init ~/repos/test.fossil. Initializing a repository automatically creates a password for you that you can use to login at https://code.example.net/test.