My Current Single-User Fossil Server Setup
Git was the first proper version control software I've used, and I've only used Git till now; I believe that one should learn as many ways of solving the same problem as possible so that he would not be biased and have a better imagination and intuition at solving similar problems; and "only know about Git" does not align with that idea very well, so I decided to try out other solutions.
The one I've decided that I would use, at least for now, is Fossil. It is made by the team who made SQLite, it is the VCS used by SQLite, and it comes with a lot of very handy things; all the Git setups I've used (GitLab; Gitea; cgit + gitolite) did not come as efficient as Fossil for my use case of "one single dev hosting his own stuff" in terms of resource usage and functionalities.
I've recently switched to a new server running Debian (the previous one runs Arch and it somehow broke when I was doing pacman -Syu
); it is quite easy to setup, and I shall record how I did that there.
First install NGINX:
apt-get install nginx systemctl enable nginx systemctl start nginx
And Fossil:
apt-get install fossil
And create a user specially for hosting Fossil repositories. Things like Gitea and GitLab also do the same thing; if you have ever cloned with SSH you should have noticed that the remote URL is like git@git.[domain]
; the git
part before the at sign is the user name for the user that deals with all hosted Git repositories.
useradd -m fossil # we will put the things in /home/fossil/museum. # "museum" is a Fossil convention; you can put it anywhere else. mkdir ~/museum
We need to setup Fossil as a daemon. Put this in /etc/systemd/system/fossil.service
:
[Unit] Description=Fossil server After=network-online.target [Service] User=fossil Group=fossil WorkingDirectory=/home/fossil/museum ExecStart=/usr/bin/fossil server --port 19001 . --files '*.txt,*.html,*.css,*.svg,*.png' Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
Basically what we are doing here is to start Fossil's built-in web server and bind it to port 19001. We select the current working directory, so that all Fossil repositories (they are in the form of SQLite databases) whose file name ends with .fossil
would have a web interface. The *.txt,*.html,*.css,*.svg,*.png
part is to config the extension names of the files that would be served by the Fossil server as static files. The reason you might want to do this is that when selecting a directory for the Fossil web server the root route (i.e. /
) does not work (it would return 404, because there isn't a repository that matches the root route) until you add the --repolist
argument, but it really only gives a list of repository it has found and it seems like there's no way to customize that (or maybe I just didn't read enough documentation). Anyway, in my setup I redirected /
to /index.html
and configured Fossil to serve /index.html
as a static file (this will be mentioned later).
And then start Fossil:
systemd daemon-reload systemd enable fossil systemd start fossil
And then we can put fossil repo in /home/fossil/museum
; they should be available at [ip]:19001/[Name]
. The setup of domain name comes later.
Now, setup nginx reverse proxy like this:
location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:19001; }
Setup your domain, wait for the DNS record to propagate, and then run certbot (for https). After that, edit the fossil service file and reload. First change the service file:
ExecStart=/usr/bin/fossil server --port 19001 . --files '*.txt,*.html' --https
And then reload:
systemd daemon-reload systemd restart fossil.service
Now it's a good time to configure the repository to have the correct base URL.
Setup index redirect at NGINX config like I've mentioned above:
location = / { absolute_redirect off; return 301 /index.html; } location = /index.html { try_files $uri =404; }
Restart NGINX service. After nginx restart, these things should happen:
https://[domain]/
should bring you tohttps://[domain]/index.html
which should load the index.html file.https://[domain]/[repo-name]
should bring you to the page for the repo[repo-name]
.
Now, the simplest method of managing repos (i.e. uploading & deleting) is to do it via sftp; this requires your ssh keys to be authorized for the fossil user. Put your public key in /home/fossil/.ssh/authorized_keys
.
After the last step, everything should be done. To push & pull via ssh, you need to use the full url:
fossil update ssh://[username]@[domain]/[path-to-your-fossil-repo-file]
in my setup the username
is fossil and the files are at /home/fossil/museum
, so for repo fossiltest.fossil
the command is:
fossil update ssh://fossil@[domain]//home/fossil/museum/fossiltest.fossil
Good thing in most of the time I only need to do this once since Fossil remembers the last URL you synced with.
Last update: 2024.7.12