skip to Main Content

The Problem

I have a web-application that I want to containerize with docker and reverse-proxy via nginx. This web application shall receive uploads of audio files (~200-500Mb), thus I want upload progress events while uploading to be sent to the client.

I decided to base my docker image (see dockerfile below) on an alpine base that also contains glibc. From there the idea was to install nginx from the alpine repositories and use the nginx upload progress module to send the progress events. This module is compiled into the nginx module on alpine by default (See Alpine Repository)!

Thus, I created a simple nginx.conf file (see below) that just enables the upload_progress uploads 1m; directive in the http-block and made sure it gets copied into the container to /etc/nginx/nginx.conf.

I then started the container, installed nginx through apk and ran nginx -t. However, the conf file fails the test with this error message:

/ # nginx -t
nginx: [emerg] unknown directive "upload_progress" in /etc/nginx/nginx.conf:10
nginx: configuration file /etc/nginx/nginx.conf test failed

Troubleshooting so far

The error indicates that the binary does not have the upload progress module compiled in. However, this goes contrary to what is documented on the alpine repositories.

I also validated that the module is present in the binary by running a docker container with -i and executing nginx -V inside it to get a dump of all the modules and flags it was compiled with. It contains the necessary --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-progress-module-0.9.2/ as expected (see nginx -V dump below).

The nginx.conf is not the issue. When I run the given nginx conf file locally where I have compiled the upload progress module into nginx, it runs fine.

So now I’m left confused, what am I doing wrong? Why can’t I use the upload_progress directive when the module exists in the nginx binary?

dockerfile

FROM frolvlad/alpine-glibc

# Install dependencies
RUN apk update
RUN apk add --no-cache openrc nginx sqlite-libs

COPY ./nginx.conf /etc/nginx/nginx.conf

nginx.conf

# nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    upload_progress uploads 1m;
    types_hash_max_size 4096;
    client_max_body_size 1000M;

    sendfile        on;

    keepalive_timeout  600;

    server {
        server_name aldrune.com;
        autoindex off;

        listen 80;

        root /frontend;

        location /session_audio/ {
            #CORS
            add_header Access-Control-Allow-Origin '*';

            alias /audiomedia/;
        }

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

nginx -V dump

/ # nginx -V
nginx version: nginx/1.22.0
built with OpenSSL 1.1.1o  3 May 2022
TLS SNI support enabled
configure arguments: --prefix=/var/lib/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --pid-path=/run/nginx/nginx.pid --lock-path=/run/nginx/nginx.lock --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-threads --with-file-aio --without-pcre2 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --add-dynamic-module=/home/buildozer/aports/main/nginx/src/njs-0.7.4/nginx --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_devel_kit-0.3.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/traffic-accounting-nginx-module-2.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/array-var-nginx-module-0.05/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_brotli-1.0.0rc/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_cache_purge-2.5.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx_cookie_flag_module-1.1.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-dav-ext-module-3.0.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/echo-nginx-module-0.62/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/encrypted-session-nginx-module-0.09/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx-fancyindex-0.5.2/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_http_geoip2_module-3.3/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/headers-more-nginx-module-0.33/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-log-zmq-1.0.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-nginx-module-0.10.21/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-upstream-nginx-module-0.07/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/naxsi-1.3/naxsi_src --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nchan-1.2.8/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/redis2-nginx-module-0.15/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/set-misc-nginx-module-0.33/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-http-shibboleth-2.0.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_http_untar_module-1.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-progress-module-0.9.2/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upstream-fair-0.1.3/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_upstream_jdomain-1.3.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-vod-module-1.29/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-module-vts-0.1.18/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/mod_zip-1.2.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-rtmp-module-1.2.2/

2

Answers


  1. Chosen as BEST ANSWER

    @Ivan Shatsky provided the accepted solution, I just wanted to be more explicit of what exactly I did for others reading in the future.

    On alpine you can pretty easily install nginx modules since they are provided in the repositories. The module in question for me for example is here.

    Thus you can simply run apk add nginx-mod-http-upload-progress and you'll get the so file you need. apk installs those under /usr/lib/nginx/modules/ngx_http_uploadprogress_module.so.

    Knowing this, you can add the load_module command as Ivan suggested:

    load_module /usr/lib/nginx/modules/ngx_http_uploadprogress_module.so;


  2. The error indicates that the binary does not have the upload progress module compiled in.

    Yes, it isn’t. You compile it as a dynamic module using

    --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-progress-module-0.9.2/
    

    configure script parameter, so you need to load it dynamically using the load_module directive:

    load_module /path/to/nginx-upload-progress-module.so;
    

    at the top configuration level before you were able to use it (or compile it into nginx binary as a static module).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search