Fossil Scm
Overview
Fossil is a simple, high-reliability, distributed version control system. Unlike most version control tools, it bundles everything a small project needs into one self-contained executable: distributed source control, a bug tracker, a wiki, a forum, a chatroom, technotes and an integrated web interface, all backed by a single SQLite database file that is the entire repository. There is nothing else to install and nothing external to run.
The SecureAnyCloud image installs Fossil 2.28 behind an nginx reverse proxy. The proxy binds the server to loopback, rate-limits inbound requests and caps the request size.
Fossil has a real administrator login, and the image is secure by default. Anonymous and unauthenticated visitors are read-only: they can browse the timeline, read the wiki and tickets and clone the repository, but they cannot commit, edit the wiki or file tickets. The administrator password is not baked into the image. On each virtual machine's first boot, fossil-firstboot.service generates a fresh empty repository and a unique random admin password, and writes the password to a root-only file at /root/fossil-info.txt.
What you get:
- Fossil 2.28 single official binary (
/usr/local/bin/fossil) - A single SQLite repository at
/var/lib/fossil/repo.fossil(no separate database to maintain) fossil.servicerunning as thefossiluser, bound to loopback127.0.0.1:8081nginx.servicereverse proxy on TCP 80, TLS-ready and rate-limited (10 requests per second, burst 40)fossil-firstboot.servicegenerating a fresh repository and a per-VM admin password on first boot- Anonymous write disabled: unauthenticated and anonymous users are read-only
- Ubuntu 24.04 LTS base, latest patches, unattended security upgrades enabled
- 24/7 SecureAnyCloud support, 24h response SLA
Prerequisites
You need an active Azure subscription, an SSH key, and a VNet with a subnet. The recommended VM size is Standard_B2s. Fossil is very light, and 4 GB RAM is plenty.
Deploy from the Azure Portal
Search the Azure Marketplace for Fossil, choose the plan, and create the VM. In the networking step, attach an NSG that allows inbound TCP 22 (SSH) and TCP 80 (the web UI) from your client networks only. For production, put a TLS reverse proxy in front of port 80.
Deploy from the Azure CLI
RG="fossil-prod"; LOCATION="eastus"; VM_NAME="fossil-01" IMAGE_URN="sac1647283583153:fossil-scm-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name fossil-vnet --address-prefix 10.104.0.0/16 --subnet-name fossil-subnet --subnet-prefix 10.104.1.0/24 az network nsg create -g "$RG" --name fossil-nsg az network nsg rule create -g "$RG" --nsg-name fossil-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name fossil-nsg --name allow-web --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:fossil-scm-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name fossil-vnet --subnet fossil-subnet --nsg fossil-nsg --public-ip-sku StandardConnect via SSH
ssh azureuser@<vm-ip>fossil.service, nginx.service and fossil-firstboot.service all start automatically on first boot.
Verify the Service
sudo systemctl is-active fossil nginx fossil-firstboot
sudo test -f /var/lib/sac/data/fossil-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':80 |:8081 'The expected output shows that all services are active, nginx is bound to the public port 80, and Fossil is bound to loopback 127.0.0.1:8081 only:
active active active FIRSTBOOT_DONE LISTEN 0 10 127.0.0.1:8081 0.0.0.0:* users:(("fossil",...)) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...))Secure by Default
Fossil binds only to loopback and is fronted by nginx, which rate-limits requests and caps the request size. On first boot, a fresh empty repository and a per-VM admin password are generated and written to a root-only note:
sudo cat /root/fossil-info.txt
sudo ss -tlnp | grep 8081 grep -E 'limit_req|client_max_body_size' /etc/nginx/conf.d/sac-fossil-ratelimit.conf /etc/nginx/sites-available/sac-fossilThe note contains the per-VM admin password (unique to this machine, never baked into the image) and the resolved URL:
FOSSIL_ADMIN_USER=admin FOSSIL_ADMIN_PASSWORD=<FOSSIL_ADMIN_PASSWORD> FOSSIL_URL=http://<vm-ip>/Anonymous write is disabled. The nobody user (every unauthenticated visitor) and the anonymous user (captcha login) have read-only Fossil capabilities. The admin user has the setup capability and is the only writer:
sudo runuser -u fossil -- env HOME=/var/lib/fossil fossil user list -R /var/lib/fossil/repo.fossil for u in admin nobody anonymous; do echo "$u: $(sudo runuser -u fossil -- env HOME=/var/lib/fossil fossil user capabilities $u -R /var/lib/fossil/repo.fossil)" doneThe capability string ghjorz is read-only (clone, hyperlinks, read wiki, check out, read tickets, download). It contains none of the check-in, wiki write, ticket write or unversioned write capabilities:
admin: s nobody: ghjorz anonymous: ghjorzLog In as the Administrator
Read the per-VM admin password from the root-only note, and then confirm that it authenticates. A valid admin session can reach the /setup page (HTTP 200), while an anonymous request is redirected to the login page:
ADMIN_PW="<FOSSIL_ADMIN_PASSWORD>" curl -s -c /tmp/fossil-cookies --data-urlencode "u=admin" --data-urlencode "p=$ADMIN_PW" http://127.0.0.1/login -o /dev/null echo "admin /setup -> HTTP $(curl -s -b /tmp/fossil-cookies -o /dev/null -w '%{http_code}' http://127.0.0.1/setup)" echo "anon /setup -> HTTP $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/setup)" rm -f /tmp/fossil-cookiesThe expected output shows that the admin session reaches the setup page while the anonymous request is redirected:
admin /setup -> HTTP 200 anon /setup -> HTTP 302In a browser, open http://<vm-ip>/ and click Login. Sign in as admin with the password from /root/fossil-info.txt. For production, put TLS in front of port 80 (see Step 13) so the password is never sent in the clear.
Browse the Timeline
The timeline is the home of the repository. It shows every check-in, wiki edit, ticket change and forum post in reverse chronological order, with branch tags and links to each artifact:
curl -s -o /dev/null -w 'timeline -> HTTP %{http_code}\n' http://127.0.0.1/timelineUse the Wiki
Fossil has a built-in wiki. Pages can be written in Fossil wiki markup or in Markdown. Open the Wiki tab to browse and edit pages. Anonymous visitors can read them, but only authenticated users with the wiki capability can edit:
Track Bugs with Tickets
The built-in ticket system is a full bug tracker. Open the Tickets tab, choose the All Tickets report to list every ticket, or select New Ticket to file one. Each ticket has a type, status, priority and full change history:
Clone and Work with the Repository
From a workstation that has Fossil installed, clone the repository over HTTP using the admin credentials (replace <vm-ip> with your VM's address), open a working checkout, then add files and commit. Because Fossil is distributed, every clone is a full copy of the repository, its wiki and its tickets:
fossil clone http://admin@<vm-ip>/ myrepo.fossil mkdir myrepo && cd myrepo fossil open ../myrepo.fossil echo "hello" > README.md fossil add README.md fossil commit -m "Add README"Server Components
Components and paths:
Fossil binary /usr/local/bin/fossil
Repository (single SQLite file) /var/lib/fossil/repo.fossil
Systemd unit /etc/systemd/system/fossil.service
Firstboot script /usr/local/sbin/fossil-firstboot.sh
nginx site /etc/nginx/sites-available/sac-fossil
Per VM info note /root/fossil-info.txt (mode 0600)
Sentinel /var/lib/sac/data/fossil-firstboot.done
fossil version ls /usr/local/bin/fossil /var/lib/fossil/repo.fossilManaging the Service
sudo systemctl restart fossil.service
sudo journalctl -u fossil.service --no-pager -n 20The fossil command line administers the repository directly. For example, list the users, add a developer with commit rights, or change the admin password:
sudo runuser -u fossil -- env HOME=/var/lib/fossil fossil user list -R /var/lib/fossil/repo.fossilAdd TLS (Optional)
For production, terminate TLS at nginx. Point a DNS A record for <your-domain> at your VM's public address (<vm-ip>), then use the packaged nginx with a certificate from Let's Encrypt:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>certbot installs the certificate, rewrites the nginx server block to listen on 443 and sets up automatic renewal. Serving Fossil over HTTPS also means that the login password is no longer sent in the clear.
Security Recommendations
- Restrict the NSG so that ports 80 and 22 only reach trusted networks.
- Terminate TLS at nginx (Step 13) so that the admin password and repository content travel encrypted.
- Keep anonymous access read-only. The image ships with the
nobodyandanonymoususers restricted to read-only capabilities. Grant write capabilities only to named users you trust. - Keep the rate limit in
/etc/nginx/conf.d/sac-fossil-ratelimit.conf. Fossil has no built-in denial-of-service mitigation, so the reverse proxy limit is what protects it. - Back up
/var/lib/fossil/repo.fossilto Azure Blob. The whole repository, including its wiki and tickets, is that one file. - Patch the OS monthly with
sudo apt-get update && sudo apt-get upgrade. Unattended security upgrades are already enabled.
Support and Licensing
Fossil is distributed under the 2-clause BSD license, with no per-CPU or per-user fee. SecureAnyCloud provides commercial support separately.
- Email: sales@secureanycloud.com
- Website: secureanycloud.com
- Support hours: 24/7, 24h response SLA
Deploy on Azure
Launch Fossil on Ubuntu 24.04 with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7. sales@secureanycloud.com
Deploy on Azure
Launch Fossil on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Fossil is a simple, high-reliability, distributed version control system. Unlike most version control tools, it bundles everything a small project needs into one self-contained executable: distributed source control, a bug tracker, a wiki, a forum, a chatroom, technotes and an integrated web interface, all backed by a single SQLite database file that is the entire repository. There is nothing else to install and nothing external to run.
The SecureAnyCloud image installs Fossil 2.28 behind an nginx reverse proxy. The proxy binds the server to loopback, rate-limits inbound requests and caps the request size.
Fossil has a real administrator login, and the image is secure by default. Anonymous and unauthenticated visitors are read-only: they can browse the timeline, read the wiki and tickets and clone the repository, but they cannot commit, edit the wiki or file tickets. The administrator password is not baked into the image. On each instance's first boot, fossil-firstboot.service generates a fresh empty repository and a unique random admin password, and writes the password to a root-only file at /root/fossil-info.txt.
What you get:
- Fossil 2.28 single official binary (
/usr/local/bin/fossil) - A single SQLite repository at
/var/lib/fossil/repo.fossil(no separate database to maintain) fossil.servicerunning as thefossiluser, bound to loopback127.0.0.1:8081nginx.servicereverse proxy on TCP 80, TLS-ready and rate-limited (10 requests per second, burst 40)fossil-firstboot.servicegenerating a fresh repository and a per-instance admin password on first boot- Anonymous write disabled: unauthenticated and anonymous users are read-only
- Ubuntu 24.04 LTS base, latest patches, unattended security upgrades enabled
- 24/7 SecureAnyCloud support, 24h response SLA
Connecting to your instance
Connect over SSH on port 22 as the default login user for the operating system variant that you launched. For Ubuntu 24.04 LTS, the SSH login user is ubuntu. Fossil is served on port 80 through nginx, and the web UI is at http://<public-ip>/.
ssh ubuntu@<public-ip>Prerequisites
You need an AWS account, an EC2 key pair in your Region, and a VPC with a public subnet. The recommended instance type is m5.large. Fossil is very light, and a smaller type also works.
For production, put a TLS reverse proxy or an Application Load Balancer in front of port 80.
Deploy from the AWS Console
In the AWS Marketplace, subscribe to Fossil SCM, then choose Launch through EC2. Pick the m5.large instance type, select your key pair, and attach a security group that allows inbound TCP 22 (SSH) and TCP 80 (the web UI) from your client networks only. Launch the instance.
Deploy from the AWS CLI
AMI_ID="<the-marketplace-ami-id>"
# from the Marketplace listing, for your Region KEY_NAME="my-key" SG_ID="sg-xxxxxxxx"
# a security group allowing TCP 22 + 80 SUBNET_ID="subnet-xxxxxxxx"
# a public subnet aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type m5.large \
--key-name "$KEY_NAME" \
--security-group-ids "$SG_ID" \
--subnet-id "$SUBNET_ID" \
--associate-public-ip-address \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=fossil-01}]'Connect via SSH
ssh ubuntu@<public-ip>fossil.service, nginx.service and fossil-firstboot.service all start automatically on first boot.
Verify the Service
sudo systemctl is-active fossil nginx fossil-firstboot
sudo test -f /var/lib/sac/data/fossil-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':80 |:8081 'The expected output shows that all services are active, nginx is bound to the public port 80, and Fossil is bound to loopback 127.0.0.1:8081 only:
active active active FIRSTBOOT_DONE LISTEN 0 10 127.0.0.1:8081 0.0.0.0:* users:(("fossil",...)) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...))Secure by Default
Fossil binds only to loopback and is fronted by nginx, which rate-limits requests and caps the request size. On first boot, a fresh empty repository and a per-instance admin password are generated and written to a root-only note:
sudo cat /root/fossil-info.txt
sudo ss -tlnp | grep 8081 grep -E 'limit_req|client_max_body_size' /etc/nginx/conf.d/sac-fossil-ratelimit.conf /etc/nginx/sites-available/sac-fossilThe note contains the per-instance admin password (unique to this machine, never baked into the image) and the resolved URL:
FOSSIL_ADMIN_USER=admin FOSSIL_ADMIN_PASSWORD=<FOSSIL_ADMIN_PASSWORD> FOSSIL_URL=http://<public-ip>/Anonymous write is disabled. The nobody user (every unauthenticated visitor) and the anonymous user (captcha login) have read-only Fossil capabilities. The admin user has the setup capability and is the only writer:
for u in admin nobody anonymous; do echo "$u: $(sudo runuser -u fossil -- env HOME=/var/lib/fossil fossil user capabilities $u -R /var/lib/fossil/repo.fossil)" doneThe capability string ghjorz is read-only (clone, hyperlinks, read wiki, check out, read tickets, download). It contains none of the check-in, wiki write, ticket write or unversioned write capabilities:
admin: s nobody: ghjorz anonymous: ghjorzLog In as the Administrator
Read the per-instance admin password from the root-only note, and then confirm that it authenticates. A valid admin session can reach the /setup page (HTTP 200), while an anonymous request is redirected to the login page:
ADMIN_PW="<FOSSIL_ADMIN_PASSWORD>" curl -s -c /tmp/fossil-cookies --data-urlencode "u=admin" --data-urlencode "p=$ADMIN_PW" http://127.0.0.1/login -o /dev/null echo "admin /setup -> HTTP $(curl -s -b /tmp/fossil-cookies -o /dev/null -w '%{http_code}' http://127.0.0.1/setup)" echo "anon /setup -> HTTP $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/setup)" rm -f /tmp/fossil-cookiesThe expected output shows that the admin session reaches the setup page while the anonymous request is redirected:
admin /setup -> HTTP 200 anon /setup -> HTTP 302In a browser, open http://<public-ip>/ and click Login. Sign in as admin with the password from /root/fossil-info.txt. For production, put TLS in front of port 80 (see Step 13) so the password is never sent in the clear.
Browse the Timeline
The timeline is the home of the repository. It shows every check-in, wiki edit, ticket change and forum post in reverse chronological order, with branch tags and links to each artifact:
curl -s -o /dev/null -w 'timeline -> HTTP %{http_code}\n' http://127.0.0.1/timelineUse the Wiki
Fossil has a built-in wiki. Pages can be written in Fossil wiki markup or in Markdown. Open the Wiki tab to browse and edit pages. Anonymous visitors can read them, but only authenticated users with the wiki capability can edit:
Track Bugs with Tickets
The built-in ticket system is a full bug tracker. Open the Tickets tab, choose the All Tickets report to list every ticket, or select New Ticket to file one. Each ticket has a type, status, priority and full change history:
Clone and Work with the Repository
From a workstation that has Fossil installed, clone the repository over HTTP using the admin credentials (replace <public-ip> with your instance's address), open a working checkout, then add files and commit. Because Fossil is distributed, every clone is a full copy of the repository, its wiki and its tickets:
fossil clone http://admin@<public-ip>/ myrepo.fossil mkdir myrepo && cd myrepo fossil open ../myrepo.fossil echo "hello" > README.md fossil add README.md fossil commit -m "Add README"Server Components
Components and paths:
Fossil binary /usr/local/bin/fossil
Repository (single SQLite file) /var/lib/fossil/repo.fossil
Systemd unit /etc/systemd/system/fossil.service
Firstboot script /usr/local/sbin/fossil-firstboot.sh
nginx site /etc/nginx/sites-available/sac-fossil
Per instance info note /root/fossil-info.txt (mode 0600)
Sentinel /var/lib/sac/data/fossil-firstboot.done
/usr/local/bin/fossil version ls /usr/local/bin/fossil /var/lib/fossil/repo.fossilManaging the Service
sudo systemctl status fossil.service --no-pager | head -5 sudo runuser -u fossil -- env HOME=/var/lib/fossil fossil user list -R /var/lib/fossil/repo.fossilThe fossil command line administers the repository directly. For example, list the users, add a developer with commit rights, or change the admin password.
Add TLS (Optional)
For production, terminate TLS at nginx. Point a DNS A record for <your-domain> at your instance's public address, then use the packaged nginx with a certificate from Let's Encrypt:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>certbot installs the certificate, rewrites the nginx server block to listen on 443 and sets up automatic renewal. Serving Fossil over HTTPS also means that the login password is no longer sent in the clear. Alternatively, terminate TLS at an Application Load Balancer with your own certificate.
Security Recommendations
- Restrict the security group so that ports 80 and 22 only reach trusted networks.
- Terminate TLS at nginx (Step 13) or an Application Load Balancer so that the admin password and repository content travel encrypted.
- Keep anonymous access read-only. The image ships with the
nobodyandanonymoususers restricted to read-only capabilities. Grant write capabilities only to named users you trust. - Keep the rate limit in
/etc/nginx/conf.d/sac-fossil-ratelimit.conf. Fossil has no built-in denial-of-service mitigation, so the reverse proxy limit is what protects it. - Back up
/var/lib/fossil/repo.fossilwith EBS snapshots or AWS Backup. The whole repository, including its wiki and tickets, is that one file. - Patch the OS monthly with
sudo apt-get update && sudo apt-get upgrade. Unattended security upgrades are already enabled.
Support and Licensing
Fossil is distributed under the 2-clause BSD license, with no per-CPU or per-user fee. SecureAnyCloud provides commercial support separately.
- Email: sales@secureanycloud.com
- Website: secureanycloud.com
- Support hours: 24/7, 24h response SLA
Deploy on AWS
Launch Fossil on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7. sales@secureanycloud.com
Deploy on AWS
Launch Fossil SCM on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com