# Host fossil scm on fly.io

## Prerequisites

1. [Install flyctl][inst_fly] and authenticate (`fly auth login`)

## Setup

1. Create app
2. Create persistent storage volume
3. Deploy
4. Verify fossil web server
5. Upload your repos
6. Configure sync settings

```
## list available regions; uses airport codes. YYZ and YUL are Canada
fly platform regions

## Create app template and register it with Fly.io
# answering Yes to "tweak settings" will open a web page allowing all of 
# these to be changed
fly launch --no-deploy --dockerfile Dockerfile --vm-memory 256 --generate-name --org personal --region yyz

## Create volume for persistent storage for the repos. Fly recommends 2.
fly vol create persistent --region yyz --size 1 --count 2

## Deploy
# transfers the dockerfile, builds image, creates & starts app machine, sets DNS
fly deploy
```

At this point you should be able to visit `https://YOUR_MACHINE.fly.dev/`, e.g. <https://flyio-fossil.fly.dev/>

## Secure local repositories

_See <https://fossil-scm.org/home/doc/trunk/www/server/>_

### Repository Prep

Prior to serving a Fossil repository to others, consider running fossil ui locally and taking these minimum recommended preparation steps:

Fossil creates only one user in a new repository and gives it the all-powerful Setup capability. The 10-digit random password generated for that user is fairly strong against remote attack, even without explicit password guess rate limiting, but because that user has so much power, you may want to give it a much stronger password under Admin → Users.

Run the _Admin → Security-Audit_ tool to verify that other security-related permissions and settings are as you want them. Consider clicking the "Take it private" link on that page to lock down the security on that site to a level appropriate to a private repository, even if you will eventually want some public service. It's better to start from a secure position and open up service feature-by-feature as necessary than it is to start from a fully open position and lock down features one by one to achieve a secure stance.

With the repository secured, it is safe to upload a copy of the repository file to your server and proceed with server setup, below. Further configuration steps can wait until after the server is running.

## Upload repositories

The dockerfile in this project creates a new empty fossil repository. After uploading your own repos you can delete it, or use for own purposes. To re-use, make note of the admin user credentials:

```
# check initialization log and get admin user credentials for the sample repo
fly ssh console -C "cat /persistent/fossil-init.log"

# output will look like this:
Connecting to fdaa:7:ae6b:a7b:f2:9aad:f82e:2... complete
Initializing new Fossil repository...
This is fossil version 2.24 [8be0372c10] 2024-04-23 13:25:26 UTC
project-name: flyio-fossil
project-description: Hosting Fossil SCM on Fly.io
project-id: 9da03********f756ea0
server-id:  b8427********49350a
admin-user: CHANGE_ME (initial password is "fb****8T")
Repository initialization complete
```

Upload repositories to the volume using the [flyio sftp shell][f-sftp]. This is done manually as it has a very limited command set and can't be easily scripted. Filenames must be spelled out, both source and destination (`put something.db /peristent/` will fail).

```
fly ssh sftp shell
```

Inside the sftp console:

```
put ~/my-local-machine/data/some-repo.fossil /persistent/repos/some-repo.fossil
```

Use `fly ssh console` to open a standard shell on the remote machine and poke around. Fossil will be in PATH. **IMPORTANT**: Fly activity monitor only checks for http traffic in keeping the VM alive, so refresh the web page every 30 secs or so else you'll get booted out of the ssh session with no warning.

## Configure sync settings

_See <https://fossil-scm.org/forum/forumpost/aad4e561b58deab7>_

On each check-out do something like:

```
fossil sync https://USERNAME@flyio-fossil.fly.dev/myrepo.fossil
```

At this point you have clones of your repository both on your local machine and on "remote". Whenever you make a new check-in (assuming you have not disabled auto-sync), that check-in is first written to the repository on your local machine, then gets replicated to "remote", thus automatically doing a backup.

For added redundancy, you can do "fossil remote add ... to name multiple remote repositories that are accessible by ssh or https, then set:

    fossil setting autosync all

And then each check-in you make will be pushed to all of your remote repositories.



[inst_fly]: https://fly.io/docs/flyctl/install/
[f-sftp]: https://fly.io/docs/flyctl/ssh-sftp-shell/
