Use Traefik 2 with Nginx, Apache, or CaddyServer to Serve Static Files
Setup a simple HTTP static file server behind Traefik. Nginx is a nice drop-in to solve this because it is small, fast, and will work well in a default configuration.
Setup a simple HTTP static file server behind Traefik. My specific use case is to serve static files (eg - PDF, excel, etc) from my blog that runs Ghost. However, the software itself does not support that. There are a number of HTTP servers, but we will choose three of the most popular ones.
These work well because they provide a nice drop-in to solve static file serving because it is small, fast, and will work well in a default configuration.
Now we will explore two ways to serve up files.
- Hosting on a subdomain (eg -
files.example.com
) - Hosting on the blog's domain but in a subfolder (eg -
example.com/static
)
Use docker-compose
and docker labels to configure Traefik's routing and middlewares.
In both scenarios:
- Use the images from Docker Hub.
- Bind-mount a local folder to host the files for the web server. See
volumes:
in the docker-compose.
On its own domain
You must have the DNS entry, files.example.com
in this case, to point at the server. An example file download URL would be:
- https://files.example.com/sales-pitch.pdf
All-in-one config (docker-compose)
This is a docker-compose.yml
with configurations for all three servers. Simply comment out the ones you don't want and un-comment the ones you do. Bobs- your uncle.
static:
# nginx config
image: nginx
volumes:
- ./files:/usr/share/nginx/html:ro
# uncomment to use Aapche HTTPD Server
# image: httpd:2.4-alpine
# volumes:
# - ./files:/usr/local/apache2/htdocs:ro
# Uncomment to use Caddeserver
# image: caddy/caddy:scratch
# command: file-server --root /files --listen 0.0.0.0:80
# volumes:
# - ./files:/files:ro
container_name: static-files
restart: unless-stopped
networks:
- traefik
labels:
# Match on the hostname and the path
- traefik.http.routers.nginx.rule=Host(`files.example.com`)
- traefik.http.routers.nginx.tls=true
- traefik.http.routers.nginx.tls.certresolver=le
- traefik.http.services.nginx.loadbalancer.server.port=80
# tell Traefik which middlewares we want to use on this container
- traefik.http.routers.nginx.middlewares=gzip
On a specific URI path (/static) in an existing domain
It is only a matter of three lines that will enable this to live under /static
Path. An example file download URL would be:
- https://blog.example.com/static/sales-pitch.pdf
Just the parts you need
# Match on the hostname and the path
- traefik.http.routers.nginx.rule=(Host(`blog.example.com`) && Path(`/static`))
# Define a new middleware to strip the URL prefix before sending it to nginx
- traefik.http.middlewares.nginx-stripprefix.stripprefix.prefixes=/static
# tell Traefik which middlewares we want to use on this container
- traefik.http.routers.nginx.middlewares=gzip@docker,nginx-stripprefix@docker
Full docker-compose.yml
static:
# nginx config
image: nginx
volumes:
- ./files:/usr/share/nginx/html:ro
# uncomment to use Aapche HTTPD Server
# image: httpd:2.4-alpine
# volumes:
# - ./files:/usr/local/apache2/htdocs:ro
# Uncomment to use Caddeserver
# image: caddy/caddy:scratch
# command: file-server --root /files --listen 0.0.0.0:80
# volumes:
# - ./files:/files:ro
container_name: static-files
restart: unless-stopped
networks:
- traefik
labels:
# Match on the hostname and the path
- traefik.http.routers.static-files.rule=(Host(`blog.example.com`) && Path(`/static`))
- traefik.http.routers.static-files.tls=true
- traefik.http.routers.static-files.tls.certresolver=le
- traefik.http.services.static-files.loadbalancer.server.port=80
# Define a new middleware to strip the URL prefix before sending it to static-files
- traefik.http.middlewares.static-files-stripprefix.stripprefix.prefixes=/static
# tell Traefik which middlewares we want to use on this container
- traefik.http.routers.static-files.middlewares=gzip@docker,static-files-stripprefix@docker
Things to note
- The CaddyServer config needed a
command:
attribute added to tell it to activate its fileserver feature. - The mountpoints for
volumes:
is different per server - Only official images are used. Your milage may vary if you stray from these...
Other guides
- I previously made a guide on hosting your files using a nice Golang service called filebrowser. Read more about Ghost and Filebrowse here.
Conclusion
Using the above snippets you should be able to add Nginx, Apache HTTPD, or CaddyServer to your docker / Traefik deployments and have simple, no fuss static file serving.
I should also mention that is snipped is part of my production stack template that use for most Simple CTO projects. More on that later