UP | HOME

[17may2026] setting up git on a cloud host

Table of Contents

1. Problem

Github increasingly flaky, want to have an alternative.

2. Plan

Setup git hosting on a rented droplet.

Ingredients:

DNS register.com conybeare.us
host digitalocean.com 159.203.164.149

2.1. DNS

  1. login to register.com account. drop register.com's nameservers, replace them with digital ocean's

    NS ns1.digitalocean.com
    NS ns2.digitalocean.com
    NS ns3.digitalocean.com
  2. login to digitalocean.com console, under Networking add similar domain records alogn with an A records

    A conybeare.us 159.203.164.149
    NS conybeare.us directs to ns1.digitalocean.com
    NS conybeare.us directs to ns2.digitalocean.com
    NS conybeare.us directs to ns3.digitalocean.com

    I created record at domain root, so everything forwards to the chosen address

  3. confirm working

    $ nslookup conybeare.us
    Server:            127.0.0.53
    Address:   127.0.0.53#53
    
    Non-authoritative answer:
    Name:      conybeare.us
    Address: 159.203.164.149
    

2.2. Nix

Setup nixpkgs.

# on 159.203.164.149
$ sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon

We will also want system services to be able to use flakes

# /etc/nix/nix.conf

build-users-group = nixbld
trusted-users = root @wheel
experimental-features = nix-command flakes    # <-- adding this

2.3. Forgejo

2.3.1. Forgejo user

Add user

$ sudo useradd --system --shell /bin/false --home /var/lib/forgejo forgejo
$ sudo mkdir -p /var/lib/forgejo /var/log/forgejo
$ sudo mkdir -p /var/lib/forgejo/lfs
$ sudo mkdir -p /var/lib/forgejo/gitea-repositories
$ sudo chown -R forgejo:forgejo /var/lib/forgejo /var/log/foregejo

Forgejo setup

$ sudo mkdir -p /etc/forgejo

create /etc/foregejo/app.ini:


[server]
ROOT_URL = https://conybeare.us/git/
APP_DATA_PATH = /var/lib/forgejo
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
START_SSH_SERVER = true
SSH_LISTEN_PORT = 2222
SSH_USER = forgejo
SSH_PORT = 2222

[database]
DB_TYPE = sqlite3
PATH = /var/lib/forgejo/forgejo.db

[repository]
ROOT = /var/lib/forgejo/gitea-repositories

[ui]
DEFAULT_THEME = forgejo-dark
INSTANCE_SLOGAN = Mad Science, all the way down

[lfs]
PATH = /var/lib/forgejo/lfs
STORAGE_TYPE = local

[log]
ROOT_PATH = /var/log/forgejo
MODE = file
LEVEL = info

[mailer]
ENABLED = false

$ sudo chown forgejo:forgejo /etc/forgejo/app.ini
$ sudo chmod 600 /etc/forgejo/app.ini

2.3.2. Runtime environment for forgejo

We want to use nix for this:

# /etc/forgejo/nix/flake.nix

{
  description = "Forgejo environment";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system :
      let pkgs = nixpkgs.legacyPackages.${system};
      in {
        packages.default = pkgs.forgejo;
        apps.forgejo = {
          type = "app";
          program = "${pkgs.forgejo}/bin/forgejo";
        };
        devShells.default = pkgs.mkShell {
          buildInputs = [ pkgs.forgejo ];
        };
      }
    );
}

To verify syntax (will also fetch all the deps)

$ nix flake show /etc/forgejo/nix
$ ls /etc/forgejo/nix/flake.lock   # now pinned

2.3.3. Systemd setup (Forgejo)


[Unit]
Description=Forgejo
After=network.target

[Service]
Type=simple
User=forgejo
Group=forgejo
WorkingDirectory=/var/lib/forgejo
ExecStart=/nix/var/nix/profiles/default/bin/nix run /etc/forgejo/nix#forgejo -- -c /etc/forgejo/app.ini web
Restart=always
RestartSec=5

Environment="HOME=/var/lib/forgejo"

[Install]
WantedBy=multi-user.target

then setup

$ sudo systemctl daemon-reload
$ sudo systemctl enable forgejo
$ sudo systemctl start forgejo

2.3.4. Verify status

$ sudo systemctl status forgejo
$ sudo journalctl -u forgejo -n 3
May 18 02:16:21 vpn1 nix[1043231]: Listen: http://127.0.0.1:3000
May 18 02:16:21 vpn1 nix[1043231]: AppURL(ROOT_URL): https://conybeare.us/
May 18 02:16:21 vpn1 nix[1043231]: Starting new Web server: tcp:127.0.0.1:3000 on PID: 1043231

2.4. Proxy Magic

2.4.1. Certificates

$ sudo /nix/var/nix/profiles/default/bin/nix run nixpkgs#certbot -- certonly --standalone -d conybeare.us
$ tree /etc/letsencrypt
/etc/letsencrypt/
├── accounts  [error opening dir]
├── archive  [error opening dir]
├── live  [error opening dir]
├── renewal
│   └── conybeare.us.conf
└── renewal-hooks
    ├── deploy
    ├── post
    └── pre

2.4.2. Nginx user

Add user

$ sudo useradd --system --shell /bin/false --home /var/cache/nginx nginx

Also working directories

$ sudo mkdir -p /var/cache/nginx
$ sudo chown nginx:nginx /var/cache/nginx
$ sudo chmod 755 /var/cache/nginx

$ sudo mkdir -p /var/log/nginx
$ sudo chown nginx:nginx /var/log/nginx
$ sudo chmod 755 /var/log/nginx

2.4.3. Nginx

/etc/nginx/nginx.conf:


events { }

http {
    server {
        listen 80;
        server_name conybeare.us:
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name conybeare.us;

        ssl_certificate /etc/letsencrypt/live/conybeare.us/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/conybeare.us/privkey.pem;

        location /git/ {
            proxy_pass http://127.0.0.1:3000/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

2.4.4. Runtime environment for nginx

Using nix again:

/etc/nginx/nix/flake.nix:


{
  description = "Nginx environment";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system};
      in {
        packages.default = pkgs.nginx;
        apps.nginx = {
          type = "app";
          program = "${pkgs.nginx}/bin/nginx";
        };
      }
    );
}

To verify syntax (and fetch deps)

$ nix flake show /etc/nginx/nix
$ ls /etc/nginx/nix/flake.lock

2.4.5. Systemd setup (Nginx)

/etc/systemd/system/nginx.service:


[Unit]
Description=Nginx
After=network.target

[Service]
Type=forking
# User=nginx # start as root, bind to ports 80/443; then drop to nginx user for workers
ExecStart=/nix/var/nix/profiles/default/bin/nix run /etc/nginx/nix#nginx -- -c /etc/nginx/nginx.conf
ExecReload=/nix/var/nix/profiles/default/bin/nix run /etc/nginx/nix#nginx -- -c /etc/nginx/nginx.conf -s reload
ExecStop=/nix/var/nix/profiles/default/bin/nix run /etc/nginx/nix#nginx -- -s quit

[Install]
WantedBy=multi-user.target

then ssetup

$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
$ sudo systemctl status nginx

$ systemctl status nginx
● nginx.service - Nginx
     Loaded: loaded (/etc/systemd/system/nginx.service; disabled; preset: enabled)
     Active: active (running) since Mon 2026-05-18 04:13:51 UTC; 4s ago
    Process: 1045381 ExecStart=/nix/var/nix/profiles/default/bin/nix run /etc/nginx/nix#nginx -- -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
   Main PID: 1045385 (nginx)
      Tasks: 2 (limit: 9489)
     Memory: 2.9M (peak: 145.4M)
        CPU: 1.281s
     CGroup: /system.slice/nginx.service
             ├─1045385 "nginx: master process /nix/store/6xi5jqgw6mqdvzk36285ywc17wnx1548-nginx-1.30.1/bin/nginx -c /etc/nginx/nginx.conf"
             └─1045386 "nginx: worker process"

May 18 04:13:50 vpn1 systemd[1]: Starting nginx.service - Nginx...
May 18 04:13:51 vpn1 nix[1045381]: nginx: [warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead in /etc/nginx/nginx.conf:11
May 18 04:13:51 vpn1 systemd[1]: Started nginx.service - Nginx.

2.5. Enable-on-boot

$ sudo systemctl enable nginx forgejo

2.6. Testing

$ curl  https://conybeare.us
<!DOCTYPE html>
<html lang="en-US" data-theme="forgejo-auto">
...

2.6.1. Forgejo install (web)

Now setup forgejo by visiting https://conybeare.us

Instance Slogan It's mad science, all the way down
Repository root path /var/lib/forgejo/gitea-repositories
Git LFS root path /var/lib/forgejo/lfs
Log path /var/log/forgejo
Administrator Account username, email, …

Author: Roland Conybeare

Created: 2026-05-24 Sun 18:48

Validate