This is an example application that shows how to combine nginx with the
ngx_aws_auth and mod_zip modules to create a server that can stream
multiple files from Amazon Web Services S3 as a single ZIP file without using
any temporary storage.
For convenience, this project is packaged as a Docker container.
- Nginx: https://www.nginx.com
- Nginx
ngx_aws_auth: https://github.com/anomalizer/ngx_aws_auth - Nginx
mod_zip: https://www.nginx.com/resources/wiki/modules/zip/
First we need to build the Docker container:
docker build -t nginx_s3_streaming_zip .
Get your Amazon Web Services S3 authentication information. Upload some test files into an S3 bucket. Record their sizes and file names.
We now need to create a file in the format that mod_zip understands. For this
example code, we will do this by hand as a static file. In the real world, this
would be created by a dynamic backend (in PHP, Python, etc.).
This is the documentation for the mod_zip file format:
Here is an example file in that format. Note that the CRC32 checksum is
optional. DO NOT FORGET THE /s3/ PREFIX ON THE FILE NAMES!!!
- 1234 /s3/test1.txt test1.txt
- 5678 /s3/test2.txt test2.txt
Create a new directory example and save the file in example/test.txt.
Now we run the Docker container on TCP port 8888, and bind mount our example
directory inside the container at /var/www/html/example/. We also specify the
Amazon Web Services S3 credentials.
docker run -p 8888:80 \
-v example:/var/www/html/example \
-e 'AWS_ACCESS_KEY_ID=' \
-e 'AWS_SECRET_ACCESS_KEY=' \
-e 'AWS_DEFAULT_REGION=' \
-e 'AWS_BUCKET=' \
nginx_s3_streaming_zipAnd now you can visit the page with cURL (or with the web browser of your choice):
curl -v -XGET 'http://localhost:8888/example/test.txt' > example.zip
You will have a valid ZIP file containing the files you asked for!
The nginx.conf has several configurations.
The main server listening on port 80 directs all the requests depending on:
- All paths matching
^/s3/(?<url>.*)$(the /s3/ files) will be redirected to the server listening on port3333:http://127.0.0.1:3333/$url. This server will be our proxy toS3files. - Everything else is handled by the server running on port
8080:http://127.0.0.1:8080.
When the request for /example/test.txt arrives, it will be handled by the server running on port 8080. It will add a header:
add_header X-Archive-Files 'zip';
which triggers the mod_zip. As a result, the content of example/test.txt will be parsed by mod_zip to generate a zip file on the fly. Now this is where the proxy to S3 on port 3333 kicks in. Remeber that the S3 files in test.txt had a prefix /s3/. This will cause the internal reads to /s3/test1.txt to be handled by the proxy and directed to https://<bucket>.s3.amazonaws.com/test1.txt.
This project is licensed under the MIT License. Please see the LICENSE file in this repository for details.