├── .env.example ├── .gitignore ├── Dockerfile ├── README.md └── config └── nginx.conf /.env.example: -------------------------------------------------------------------------------- 1 | AWS_ACCESS_KEY_ID=YOURAWSACCESSKEYID 2 | AWS_SECRET_ACCESS_KEY=YOURAWSSECRETACCESSKEY 3 | S3_BUCKET_NAME=YOURS3BUCKETNAME -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | 3 | MAINTAINER James Martinez 4 | 5 | # Install prerequisites for Nginx compile 6 | RUN apt-get update && \ 7 | apt-get install -y wget tar gcc libpcre3-dev zlib1g-dev make libssl-dev libluajit-5.1-dev 8 | 9 | # Download Nginx 10 | WORKDIR /tmp 11 | RUN wget http://nginx.org/download/nginx-1.14.0.tar.gz -O nginx.tar.gz && \ 12 | mkdir nginx && \ 13 | tar xf nginx.tar.gz -C nginx --strip-components=1 14 | 15 | # Download Nginx modules 16 | RUN wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz -O ngx_devel_kit.tar.gz && \ 17 | mkdir ngx_devel_kit && \ 18 | tar xf ngx_devel_kit.tar.gz -C ngx_devel_kit --strip-components=1 19 | RUN wget https://github.com/openresty/set-misc-nginx-module/archive/v0.32.tar.gz -O set-misc-nginx-module.tar.gz && \ 20 | mkdir set-misc-nginx-module && \ 21 | tar xf set-misc-nginx-module.tar.gz -C set-misc-nginx-module --strip-components=1 22 | RUN wget https://github.com/openresty/lua-nginx-module/archive/v0.10.13.tar.gz -O lua-nginx-module.tar.gz && \ 23 | mkdir lua-nginx-module && \ 24 | tar xf lua-nginx-module.tar.gz -C lua-nginx-module --strip-components=1 25 | 26 | # Build Nginx 27 | WORKDIR nginx 28 | RUN ./configure --sbin-path=/usr/local/sbin \ 29 | --conf-path=/etc/nginx/nginx.conf \ 30 | --pid-path=/var/run/nginx.pid \ 31 | --error-log-path=/var/log/nginx/error.log \ 32 | --http-log-path=/var/log/nginx/access.log \ 33 | --with-http_ssl_module \ 34 | --add-module=/tmp/ngx_devel_kit \ 35 | --add-module=/tmp/set-misc-nginx-module \ 36 | --add-module=/tmp/lua-nginx-module && \ 37 | make && \ 38 | make install 39 | 40 | # Apply Nginx config 41 | ADD config/nginx.conf /etc/nginx/nginx.conf 42 | 43 | # Expose ports 44 | EXPOSE 80 45 | 46 | # Set default command 47 | CMD ["nginx", "-g", "daemon off;"] 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nginx S3 File Upload Proxy 2 | S3 file upload proxy using Nginx, complete with AWS authentication. 3 | 4 | ## Installation 5 | 6 | Create a `.env` file to hold your environment variables for Nginx. You can base on the `.env.example` file contained in root folder. 7 | 8 | Using Docker, build the image. 9 | ```bash 10 | $ docker build -t jamescmartinez/nginx-s3-upload . 11 | ``` 12 | 13 | After the image is built, create a container. 14 | ```bash 15 | $ docker run -d -p 80:80 --env-file=.env jamescmartinez/nginx-s3-upload 16 | ``` 17 | 18 | ## Usage 19 | 20 | Once the container is running, give it a try! 21 | ```bash 22 | $ curl -T path/to/file/to/upload http://nginx-s3-upload.yourdomain.com/uploads/entity/property/filename.extension 23 | ``` 24 | 25 | The response will contain a header, `X-File-URL`, with the location of the file on your S3 bucket. 26 | 27 | ## Contributing 28 | 29 | Issue a pull request and I will love you forever. 30 | 31 | ## License 32 | 33 | nginx-s3-upload is released under the MIT license. 34 | -------------------------------------------------------------------------------- /config/nginx.conf: -------------------------------------------------------------------------------- 1 | env AWS_ACCESS_KEY_ID; 2 | env AWS_SECRET_ACCESS_KEY; 3 | env S3_BUCKET_NAME; 4 | 5 | worker_processes 1; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | server { 13 | listen 80; 14 | 15 | client_max_body_size 0; 16 | 17 | location ~* ^/uploads/(.*)/(.*)/(.*) { 18 | if ($request_method != PUT) { 19 | return 404; 20 | } 21 | 22 | set $entity $1; 23 | set $property $2; 24 | set $filename $3; 25 | set_secure_random_alphanum $prefix 64; 26 | set_sha1 $prefixsha $prefix; 27 | set_by_lua $date "return ngx.cookie_time(ngx.time())"; 28 | set_sha1 $datesha $date; 29 | set $upload_id $prefixsha$datesha; 30 | set $key $entity/$property/$upload_id/original/$filename; 31 | set_by_lua $bucket "return os.getenv('S3_BUCKET_NAME')"; 32 | set $url http://$bucket.s3.amazonaws.com/$key; 33 | set_by_lua $aws_access_key "return os.getenv('AWS_ACCESS_KEY_ID')"; 34 | set_by_lua $aws_secret_key "return os.getenv('AWS_SECRET_ACCESS_KEY')"; 35 | set $acl public-read; 36 | set $canonicalized_amz_headers "x-amz-acl:$acl\nx-amz-date:$date"; 37 | set $canonicalized_resource "/$bucket/$key"; 38 | set $string_to_sign "$request_method\n$http_content_md5\n$http_content_type\n\n$canonicalized_amz_headers\n$canonicalized_resource"; 39 | set_by_lua $aws_signature "return ngx.encode_base64(ngx.hmac_sha1(ngx.var.aws_secret_key, ngx.var.string_to_sign))"; 40 | 41 | proxy_set_header Authorization "AWS $aws_access_key:$aws_signature"; 42 | proxy_set_header x-amz-acl $acl; 43 | proxy_set_header x-amz-date $date; 44 | proxy_hide_header x-amz-id-2; 45 | proxy_hide_header x-amz-request-id; 46 | add_header X-File-URL $url; 47 | 48 | resolver 8.8.8.8 valid=300s; 49 | resolver_timeout 10s; 50 | 51 | proxy_pass $url; 52 | } 53 | } 54 | } 55 | --------------------------------------------------------------------------------