Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-z committed Dec 2, 2023
0 parents commit cb44198
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 0 deletions.
58 changes: 58 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
FROM public.ecr.aws/amazonlinux/amazonlinux:2023 as builder

# We need the full version of GnuPG
RUN dnf install -y --allowerasing wget gnupg2

RUN MP_ARCH=`uname -p | sed s/aarch64/arm64/` && \
wget -q "https://s3.amazonaws.com/mountpoint-s3-release/latest/$MP_ARCH/mount-s3.rpm" && \
wget -q "https://s3.amazonaws.com/mountpoint-s3-release/latest/$MP_ARCH/mount-s3.rpm.asc" && \
wget -q https://s3.amazonaws.com/mountpoint-s3-release/public_keys/KEYS

# Import the key and validate it has the fingerprint we expect
RUN gpg --import KEYS && \
(gpg --fingerprint [email protected] | grep "673F E406 1506 BB46 9A0E F857 BE39 7A52 B086 DA5A")

# Verify the downloaded binary
RUN gpg --verify mount-s3.rpm.asc

# Node.js binary verification instructions: https://github.com/nodejs/node?tab=readme-ov-file#verifying-binaries
ARG NODE_VERSION=20.9.0
RUN wget --quiet https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz \
&& wget --quiet https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt{,.sig} \
&& gpg --keyserver hkps://keys.openpgp.org --recv-keys C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
&& gpg --verify SHASUMS256.txt{.sig,} \
&& grep node-v${NODE_VERSION}-linux-x64.tar.xz SHASUMS256.txt | sha256sum -c - \
&& rm -f SHASUMS256.txt{,.sig} \
&& mv node-v${NODE_VERSION}-linux-x64.tar.xz node.tar.xz

FROM amazonlinux:2023
COPY --from=builder /mount-s3.rpm /mount-s3.rpm

RUN dnf upgrade -y && \
dnf install -y ./mount-s3.rpm && \
dnf clean all && \
rm mount-s3.rpm

RUN dnf upgrade -y \
&& dnf install -y python3-pip

RUN pip install supervisor

COPY --from=builder /node.tar.xz /node.tar.xz
RUN dnf upgrade -y \
&& dnf install -y tar xz \
&& tar -xf /node.tar.xz -C /usr/local --strip-components=1 \
&& rm /node.tar.xz

RUN npm install -g serve

COPY ./serve.json /etc/serve.json
COPY ./supervisord.conf /etc/supervisord.conf

# Optional environment variables
ENV MOUNTPOINT_S3_ADDITIONAL_ARGS=""
ENV SERVE_ADDITIONAL_ARGS=""

# Run in foreground mode so that the container can be detached without exiting Mountpoint
ENTRYPOINT [ "supervisord" ]

80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# s3-serve

Runs [serve][serve] with an [S3-compatible backend][mountpoint-s3]. Useful for serving websites from S3[^rewrite].

[serve]: https://github.com/vercel/serve
[mountpoint-s3]: https://github.com/awslabs/mountpoint-s3
[^rewrite]: S3 does not support [clean URLs](https://github.com/vercel/serve-handler/blob/da507891/README.md#cleanurls-booleanarray). The closest you can get is to use [index documents](https://docs.aws.amazon.com/AmazonS3/latest/userguide/IndexDocumentSupport.html), but this only supports `index.html` and not other files (e.g. `about.html`. A workaround is to convert all `<name>.html` files to `<name>/index.html` files, but that is error-prone because it's not the default behaviour of frameworks like [Next.js](https://nextjs.org/)). Moreover, in some S3-compatible storage backends like [Ceph Object Gateway](https://docs.ceph.com/en/latest/radosgw/s3/), the support for index documents requires setting `rgw_dns_name` and `rgw_dns_s3website_name`, which restricts the RGW instance to only serve from two domains. On the other hand, [serve][serve] supports clean URLs the box. This project combines the two to provide clean URLs on S3.

## Getting started

```bash
export AWS_ACCESS_KEY_ID=<access_key_id>
export AWS_SECRET_ACCESS_KEY=<secret_key>
export S3_ENDPOINT_URL=<endpoint_url>
export S3_BUCKET=<bucket_name>

docker run --rm --cap-add SYS_ADMIN --device /dev/fuse --name s3-serve \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e S3_ENDPOINT_URL \
-e S3_BUCKET \
-p 3000:3000 \
ghcr.io/watonomous/s3-serve
```

### Use path-style addressing

If your S3 endpoint does not support virtual-hosted-style addressing, you can use path-style addressing by including `--force-path-style` in the `MOUNTPOINT_S3_ADDITIONAL_ARGS` environment variable:

```bash
# In addition to the above environment variables
export MOUNTPOINT_S3_ADDITIONAL_ARGS="--force-path-style"

docker run --rm --cap-add SYS_ADMIN --device /dev/fuse --name s3-serve \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e S3_ENDPOINT_URL \
-e S3_BUCKET \
-e MOUNTPOINT_S3_ADDITIONAL_ARGS \
-p 3000:3000 \
ghcr.io/watonomous/s3-serve
```

### Reduce logging

By default, [serve][serve] and [mountpoint-s3][mountpoint-s3] log all requests[^logging]. You can reduce the amount of logging by including the following environment variables:

```bash
# In addition to the above environment variables
export SERVE_ADDITIONAL_ARGS="--no-request-logging"
export MOUNTPOINT_LOG="error,awscrt=off"

docker run --rm --cap-add SYS_ADMIN --device /dev/fuse --name s3-serve \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e S3_ENDPOINT_URL \
-e S3_BUCKET \
-e SERVE_ADDITIONAL_ARGS \
-e MOUNTPOINT_LOG \
-p 3000:3000 \
ghcr.io/watonomous/s3-serve
```

[^logging]: [`serve` logging documentation](https://github.com/vercel/serve/blob/1ea55b/source/utilities/cli.ts#L47), `mountpoint-s3` logging documentation [1](https://github.com/awslabs/mountpoint-s3/blob/27bac02/doc/LOGGING.md) [2](https://github.com/awslabs/mountpoint-s3/blob/27bac02/mountpoint-s3/src/main.rs#L289-L304)

### Use a custom `serve` configuration

You can use a custom `serve` configuration by mounting a [`serve.json`](https://github.com/vercel/serve/blob/1ea55b/readme.md#configuration) file to `/etc/serve.json`:

```bash
docker run --rm --cap-add SYS_ADMIN --device /dev/fuse --name s3-serve \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e S3_ENDPOINT_URL \
-e S3_BUCKET \
-v /path/to/serve.json:/etc/serve.json:ro \
-p 3000:3000 \
ghcr.io/watonomous/s3-serve
```

1 change: 1 addition & 0 deletions serve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "directoryListing": false }
19 changes: 19 additions & 0 deletions supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[supervisord]
nodaemon=true
user=root

[program:mountpoint-s3]
command=/usr/bin/mount-s3 --foreground --endpoint-url %(ENV_S3_ENDPOINT_URL)s %(ENV_MOUNTPOINT_S3_ADDITIONAL_ARGS)s %(ENV_S3_BUCKET)s /mnt
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
priority=10

[program:serve]
command=/usr/local/bin/serve --config /etc/serve.json --listen tcp://0.0.0.0:3000 %(ENV_SERVE_ADDITIONAL_ARGS)s
directory=/mnt
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
priority=20

0 comments on commit cb44198

Please sign in to comment.