DEV Community

Sam Texas
Sam Texas

Posted on • Originally published at simplecto.com on

Use Traefik 2 with Nginx, Apache, or CaddyServer to Serve Static Files

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.

  1. Hosting on a subdomain (eg - files.example.com)
  2. 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:

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

Enter fullscreen mode Exit fullscreen mode

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:

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

Enter fullscreen mode Exit fullscreen mode

<!--kg-card-end: markdown--><!--kg-card-begin: markdown-->

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

Enter fullscreen mode Exit fullscreen mode

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

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

Top comments (0)