Developer Tools AWS

Fossil SCM on AWS User Guide

| Product: Fossil SCM on AWS

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 cloudimg image installs Fossil 2.28 and puts it behind an nginx reverse proxy that binds the server to loopback, rate limits inbound requests and caps the request size. Fossil has a real administrator login, and this image is secure by default: anonymous and unauthenticated visitors are read only, so they can browse the timeline, read the wiki and tickets and clone the repository, but cannot commit, edit the wiki or file tickets. The administrator password is not baked into the image. A fresh empty repository and a unique random admin password are generated on each instance's first boot by fossil-firstboot.service and written to a root only file at /root/fossil-info.txt.

What is included:

  • 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.service running as the fossil user, bound to loopback 127.0.0.1:8081
  • nginx.service reverse proxy on TCP 80, TLS ready, rate limited (10 requests per second, burst 40)
  • fossil-firstboot.service generating 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 cloudimg support, 24h response SLA

Connecting to your instance

Connect over SSH on port 22 as the default login user for the operating system variant you launched. Fossil is served on port 80 through nginx.

OS variant SSH login user Web UI
Ubuntu 24.04 LTS ubuntu http://<public-ip>/
ssh ubuntu@<public-ip>

Prerequisites

An AWS account, an EC2 key pair in your Region, and a VPC with a public subnet. Recommended instance type: m5.large (Fossil is very light; a smaller type also works). Put a TLS reverse proxy or an Application Load Balancer in front of port 80 for production.

Step 1: 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.

Step 2: 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}]'

Step 3: Connect via SSH

ssh ubuntu@<public-ip>

fossil.service, nginx.service and fossil-firstboot.service all start automatically on first boot.

Step 4: Verify the Service

sudo systemctl is-active fossil nginx fossil-firstboot
sudo test -f /var/lib/cloudimg/fossil-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':80 |:8081 '

Expected output — 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",...))

Step 5: 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/cloudimg-fossil-ratelimit.conf /etc/nginx/sites-available/cloudimg-fossil

The 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) are given read only Fossil capabilities, while 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)"
done

The 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: ghjorz

Step 6: Log In as the Administrator

Read the per instance admin password from the root only note, then confirm it authenticates. A valid admin session can reach the /setup page (HTTP 200); 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-cookies

Expected output — the admin session reaches the setup page while the anonymous request is redirected:

admin  /setup -> HTTP 200
anon   /setup -> HTTP 302

In 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.

The Fossil login page served behind nginx, where the admin user signs in; anonymous visitors are read only

Step 7: 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/timeline

The Fossil repository timeline showing the initial check in on the trunk branch, logged in as admin

Step 8: Use 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:

A wiki page rendered as Markdown, with the Edit, Help and History actions available to the logged in admin

Step 9: 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 click New Ticket to file one. Each ticket has a type, status, priority and full change history:

The All Tickets report listing a ticket with its type, status and title, with the color key for ticket states

Step 10: 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"

Step 11: Server Components

Component Path
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/cloudimg-fossil
Per instance info note /root/fossil-info.txt (mode 0600)
Sentinel /var/lib/cloudimg/fossil-firstboot.done
/usr/local/bin/fossil version
ls /usr/local/bin/fossil /var/lib/fossil/repo.fossil

Step 12: Managing 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.fossil

The fossil command line administers the repository directly — for example, list the users, add a developer with commit rights, or change the admin password.

Step 13: 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 the login password is no longer sent in the clear. Alternatively, terminate TLS at an Application Load Balancer with your own certificate.

Step 14: Security Recommendations

  • Restrict the security group so ports 80 and 22 only reach trusted networks.
  • Terminate TLS at nginx (Step 13) or an Application Load Balancer so the admin password and repository content travel encrypted.
  • Keep anonymous read only. The image ships with the nobody and anonymous users restricted to read only capabilities; only grant write capabilities to named users you trust.
  • Keep the rate limit in /etc/nginx/conf.d/cloudimg-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.fossil with 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.

Step 15: Support and Licensing

Fossil is distributed under the 2 clause BSD license — no per CPU or per user fee. cloudimg provides commercial support separately.

  • Email: support@cloudimg.co.uk
  • Website: www.cloudimg.co.uk
  • Support hours: 24/7, 24h response SLA

Deploy on AWS

Launch Fossil on AWS with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7. support@cloudimg.co.uk