A simple file server than can accept uploads. Built with ❤️ for Alessio.
Yep--that's it. Just one line.
# Omit the -d if you want to run the server in the foreground to see logs
docker-compose up -d
Go to http://localhost:8000 to view your server.
Note that nginx is running as root
inside the docker container, so the files it writes as the result of an upload will be owned by root
. In practice, you'd probably want to mount a docker volume rather than the ./shared_files
directory into the container. However, using a local directory makes it easier to see what's going on. You can add any files or directories you want to shared_files
and nginx will serve them. You could also change the permissions on shared_files/uploads
to be writable by everyone, and then run nginx
as non-root by removing the user root
directive from nginx.conf
.
Set your desired autoindex_format
value in nginx.conf
. nginx
can serve html
(human readable) or json
(machine readable) data. The autoindex_format
value can be set independently to either html
or json
for both the /
and /uploads/
locations
. If you change the autoindex_format
values you'll need to stop and restart your server to load the new configuration. The python client's client.put()
and client.get()
methods will work with either setting, the client.ls()
method will only work if serving json
.
Communicate programmatically with the file server using python. Code found in client.py
.
python -m venv env
source ./env/bin/activate
pip install -r requirements.txt
# From the root directory of this project
>>> import client
# If you get a JSONDecodeError you need to change your server from html to json
>>> client.ls()
# Open file in binary mode and load bytes to the server
>>> with open("path_to_some_file", "rb") as f:
data = f.read()
url = client.put("my_filename.whatever", data)
>>> url
'uploads/62b2013b-097e-4560-9119-449650dca77c-my_filename.whatever'
# Download the file I just uploaded
>>> data = client.get(url)
>>> with open("my_ouput_file.whatever", "wb") as f:
f.write(data)
Generally:
python client.py mynewfilename.whatever /path/to/file/i/want/to/upload/file.whatever
For example:
python client.py new-docker-compose.yaml ./docker-compose.yaml
Now check the /uploads/
directory of your file server and the local shared_files
directory.
Set global variables in client.py
as needed. The default values will work fine for local development
SERVER_URL = "http://localhost"
SERVER_PORT = 8000
SERVER_UPLOAD_PREFIX = "uploads"
Stop web server:
docker-compose down
Deactivate python virtual environment:
deactivate
Remove shared_files
directory:
# Need sudo because files were written by nginx running as root
sudo rm -rf shared_files
Deploy this service behind a traefik reverse proxy that provides TLS
, http
-> https
redirects, etc. for a secure production deployment. See Docker Swarm Rocks for a great overview.
If you want a server that only allows uploads without serving any files, just remove/comment out the autoindex
directives on the /uploads/
location
(and potentially remove the /
location, if desired) and your server will accept uploads, but not serve files back to end users.
This project is built on the built-in nginx module ngx_http_dav_module. It is using the WebDAV protocol to allow basic HTTP methods like PUT
and DELETE
. Other methods can be added if needed. Do an internet search for nginx webdav
to find examples and more details.