The F-Droid website is built using Jekyll and gitlab-ci. The whole website now works using a standard git “fork” workflow that is well supported by gitlab, and well known from services like GitHub. For all of the pages and information about apps and packages distributed by f-droid.org, those pages are generated using our jekyll-fdroid plugin, which takes the content from the f-droid.org index file.
Staging on development forks
All development forks of fdroid-website automatically have a staging server setup and maintained by the gitlab-ci configuration. This automatically deploys the content of the fork’s master branch to GitLab Pages. For example, nicoalt’s git fork is at https://gitlab.com/nicoalt/fdroid-website, and the master branch from that is automatically deployed to https://nicoalt.gitlab.io/fdroid-website.
Deploying merge request branches
The current gitlab-ci setup is optionally capable of pushing the resulting HTML to a live webserver and linking to it automatically from the GitLab merge request, deploying to surge.sh.
Doing so will allow for easier review of your merge requests, but is not required. If you don’t follow the steps below, your merge requests will still run through the gitlab-ci continuous integration checks, but the resulting HTML will not be accessible online.
To configure this:
- Install the surge.sh CLI:
npm install surge
- Signup for surge.sh:
- Get a “token” to allow CI to deploy on your behalf:
- Add two “Secret Variables” to your fork of this project:
- Navigate to your projects Settings -> CI/CD Pipelines -> Secret Variables.
- Add the following two variables:
SURGE_LOGIN: The email you used to signup with
SURGE_TOKEN: The value given when you ran
Now your CI jobs should be authorized to deploy to surge.sh, and the GitLab merge requests screen will automatically link to this deployment.
Staging of the official website
Like with forks, the master branch of the main git repo for the website, https://gitlab.com/fdroid/fdroid-website, is automatically deployed to https://fdroid.gitlab.io/fdroid-website. That is the place to review the current state of the website before tagging a release.
Deploying to https://f-droid.org
When an update to the website is tested and ready to go, a release manager creates a PGP-signed release tag in the main git repo. The deploy server monitors the main git repo for new tgs. When it sees a new tag, it first checks the PGP signature on the git tag using a manually configured GnuPG keyring that contains only the public keys of the PGP keys that are allowed to tag website releases.
After the git tag is verified, the
f-droid.org target in
is run to generate the actual files for the site. Those files are
then copied into place on the f-droid.org servers.
The deploy tags use a “semantic versioning” naming scheme:
- <minor> is incremented on each deployment
- <major> is only incremented when there are major changes
Setting up and running the deploy procedure
The deploy procedure was tested on a machine running Debian/stretch.
It should be triggered whenever the repo index is published, so it can
rebuild with the latest app information. This whole procedure can be
run as root, or just
gitlab-runner. This final procedure is not
part of a script committed into the website git repo so that the
commands that run outside of docker cannot be modified via git.
- setup docker
- setup gitlab-ci-multi-runner
- prepare deploy-whitelist-keyring.gpg using GnuPG:
$ gpg --recv-keys 00aa5556 $ gpg --fingerprint 00aa5556 # verify it! $ gpg --export 00aa5556 > /path/to/deploy-whitelist-keyring.gpg
- get the website source code:
$ git clone https://gitlab.com/fdroid/fdroid-website
- run the generation:
$ cd fdroid-website $ git fetch --tags $ sudo gitlab-runner exec docker f-droid.org \ --pre-build-script ./prepare-for-deploy.py \ --docker-volumes "/path/to/deploy-whitelist-keyring.gpg:/root/.gnupg/pubring.gpg:ro" \ --docker-volumes `pwd`/_site:/builds/output --env DEPLOY_DIR=/builds/output
- deploy the site’s files to the webserver, while preventing the
jekyll generated files from overwriting
parts of the website
that other things manage:
$ rsync -ax --delete --exclude-from=_site/build/.rsync-deploy-exclude-list _site/build/ f-droid.org:/var/www/
The F-Droid website is translated into several languages. Two things are required to ensure this works.
The first is taken care of by
.gitlab-ci.yml, which is to run the
This ensures that each
.html file is replaced with an Apache2 TypeMap.
The second is to add the following to the Apache2 server or VirtualHost config so that the TypeMaps are used correctly,
telling apache where to find the translated version of the file (replace
/var/www/html with the actual webroot):
<Files *.html> SetHandler type-map </Files> # virtualize the language sub"directories" AliasMatch ^(?:/\w\w/)?(.*)?\$ /var/www/html/\$1 # Tell mod_negotiation which language to prefer SetEnvIf Request_URI ^/(\w\w)/ prefer-language=\$1
If this is not done or done incorrectly, then you will see something like the following when viewing any page:
URI: index.html.en Content-language: en Content-type: text/html URI: index.html.fr Content-language: fr Content-type: text/html
This is the result of the actual TypeMap being returned to the browser, rather than the translated file.
Note that this also depends on
mod_negotiation being enabled, but this happens by default when
installing apache2 on Debian.