skip to Main Content

I’m trying to execute python scripts trough fcgiwrap.socket on my Nginx server.

I wrote a Dockerfile that builds Nginx server from Nginx source code and starting nginx process. I keep getting the same error 2022/03/10 09:53:36 [error] 10#0: *7 connect() to unix:/var/run/fcgiwrap.socket failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: localhost, request: "GET /test.py HTTP/1.1", upstream: "fastcgi://unix:/var/run/fcgiwrap.socket:", when trying to execute test.py script after starting Nginx Docker container.

Could anyone give me some help please?

  • Dockerfile
FROM python:3.9.10-bullseye

# nginx, nginx upload module version
ENV NGINX_VERSION 1.20.2
ENV UPLOAD_MODULE_VERSION 2.3.0

# install dependencies
RUN apt-get update 
    && apt-get install -y wget gcc g++ make 
    && apt-get install -y fcgiwrap zlib1g zlib1g-dev openssl libssl-dev libpcre3 libpcre3-dev

# create nginx user/group and add nginx user to nginx group
RUN addgroup --system --gid 102 nginx 
    && adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 102 nginx

# compile and build nginx with nginx upload module
RUN set -x 
    && wget -P /usr/src "https://github.com/vkholodkov/nginx-upload-module/archive/${UPLOAD_MODULE_VERSION}.tar.gz" 
    && tar -xzvf /usr/src/$UPLOAD_MODULE_VERSION.tar.gz -C /usr/src 
    && wget -P /usr/src "https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" 
    && tar -xzvf /usr/src/nginx-$NGINX_VERSION.tar.gz -C /usr/src 
    && cd /usr/src/nginx-$NGINX_VERSION 
    && CONFIG="
    --sbin-path=/usr/local/sbin/nginx 
    --conf-path=/etc/nginx/nginx.conf 
    --pid-path=/var/run/nginx/nginx.pid 
    --lock-path=/var/lock/nginx/nginx.lock 
    --http-log-path=/var/log/nginx/access.log 
    --error-log-path=/var/log/nginx/error.log 
    --user=nginx 
    --group=nginx 
    --with-debug 
    --with-compat 
    --add-module=/usr/src/nginx-upload-module-${UPLOAD_MODULE_VERSION} 
    " 
    && ./configure $CONFIG 
    && make -j $(getconf _NPROCESSORS_ONLN) 
    && make install 
    && mkdir /var/lock/nginx 

# set up upload directory
ENV UPLOAD_FOLDER /upload
RUN mkdir /etc/nginx/conf.d/ 
    && chown nginx:nginx -R /etc/nginx/conf.d 
    && mkdir /usr/local/nginx/scripts/ 
    && chown nginx:nginx -R /usr/local/nginx/scripts 
    && mkdir $UPLOAD_FOLDER 
    && chown nginx:nginx -R $UPLOAD_FOLDER

# copy configuration files
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/http.conf /etc/nginx/conf.d/http.conf
COPY scripts /usr/local/nginx/scripts

# forward request, error logs to nginx-image-server Docker
RUN ln -sf /dev/stdout /var/log/nginx/access.log 
    && ln -sf /dev/stdout /var/log/nginx/error.log 
    && mkdir /docker-entrypoint.d

# docker entrypoint
COPY docker-entrypoint.sh /
# COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
# COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
# COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]

# start fcgiwrap process
RUN /etc/init.d/fcgiwrap start -f 
    && chown nginx:nginx -R /var/run/fcgiwrap.socket 
    && chmod 777 /var/run/fcgiwrap.socket

# expose port
EXPOSE 8888

# stopsignal
STOPSIGNAL SIGQUIT

# disable nginx daemon mode
CMD ["nginx", "-g", "daemon off;"]
  • checking permissions of /var/run/fcgiwrap.socket in Nginx docker container
root@3e5ad3eee456:/var/run# ls -al
total 24
drwxr-xr-x 1 root  root  4096 Mar 10 09:49 .
drwxr-xr-x 1 root  root  4096 Mar 10 09:49 ..
-rw-r--r-- 1 root  root     2 Mar 10 09:49 fcgiwrap.pid
srwxrwxrwx 1 nginx nginx    0 Mar 10 09:49 fcgiwrap.socket
drwxrwxrwt 1 root  root  4096 Mar 10 08:32 lock
drwxr-xr-x 1 root  root  4096 Mar 10 09:49 nginx
-rw-rw-r-- 1 root  utmp     0 Feb 28 00:00 utmp
  • nginx.conf
server {
    listen 8888;
    listen [::]:8888;
    server_name localhost;

    # CGI script path:
    location ~ .py$ {
        
        gzip off;

        root /usr/local/nginx/scripts; 

        # fastcgi params
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # fcgiwrap
        fastcgi_pass unix:/var/run/fcgiwrap.socket;

        # fastcgi configuration
        fastcgi_buffers 256 48k;
        fastcgi_buffer_size 48k;
        fastcgi_connect_timeout 600s;
        fastcgi_send_timeout 600s;
        fastcgi_read_timeout 600s;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }
}
  • test.py
#!/usr/local/bin/python3
print("Content-Type: text/html")
print()
print("Hello, world!")

2

Answers


  1. Chosen as BEST ANSWER

    I found an answer. The RUN statement(RUN /etc/init.d/fcgiwrap start -f ) did not start fcgiwrap process, so the fcgiwrap socket was not spawned.

    I added a shell script that starts fcgiwrap process by spawn-fcgi command like below.

    #!/bin/sh
    spawn-fcgi -s /var/run/fcgiwrap.socket -M 766 /usr/sbin/fcgiwrap 
    

  2. The cause of this seems to be the missing -M flag in the /etc/init.d/fcgiwrap.sh. By default the start command is doing this

    Starting FastCGI wrapper: fcgiwrap PATH='/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' /usr/bin/spawn-fcgi -P /var/run/fcgiwrap.pid -F '1' -s '/var/run/fcgiwrap.socket' -u 'www-data' -U 'www-data' -g 'www-data' -G 'www-data' -- /usr/sbin/fcgiwrap -f.   
    

    Small modification to the script to add the -M 766 option and it works.

    Starting FastCGI wrapper: fcgiwrap PATH='/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' /usr/bin/spawn-fcgi -P /var/run/fcgiwrap.pid -F '1' -s '/var/run/fcgiwrap.socket' -M '766' -u 'www-data' -U 'www-data' -g 'www-data' -G 'www-data' -- /usr/sbin/fcgiwrap -f.
    

    Without this the socket is created but not read/write for the nginx user. As a result, it fails.

    The root cause here is the nginx:nginx user getting access to the socket. So another fix is to change the fcgi_socket_owner/group to nginx.

    # Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
    #FCGI_SOCKET_OWNER="www-data"
    #FCGI_SOCKET_GROUP="www-data"
    FCGI_SOCKET_OWNER="nginx"
    FCGI_SOCKET_GROUP="nginx"
    FCGI_MODE="700"
    

    This is a better fix since it allows you to set the mode of the socket more securely to 700.

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