Gogs, the self-hosted Git service


I’ve noticed that @moul is already working on an image:

… but thought, why be pinned down to specific OS version with something so loosely coupled like a Go application. So I’ve made a package for Debian/Ubuntu which I’d like to share with you.
You will need ≥30 MB space on disk and, for 1–2 users, 40–60 MB free memory.

# ubuntu ≥ 15.04 has ECDSA support, which is needed
apt-get -y install apt-transport-https

printf "deb https://s.blitznote.com/debs/ubuntu/armhf/ arm7/" \
  > /etc/apt/sources.list.d/blitznote.list
printf 'Package: *\nPin: origin "s.blitznote.com"\nPin-Priority: 510\n' \
  > /etc/apt/preferences.d/blitznote

apt-get update

# redis-server is optional, but recommended
apt-get install -y redis-server
# This is not GPG signed, but pulled through HTTPS.
# I sign packages with 'signify'.
apt-get install -y --force-yes gogs

Prime Redis:

systemctl enable redis-server
systemctl start redis-server

Run Gogs for the first time, to go through the installation screen, which will be filled with defaults I’ve selected having installations on Scaleway in mind. We do this manually here so you can spot errors early on:

sudo -u git -g git /bin/bash
USER=git HOME=/var/lib/gogs /opt/gogs/gogs web

# visit http://<your-ip>:80/ and go through installation
# Remember to modify the domain name, and to create a first user at the very bottom of the page!
# You can leave everything else as it is.

# Terminate *gogs* by pressing ctrl+c.

nano /opt/gogs/custom/conf/app.ini
# Gogs has a bug and overwrite cache.ADAPTER and/or session.PROVIDER.
# Please set it to "= redis".
# You might want to tinker with logging verbosity later or change Gogs's port number.
# press ctrl+x y to exit

exit # no longer user 'git'

Nice! Let’s finalize everything by handing Gogs over to systemd:

systemctl enable gogs
systemctl start gogs

Notable folders, backup these:

  • /srv/git — will contain the GIT repositories. If Scaleway’s object storage worked for me I would try to mount that directory from there. Or from a dedicated volume.
  • /var/lib/gogs — will contain everything non-ephemeral, not-cached, related to Gogs. Like custom avatars.


In case you want to compile Gogs yourself, or create a more recent *.deb, here is how:

# gccgo-5 brings us go 1.4.2
# Use it for bootstrapping only, because gccgo is slow!
apt-get -y install silversearcher-ag git gccgo-5
update-alternatives --set go /usr/bin/go-5

# We will compile Go as regular user.
# After long and thoughtful consideration I am going here with 'mark'.
adduser --disabled-login --gecos 'Mark' mark

su - mark
cd /tmp
curl -fLRO https://storage.googleapis.com/golang/go1.5.src.tar.gz
tar -xaf go1.5.src.tar.gz
mv go go1.5
cd go1.5/src
GOROOT_BOOTSTRAP=/usr GOOS=linux GOARCH=arm GOARM=7 ./make.bash
exit # no longer user 'mark'

apt-get -y remove gccgo-5 && apt-get -y autoremove
update-alternatives --set go /tmp/go1.5/bin/go

Now on to Gogs itself:

export GOPATH=$(mktemp -d)
GOOS=linux GOARCH=arm \
go get -v -u -tags "sqlite redis" github.com/gogits/gogs
# grab a bratwurst: downloads take a few minutes

find "${GOPATH}" -name gogs -executable -type f

Yes, that file, that’s all you need. You might want to update folders templates and public, too. They reside in ${GOPATH}/src/github.com/gogits/gogs/{templates,public}.

My *.deb can be recycled like this, in our case:

export VERSION="0.6.X.ZZZZ"
export WORKDIR=$(mktemp -d)
cd "${WORKDIR}"

curl --pinnedpubkey "sha256//fxBZ92Ul/3NOZJsiNJLhv5wHfywCe9PZvHWI6rd6frU=" \
  -fLRO https://s.blitznote.com/debs/ubuntu/armhf/arm7/gogs-
ar x gogs-
mkdir -p "gogs-${VERSION}/DEBIAN"
tar -xaf control.tar.gz -C "gogs-${VERSION}/DEBIAN/"
tar -xapf data.tar.xz -C "gogs-${VERSION}/"

rm *.deb debian-binary *.tar.*

Now that you have extracted everything: modify templates, update the gogs binary.

Finally, use find -name control -type f and edit that file updating version number and including your name.

This is how you create the new *.deb:

cd "${WORKDIR}"
apt-get -y install dpkg-dev

dpkg-deb -z9 -Zxz --build "gogs-${VERSION}"