Skip to content

Instantly share code, notes, and snippets.

@Nezteb
Last active March 29, 2023 07:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nezteb/e05aa6585daaa05f853ee8f42896ad14 to your computer and use it in GitHub Desktop.
Save Nezteb/e05aa6585daaa05f853ee8f42896ad14 to your computer and use it in GitHub Desktop.
Deploying Fossil with TLS on Fly.io via Docker

Deploying Fossil SCM on Fly.io

  1. Read about Fossil and figure out if you want to try it as an alternative to git!
  2. Follow Fly.io's hands-on guide to create an account and your first app.
    • fly init
  3. Allocate an IPv4 address for your app.
    • fly ips allocate-v4
  4. Create a volume to use:
    • fly volumes create name_of_your_volume
  5. Copy the Dockerfile and fly.toml files in this gist.
  6. Replace the REDACTED_ bits of fly.toml with the actual values.
    • REDACTED_APP: Created during the fly init step.
    • REDACTED_REGION: Set during the fly init step.
    • REDACTED_VOLUME: Creatd during the fly volumes create step.
  7. Deploy!
    • fly deploy
  8. Observe the deploy logs for your app from the "Monitoring" tab. While the app is deployed, you'll see a log that contains your defualt admin password that you should save in your password manager: (you will change it later)
    • admin-user: admin (initial password is "abcdefghij")
  9. Optional: set up your Fly.io custom domain and SSL/TLS certificates.
  10. Log into your Fossil web UI and go to the "Admin" tab to set up your new instance!

Congrats, you now have a working Fossil server!

# Pulled from https://fossil-scm.org/home/file?name=Dockerfile&ci=trunk
# With more build ARGs, cleaner tarball extraction, HTTPS, etc.
ARG ALPINE_VERSION
ARG FSLHSH
ARG FSLVER
ARG FSLCFG=""
# syntax=docker/dockerfile:1.3
# See www/containers.md for documentation on how to use this file.
## ---------------------------------------------------------------------
## STAGE 1: Build static Fossil binary
## ---------------------------------------------------------------------
### We aren't pinning to a more stable version of Alpine because we want
### to build with the latest tools and libraries available in case they
### fixed something that matters to us since the last build. Everything
### below depends on this layer, and so, alas, we toss this container's
### cache on Alpine's release schedule, roughly once a month.
FROM alpine:${ALPINE_VERSION} AS builder
WORKDIR /tmp
ARG FSLHSH
ARG FSLVER
ARG FSLCFG
### Bake the basic Alpine Linux into a base layer so it only changes
### when the upstream image is updated or we change the package set.
RUN set -x \
&& apk update \
&& apk upgrade --no-cache \
&& apk add --no-cache \
gcc make \
linux-headers musl-dev \
openssl-dev openssl-libs-static \
zlib-dev zlib-static curl
### Build Fossil as a separate layer so we don't have to rebuild the
### Alpine environment for each iteration of Fossil's dev cycle.
ARG FSLDIR="fossil-src-${FSLVER}"
ARG FSLSTB="${FSLDIR}.tar.gz"
ARG FSLURL="https://fossil-scm.org/home/tarball/${FSLHSH}/${FSLSTB}"
RUN curl -o $FSLSTB $FSLURL
RUN tar -xzf $FSLSTB
RUN mv $FSLDIR src
RUN m=src/src/main.mk && src/configure --static CFLAGS='-Os -s' $FSLCFG && make -j11
## ---------------------------------------------------------------------
## STAGE 2: Pare that back to the bare essentials.
## ---------------------------------------------------------------------
FROM busybox AS os
ARG UID=499
### Set up that base OS for our specific use without tying it to
### anything likely to change often. So long as the user leaves
### UID alone, this layer will be durable.
RUN set -x \
&& mkdir log museum \
&& echo "root:x:0:0:Admin:/:/false" > /tmp/passwd \
&& echo "root:x:0:root" > /tmp/group \
&& echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /tmp/passwd \
&& echo "fossil:x:${UID}:fossil" >> /tmp/group
## ---------------------------------------------------------------------
## STAGE 3: Drop BusyBox, too, now that we're done with its /bin/sh &c
## ---------------------------------------------------------------------
FROM scratch AS run
COPY --from=os /tmp/group /tmp/passwd /etc/
COPY --from=os --chown=fossil:fossil /log /log/
COPY --from=os --chown=fossil:fossil /museum /museum/
COPY --from=os --chmod=1777 /tmp /tmp/
COPY --from=builder /tmp/fossil /bin/
## ---------------------------------------------------------------------
## RUN!
## ---------------------------------------------------------------------
ENV PATH "/bin"
EXPOSE 8080/tcp
USER fossil
ENTRYPOINT [ "fossil", "server", "museum/repo.fossil" ]
CMD [ \
"--create", \
"--https", \
"--jsmode", "bundled", \
"--user", "admin" ]
app = "REDACTED_APP"
kill_signal = "SIGINT"
kill_timeout = 5
primary_region = "REDACTED_REGION"
processes = []
[build.args]
ALPINE_VERSION=3
FSLHSH="f9aa474081f0618c76f4c2f4d6f0277a3fd480aa185d7da0b8b61b00fad1aa78"
FSLVER="2.12"
[env]
[experimental]
auto_rollback = true
# Data
[[mounts]]
destination = "/museum"
source = "REDACTED_VOLUME"
[[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = false
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment