fastcgi-mono-server4 and nginx with docker

A lot of information on the web tells how to set up nginx + fastcgimono-server4 on the same machine to host ASP.net (at the moment I’m using F# application with Websharper) from linux environment. But docker should run only one process. Also there are solutions around that with using runit or other tools to run nginx and mono server on the same container.

I got it working in the same container, but when I try to move web application + fastcgi-mono-server4 to another container, I got

  • How to increase docker-machine memory Mac
  • Start a docker container with a user permission and a USB device
  • Running docker container in Jenkins container, How can I set the volume from host?
  • Best way to stop Docker container in Jenkins
  • Docker running out of memory when loading large sql dump
  • How can I maximize throughput in Docker and Akka HTTP?
  •  [error] 12#12: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.99.1, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://172.17.0.40:32775", host: "192.168.99.100:32786"
    

    Found an article about similar requirements but for php fastcgi server (php-fpm), and that works with just linking containers. But for fastcgi-mono-server4 it doesn’t.

    I have tried creating 1 container with fastcgi-mono-server4 + application files, exposing a VOLUME of application files, exposing port 9000 and then nginx container with volumes from first container and link to it
    Also tried to run 2 same containers with nginx and mono server installed, first with fastcgi_pass 127.0.0.1:9000, second with fastcgi_pass 172.17.0.40:32775 – ip and port from first container. If accessing first container – application works, accessing second container – same error as above.

    Comand used to run mono server:

    fastcgi-mono-server4 /printlog=True /applications=/:/var/www/websharper/ /socket=tcp:0.0.0.0:9000 /loglevels=All /verbose=True
    

    Versions of installed software:

    Container from mono (debian wheezy with mono:4.0.0)
    NGINX_VERSION 1.9.5-1~wheezy
    $ mono --version
    Mono JIT compiler version 4.0.3 (Stable 4.0.3.20/d6946b4 Tue Aug  4 09:43:57 UTC 2015)
    Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen
    $ fastcgi-mono-server4 --version
    Mono.WebServer2.dll 0.4.0.0
    

    Some logs from fastcgi-mono-server4 startup

    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.510407] Debug  : fastcgi-mono-server4
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.530481] Debug  : Uid 0, euid 0, gid 0, egid 0
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.531310] Debug  : Root directory: /
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.532843] Notice : Adding applications '/:/var/www/websharper/'...
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.533478] Notice : Registering application:
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.533757] Notice :     Host:          any
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.534075] Notice :     Port:          any
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.534459] Notice :     Virtual path:  /
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.534770] Notice :     Physical path: /var/www/websharper/
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.543250] Debug  : Parsed tcp:0.0.0.0:9000 as URI tcp:0.0.0.0:9000
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.556826] Debug  : Listening on port: 9000
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.558991] Debug  : Listening on address: 0.0.0.0
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.564079] Debug  : Max connections: 1024
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.564786] Debug  : Max requests: 1024
    9: 1 fastcgi-mono-server [2015-10-01 09:01:17.565224] Debug  : Multiplex connections: False
    9: 3 fastcgi-mono-server [2015-10-01 09:01:17.568840] Debug  : Server started [callback: Mono.WebServer.FastCgi.ServerProxy]
    

    On top of mono:4.0.0 docker image installed:

    apt-get install -y ca-certificates nginx=1.9.5-1~wheezy
    apt-get install -qy mono-fastcgi-server4
    apt-get install -qy mono-xsp4
    apt-get install -qy fsharp
    

    Also I’m ensuring that mono 4.5 is used for the application:

    sed -ie 's|mono/4.0|mono/4.5|g' /usr/bin/fastcgi-mono-server4 \
    && sed -ie 's|mono/4.0|mono/4.5|g' /usr/bin/xsp4
    

    And my nginx.conf

    worker_processes  1;
    events {
       worker_connections  1024;
    }
    http {
       include       mime.types;
       default_type  application/octet-stream;
       sendfile        on;
       keepalive_timeout  65;
       server {
           listen       80 default;
           access_log   /dev/stdout;
           error_log    /dev/stdout;
           root         /var/www/websharper;
           index        main.html;
           location / {
               root                /var/www/websharper/;
               fastcgi_pass        172.17.0.40:32775;
               include             /etc/nginx/fastcgi_params;
           }
           error_page   500 502 503 504  /50x.html;
           location = /50x.html {
               root   html;
           }
       }
    }
    

    and finally fastcgi_params

    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    fastcgi_param  PATH_INFO         "";
    fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
    

    Update:

    I have found in sources that TcpSocket is assigning Loopback ip if you choose Any ip… which is weird…

    class TcpSocket : StandardSocket {
        public TcpSocket (System.Net.IPEndPoint localEndPoint)
            : base (System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream,
                    System.Net.Sockets.ProtocolType.IP, localEndPoint)
        {
        }
    
        public TcpSocket (System.Net.IPAddress address, int port)
            : this (new System.Net.IPEndPoint (Equals(address, System.Net.IPAddress.Any) ?
                System.Net.IPAddress.Loopback : address, port))
        {
        }
    }
    

    Anyway I have tried to use set ip address directly for mono server(by linking nginx container to mono container)

    fastcgi-mono-server4 /printlog=True /applications=/:/var/www/websharper/ /socket=tcp:$(printenv NGINX_HOST_PORT_80_TCP_ADDR):9000 /loglevels=All /verbose=True
    

    and running the box with

    docker run --name t2 --link t1:nginx_host -it -P vasylpurchel/docker-websharper
    

    where t1 is a box with nginx running in it
    This test also failed with:

    root@dc540db6577f:/#     8: 1 fastcgi-mono-server [2015-10-02 14:32:05.147774] Debug  : fastcgi-mono-server4
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.154128] Debug  : Uid 0, euid 0, gid 0, egid 0
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.155000] Debug  : Root directory: /
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.156562] Notice : Adding applications '/:/var/www/websharper/'...
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.157182] Notice : Registering application:
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.157457] Notice :     Host:          any
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.157908] Notice :     Port:          any
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.158195] Notice :     Virtual path:  /
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.158489] Notice :     Physical path: /var/www/websharper/
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.169995] Debug  : Parsed tcp:172.17.0.5:9000 as URI tcp:172.17.0.5:9000
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.181117] Debug  : Listening on port: 9000
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.182573] Debug  : Listening on address: 172.17.0.5
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.186638] Debug  : Max connections: 1024
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.187418] Debug  : Max requests: 1024
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.187767] Debug  : Multiplex connections: False
    8: 1 fastcgi-mono-server [2015-10-02 14:32:05.192868] Error  : Failed to start server Mono.WebServer.FastCgi.Sockets.    TcpSocket: The requested address is not valid in this context (10049)
    Unhandled Exception:
    System.Net.Sockets.SocketException: The requested address is not valid in this context
    at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end) [0x00000] in <filename unknown>:0
    at Mono.WebServer.FastCgi.Sockets.StandardSocket.Listen (Int32 backlog) [0x00000] in <filename unknown>:0
    at Mono.WebServer.FastCgi.GenericServer`1[Mono.WebServer.FastCgi.ConnectionProxy].Start (Boolean background, Int32 backlog) [    0x00000] in <filename unknown>:0
    [ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException: The requested address is not valid in this context
    at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end) [0x00000] in <filename unknown>:0
    at Mono.WebServer.FastCgi.Sockets.StandardSocket.Listen (Int32 backlog) [0x00000] in <filename unknown>:0
    at Mono.WebServer.FastCgi.GenericServer`1[Mono.WebServer.FastCgi.ConnectionProxy].Start (Boolean background, Int32 backlog) [0x00000] in <filename unknown>:0
    

    Address 172.17.0.5 was an IpAddress of container with nginx running on.

  • Port forwarding with Elastic docker image
  • Docker cannot start MongoDb with attached volume through data-only container
  • Trying to pull image from private-repo.microsoft.com
  • Docker – fix service IP addresses [duplicate]
  • Trouble while logging to docker hub registry from bootdocker in windows
  • What components should be “containerized” - Docker
  • One Solution collect form web for “fastcgi-mono-server4 and nginx with docker”

    The fastcgi-mono-server4 has a limitation on docker container with the listening address when you use the parameter

    • /socket=tcp:9000 only listen in localhost
    • /socket=tcp:0.0.0.0:9000 only listen in localhost, weird but true

    to fix the fastcgi-mono-server4 behavior, you have to use the docker container IP address in socket parameter

    • /socket=tcp:IPContainer:9000
    • /socket=tcp:$(ip -4 addr show eth0| grep -Po ‘inet \K[\d.]+’):9000

    you need to fix the command inside the Docker container

    fastcgi-mono-server4 /applications=/:/var/www/websharper/ /socket=tcp:$(ip -4 addr show eth0| grep -Po 'inet \K[\d.]+'):9000
    

    This is an example the Dockerfile fixed

    FROM mono:latest
    
    RUN apt-get update
    RUN apt-get install -y mono-fastcgi-server4
    RUN rm -rf /var/lib/apt/lists/* /tmp/*
    
    RUN echo "#!/bin/sh\nfastcgi-mono-server4 /applications=/:/var/www/websharper/ /socket=tcp:\$(ip -4 addr show eth0| grep -Po 'inet \K[\d.]+'):9000" > /opt/mono-fastcgi
    RUN chmod +x /opt/mono-fastcgi
    
    EXPOSE 9000
    
    CMD [ "/opt/mono-fastcgi" ]
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.