Blog |Follow Nick on Mastodon| About
 

I've been experimenting with fly.io; applications are Docker containers, here are some instructions to get NGINX up-n-running, with Fuse (s3fs) mounting an S3/Tigris bucket. The goal I was looking for was directy listings for the bucket, but honestly I wouldn't recommend it because it's very slooooow! ... about 5 seconds on first load.

If you want to play along anyway, download a copy of my github repo, the instructions assume that fly-cli and amazon-cli are both already installed.

Step 1 - Fly Launch

Run fly launch --no-deploy

╰─❯ fly launch --no-deploy
Scanning source code
Detected a Dockerfile app
Creating app in /home/nick/fly-docker-nginxs3fs
We're about to launch your app on Fly.io. Here's what you're getting:

Organization: NB                     (fly launch defaults to the personal org)
Name:         fly-docker-nginxs3fs   (derived from your directory name)
Region:       London, United Kingdom (this is the fastest region for you)
App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
Postgres:     <none>                 (not requested)
Redis:        <none>                 (not requested)
Tigris:       <none>                 (not requested)

? Do you want to tweak these settings before proceeding? (y/N) Y

Select Yes

In the Browser window that opens, scroll down and create a bucket...

Screenshot of fly.io console, creating a bucket

Back on your console, some keys have been generated...

Opening https://fly.io/cli/launch/xxx[REDATED]xxx ...

Waiting for launch data... Done
Created app 'fly-docker-nginxs3fs' in organization 'personal'
Admin URL: https://fly.io/apps/fly-docker-nginxs3fs
Hostname: fly-docker-nginxs3fs.fly.dev
Run `fly tokens create deploy -x 999999h` to create a token and set it as the FLY_API_TOKEN secret in your GitHub repository settings
See https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions
Your Tigris project (mys3fstest) is ready. See details and next steps with: https://fly.io/docs/reference/tigris/

Setting the following secrets on fly-docker-nginxs3fs:
AWS_ACCESS_KEY_ID: tid_yyy[REDATED]yyy
AWS_ENDPOINT_URL_S3: https://fly.storage.tigris.dev
AWS_REGION: auto
AWS_SECRET_ACCESS_KEY: tsec_zzz[REDATED]zzz
BUCKET_NAME: mys3fstest

Wrote config file fly.toml
Validating /home/nick/fly-docker-nginxs3fs/fly.toml
✓ Configuration is valid
Your app is ready! Deploy with `flyctl deploy`
╰─❯ 

Take a backup of these, as you'll never see them again!

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Step 2- Fly Deploy

Now Deploy fly deploy --dns-checks=false (Disabling the ping to 8.8.8.8 because it's annoying!)

╰─❯ fly deploy --dns-checks=false
==> Verifying app config
Validating /home/nick/fly-docker-nginxs3fs/fly.toml
✓ Configuration is valid
--> Verified app config
==> Building image
Remote builder fly-builder-weathered-forest-2010 ready
Remote builder fly-builder-weathered-forest-2010 ready
==> Building image with Docker
--> docker host: 24.0.7 linux x86_64
[+] Building 2.0s (12/12) FINISHED
 => [internal] load .dockerignore 0.4s
 => => transferring context: 2B 0.4s
 => [internal] load build definition from Dockerfile  0.5s
 => => transferring dockerfile: 541B 0.5s
 => [internal] load metadata for docker.io/library/nginx:alpine-slim 0.6s
 => [1/7] FROM docker.io/library/nginx:alpine-slim@sha256:2be9e698d136d4d9be33d1852b1259bc1b80e20aed0c964cbcd6086da7fad5c7 0.0s
 => [internal] load build context 0.5s
 => => transferring context: 1.14kB   0.5s
 => CACHED [2/7] RUN apk update       0.0s
 => CACHED [3/7] RUN apk add --no-cache openssl s3fs-fuse   0.0s
 => CACHED [4/7] RUN mkdir /etc/nginx/templates             0.0s
 => [5/7] COPY etc/nginx/templates/default.conf.template /etc/nginx/templates/default.conf.template   0.0s
 => [6/7] COPY docker-entrypoint.d/40-s3fs.sh /docker-entrypoint.d/40-s3fs.sh   0.0s
 => [7/7] RUN chmod 755 /docker-entrypoint.d/40-s3fs.sh     0.1s
 => exporting to image                0.0s
 => => exporting layers               0.0s
 => => writing image sha256:73f897416cd820470a05839773fa3efc9109325985d2e4fa5c81477c14a3a5d2    0.0s
 => => naming to registry.fly.io/fly-docker-nginxs3fs:deployment-01J6CZAKTZP2WXQ2QC5MP4MM    0.0s
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/fly-docker-nginxs3fs]
0aa928e18663: Pushed
41551b3786e0: Pushed
3033ae542f6f: Pushed
8ad7f7ee614a: Layer already exists
bafbe3c5986a: Layer already exists
deployment-01J6CZAKTZP2WXQ2QC5MP4MM: digest: sha256:96b381cd48b63cd55c4a35e8c58ae2f5129152a11a74d9825ad10b7156fd1c12 size: 3026
--> Pushing image done
image: registry.fly.io/fly-docker-nginxs3fs:deployment-01J6CZAKTZP2WXQ2QC5MP4MM
image size: 25 MB

Watch your deployment at https://fly.io/apps/fly-docker-nginxs3fs/monitoring

-------
Updating existing machines in 'fly-docker-nginxs3fs' with rolling strategy

-------
 ✔ [1/2] Cleared lease for 328716d1f00668
 ✔ [2/2] Cleared lease for e7843060b496d8
-------

Visit your newly deployed app at https://fly-docker-nginxs3fs.fly.dev/
╰─❯

Step 3 - Files in a bucket

If you browse to the URL in the terminal, you'll see a default NGINX index page. If you browse to your URL + Bucket Name, like https://fly-docker-nginxs3fs.fly.dev/mys3fstest/ you'll see an empty bucket.

Screenshot of empty bucket via NGINX

To add some files, remember those credentials, you can use them with AWS's CLI.

╰─❯ 
export AWS_ACCESS_KEY_ID="tid_yyy[REDATED]yyy"
export AWS_ENDPOINT_URL_S3="https://fly.storage.tigris.dev"
export AWS_REGION="auto"
export AWS_SECRET_ACCESS_KEY="tsec_zzz[REDATED]zzz"
╰─❯ aws s3 ls
2024-08-28 17:52:20 mys3fstest
╰─❯ 

So, let's do a Hello World example...

╰─❯ echo 'hello world' > test.txt
╰─❯ aws s3 cp ./test.txt s3://mys3fstest
upload: ./test.txt to s3://mys3fstest/test.txt
╰─❯ aws s3 ls s3://mys3fstest
2024-08-28 18:26:20         12 test.txt
╰─❯

And view the results in the browser...

Screenshot of NGINX dir listing with example test.txt

Screenshot of test.txt contents, via NGINX

End

References:

  • https://github.com/s3fs-fuse/s3fs-fuse
  • https://hub.docker.com/_/nginx

 

 
Nick Bettison ©