srcfort

A user-focused git hosting service which respects licenses and blocks code scraping, in particular for AI training.

It's meant for open- and close-source projects that want to ensure their code is not used for unintended purposes (for instance plagiarism, AI training without attribution, etc).

Overview

srcfort has the following components:

  • PostgreSQL database to store application data.
  • Caddy reverse proxy that routes request to the appropriate backend.
  • Git http backend to serve git pull and pushes.
  • API server written in golang serving API and pages.

To deploy all these components, you can use the included docker-compose.yaml script.

Deploying srcfort on-premise

srcfort is made up of different services:

  • A caddy reverse proxy to route requests.
  • An API server with the application.
  • A postgresql database for storing data.
  • A ssh service to enable secure git clones using SSH.
  • (optionally) a service which regularly backs up the data.

To manage all these services, srcfort uses docker compose. We support 2 configurations:

  • Running srcfort directly on port 80, 443 and 22, which is the default configuration and is easier to use, but requires an entire VM just for srcfort.
  • Running srcfort behind reverse proxy (for instance caddy, nginx, etc), so that you can share the VM with other services.

Running srcfort on port 80, 443 and 22

Clone this repository to the server, then set some environmental variables and run docker-compose from the root of the repo:

POSTGRES_PASSWORD=... JWT_SIGNING_KEY=... ROOT_URI=... docker compose up -d
  • POSTGRES_PASSWORD indicates the password for the database.
  • JWT_SIGNING_KEY is the key used to sign authentication tokens.
  • ROOT_URI is the address at which this instance is available (without http(s):// and trailing slash).

This will start all services. You can also use .env files instead.

Running srcfort behind reverse proxy

If you want to run srcfort on the same server as other applications, you probably want to run it behind reverse proxy.

This is tricky, because srcfort requires ssh access to the machine (for ssh git clones), which conflicts with SSH to manage the server (you probably manage your server using SSH).

Additionally, you need to handle TLS certificates by yourself, because it's not possible in most reverse proxies to proxy a HTTPSconnection by hostname (it would effectively be a man-in-the-middle, which TLS strives to eliminate).

The srcfort default configuration uses ports 80, 443 and 22, and you probably want to change that because that's where your reverse proxy is running.

Solutions:

  • Configure your server to accept SSH connections from another port, such as 10022. This can be done by (assuming you use a systemd-based distro):

    • /etc/ssh/sshd_config (change the Port setting).
    • Restart the ssh daemon with systemctl restart sshd
    • Connect to you server by using ssh <user>@<host> -p <port> instead of just ssh <user>@<host>.

    This leaves the port 22 free for git.

  • Edit the compose.yaml file to run the internal srcfort proxy on ports different than 80 and 443 (in this example 127.0.0.1:50805 and removing 443 as it's not needed if behind reverse proxy):

     services:
       ...
       proxy:
         ...
         ports:
    -       - "80:80"
    -       - "443:443"
    +       - "127.0.0.1:50805:80"
         ...
    
  • Install srcfort by setting AUTO_TLS=0 to disable automatic TLS in the internal reverse proxy that srcfort uses.

    Note that this must be set at build time of the proxy container. To ensure it, run AUTO_TLS=0 ROOT_URI=... docker compose build proxy and then rerun docker compose up.

    Then forward all requests from your domain/sub-domain to 127.0.0.1:50805 (or whatever host and port you used in the compose.yaml file above) using your favorite reverse proxy. You need to manually manage TLS certificate and their renewal.

Enabling backup to WebDAV

Run docker compose with --profile webdav_backup:

POSTGRES_PASSWORD=... JWT_SIGNING_KEY=... ROOT_URI=... \
  WEBDAV_BASE_URL=... WEBDAV_USER=... WEBDAV_PASSWORD=... \
  docker compose --profile webdav_backup up -d
  • WEBDAV_BASE_URL is used to do daily backups to this WebDAV folder.
  • WEBDAV_USER and WEBDAV_PASSWORD are used to authenticate to the WebDAV folder to backup the data.

The backup will run daily and copy all repositories, database and logs to the WebDAV folder. Automatic backup rotation is not supported right now.

Developing srcfort

Running locally in development mode

Run:

# Runs docker compose in dev mode with pre-configured secrets.
./scripts/dev.sh

The local server is accessible at http://localhost:8080 and supports all operations like the production one, but is reloaded automatically on file changes.

In this development environment, you can register a user with e-mail test@example.com which will also become site admin (see http://localhost:8080/admin).


The development environment also has a pre-configured pgAdmin instance (disabled by default since it's slow). To run pgAdmin use:

./scripts/dev.sh --profile full

The point your browser to http://localhost:8081, the credentials to authenticate are:

  • email: admin@admin.admin
  • password: admin

Running the integration tests

srcfort has an extensive test suite which uses javascript + AVA + puppeteer (headless chromium) to test different features of the application.

To run all tests, use:

./scripts/test.sh

This will start the services and run the tests. Or, if you already have all containers running in dev mode, you can also do:

./scripts/only-test.sh

Note: The tests depend on order and on the application state. Therefore, the only way to ensure that all tests pass correctly is erasing all volumes restarting the applications in a clean state.

It is still useful to run part of the test multiple times without restarting everything (because some tests do not depend on too much state).

Additional details

Reverse proxy

The integrated caddy reverse proxy requires these variables at docker image build time:

  • ROOT_URI the domain at which the service is running.
  • AUTO_TLS set to 0 or 1 to disable or enable automatic TLS (HTTPS). This only works if srcfort is exposed on ports 90, 443 and 22. Default to 1.

API server

The API server can be configured using the following environment variables:

  • ROOT_URI is the address at which this instance is available (without http(s):// and trailing slash).
  • POSTGRES_HOST, POSTGRES_USER, POSTGRES_PASSWORD to configure the database connection.
  • REPOSITORY_ROOT to configure where bare git repositories are stored.
  • JWT_SIGNING_KEY to sign authentication tokens.
  • STATIC_DIR to indicate the place where static files are available.
  • TEMPLATE_DIR to indicate where template files are available.
  • AUTHORIZED_KEY_PATH to indicate where SSH keys will be stored.
  • ADMIN_USER_EMAILS is a comma separated list (no whitespace) of user emails that are allowed to access the /admin area. Only put existing users in this list, otherwise an attacker can steal a free admin account by registering the correct e-mail.
  • TEST can be set to "1" to disable bot detection and making automated testing easer.

WebDAV backups

srcfort comes with pre-configured backups to a webdav folder. To configure this, the following environmental variables are available:

  • WEBDAV_BASE_URL is used to do daily backups to this WebDAV folder.
  • WEBDAV_USER and WEBDAV_PASSWORD are used to authenticate to the WebDAV folder to backup the data.