~gitpocket/gitpocket

4
9a0689bbfd10584eedda3671e0cfd19aeb024766
mainfeed-discovery
gitpocket/INSTALL.md -rw-r--r--6.4 KiB ViewLogBlameView rawPermalink a6b5bf4fe7 feat(markdown): image attachments and preview 8 days ago

View source

Installation

gitpocket installs either as a container built from this repository or as a single binary under systemd. Both keep every piece of state in one data directory, /srv/gitpocket by default, and both expect nginx or another TLS proxy in front and the host's own sshd for git over SSH.

Requirements

A Linux host with git 2.38 or newer, which merge-tree --write-tree needs, and OpenSSH. Building from source needs Go 1.27 or newer, and the container route needs Docker with the compose plugin. 512 MB of memory is enough for a small instance.

Prepare the host

Create the account that owns the data and receives SSH logins. Its name appears in clone URLs, so git is the usual choice.

useradd -r -m -d /srv/gitpocket -s /bin/sh git

Docker

The compose file runs the server as the git account with a read only root filesystem, no capabilities, no-new-privileges, a 512 MB memory ceiling and the port bound to loopback only. It mounts /srv/gitpocket from the host, so the data outlives the container.

git clone https://gitpocket.io/~gitpocket/gitpocket /opt/gitpocket
cd /opt/gitpocket
printf 'GITPOCKET_HOST=git.example.org\nGITPOCKET_UID=%s\nGITPOCKET_GID=%s\n' $(id -u git) $(id -g git) > deploy/.env
docker compose -f deploy/compose.yaml up -d --build

The server trusts X-Forwarded-For from loopback and from the compose network gateway, 172.31.255.1, which is where connections from the host proxy appear. Change the subnet in deploy/compose.yaml if it collides with one you already use.

SSH logins are answered on the host, so copy the binary out of the image to the same path it has inside it. Repository hooks name that path, and the container and the host must agree on it.

docker cp gitpocket:/usr/local/bin/gitpocket /usr/local/bin/gitpocket

Binary

git clone https://gitpocket.io/~gitpocket/gitpocket && cd gitpocket
CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o gitpocket .
install -m 755 gitpocket /usr/local/bin/gitpocket
install -m 644 deploy/gitpocket.service /etc/systemd/system/

Replace git.example.org in /etc/systemd/system/gitpocket.service with your hostname, then start it.

systemctl daemon-reload
systemctl enable --now gitpocket

The unit sets GOMEMLIMIT to 192 MiB, caps the server and every git it starts at 512 MB, and allows writes only beneath /srv/gitpocket.

Reverse proxy

deploy/nginx.conf is a complete site. Set server_name and the certificate paths, then install it.

cp deploy/nginx.conf /etc/nginx/sites-available/gitpocket
ln -s ../sites-available/gitpocket /etc/nginx/sites-enabled/
certbot certonly --nginx -d git.example.org
nginx -t && systemctl reload nginx

Whatever proxy you use has to forward Host and X-Forwarded-Proto, set X-Forwarded-For to the client address, turn request buffering off and allow large bodies, otherwise bigger HTTPS pushes are cut short. The server takes the last address in X-Forwarded-For, so a client cannot pick its own rate limit bucket.

SSH

Add this to the end of /etc/ssh/sshd_config and reload sshd.

Match User git
    AuthenticationMethods publickey
    PasswordAuthentication no
    AuthorizedKeysFile none
    AuthorizedKeysCommand /usr/local/bin/gitpocket -root /srv/gitpocket keys %u %h %t %k
    AuthorizedKeysCommandUser root
    PermitTTY no
    DisableForwarding yes

keys opens the database read only and answers with a forced command of gitpocket shell <user>, which checks the requested repository and permission before it execs git upload-pack or git receive-pack. Nothing is left running after the push. If the account is not called git, pass -ssh-user to serve so the clone URLs match.

First run

Open the site, sign up, then grant yourself administration and choose how others join.

sudo -u git gitpocket admin you
sudo -u git gitpocket registration invite

Under Docker the same commands run as docker exec gitpocket gitpocket admin you. Registration starts open, invite hands out single use links from /admin, and closed leaves gitpocket user <name> as the only way in, with the password read from stdin.

Configuration

serve takes its settings as flags.

Flag Default Meaning
-host localhost public hostname used in clone URLs, mail and feeds
-name gitpocket site name shown in the header
-listen 127.0.0.1:3200 address the HTTP server binds
-ssh-user git account shown in SSH clone URLs
-proxy none comma separated networks, besides loopback, whose X-Forwarded-For is trusted

The data directory holds a few optional files, each read once at startup. logo.png replaces the header logo and icon.png the favicon. smtp.json enables mail, and gitpocket quota 2G sets a per owner disk quota that pushes are checked against.

Mail

Mail is optional. Without it nobody receives notifications and password resets go through gitpocket passwd <name>. Plain SMTP takes host, port, user, password, from and starttls. Many VPS providers block outbound submission ports, so api and key post to a Resend compatible endpoint instead, and account and token use the Cloudflare email API.

{"api": "https://api.resend.com/emails", "key": "re_...", "from": "gitpocket <noreply@git.example.org>"}

Save it as /srv/gitpocket/smtp.json, readable only by git, restart the server and send a test with gitpocket mail you@example.org.

Backups

gitpocket backup <dir> writes a dated copy of the database with vacuum into, keeps the last fourteen, and bundles every repository whose refs changed since its previous bundle and copies new image attachments. The supplied timer runs it nightly into /srv/gitpocket/backups, which should then be copied off the host.

install -m 644 deploy/gitpocket-backup.service deploy/gitpocket-backup.timer /etc/systemd/system/
systemctl enable --now gitpocket-backup.timer

To restore, stop the server, put the newest database back as gitpocket.db, and git clone --mirror each bundle to repos/<owner>/<name>.git and copy attachments back. The server reinstalls repository hooks when it starts.

Upgrading

Back up first. Schema changes are applied automatically when the server starts.

cd /opt/gitpocket && git pull
docker compose -f deploy/compose.yaml up -d --build
docker cp gitpocket:/usr/local/bin/gitpocket /usr/local/bin/gitpocket

For a binary install, rebuild, install the new binary over the old one and systemctl restart gitpocket.