Fossil SCM on AWS User Guide
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.servicerunning as thefossiluser, bound to loopback127.0.0.1:8081nginx.servicereverse proxy on TCP 80, TLS ready, 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 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.

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

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:

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:

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