Websocket using official docker image and nginx

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • SkylerK-GG
    Junior Member
    • Nov 2025
    • 2

    #1

    Websocket using official docker image and nginx

    Hello all,

    I have inherited a mostly set up and in use espo instance at my company, and am attempting to get websockets working on it. The compose.yml is based on the one on the page for the official docker espo image, with the addition of a phpmyadmin container, as follows:

    Code:
    services:
    
      espocrm-db:
        image: mariadb:latest
        container_name: espocrm-db
        environment:
          MARIADB_ROOT_PASSWORD: [REDACTED]
          MARIADB_DATABASE: espocrm
          MARIADB_USER: espocrm
          MARIADB_PASSWORD: [REDACTED]
        volumes:
          - espocrm-db:/var/lib/mysql
        restart: always
        healthcheck:
          test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
          interval: 20s
          start_period: 10s
          timeout: 10s
          retries: 3
        ports:
          - 8956:3306
    
      espocrm:
        image: espocrm/espocrm
        container_name: espocrm
        environment:
          ESPOCRM_DATABASE_PLATFORM: Mysql
          ESPOCRM_DATABASE_HOST: espocrm-db
          ESPOCRM_DATABASE_USER: espocrm
          ESPOCRM_DATABASE_PASSWORD: [REDACTED]
          ESPOCRM_ADMIN_USERNAME: admin
          ESPOCRM_ADMIN_PASSWORD: [REDACTED]
          ESPOCRM_SITE_URL: "https://espo.[COMPANYSITE].com"
        volumes:
          - espocrm:/var/www/html
        restart: always
        depends_on:
          espocrm-db:
            condition: service_healthy
        ports:
          - 8888:80
    
      espocrm-phpmyadmin:
        image: phpmyadmin/phpmyadmin
        container_name: espocrm-phpmyadmin
        links:
          - espocrm-db
        environment:
          PMA_HOST: espocrm-db
          PMA_PORT: 3306
          PMA_ARBITRARY: 1
        restart: always
        ports:
          - 8583:80
    
    
      espocrm-daemon:
        image: espocrm/espocrm
        container_name: espocrm-daemon
        volumes:
          - espocrm:/var/www/html
        restart: always
        entrypoint: docker-daemon.sh
    
      espocrm-websocket:
        image: espocrm/espocrm
        container_name: espocrm-websocket
        environment:
          ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
          ESPOCRM_CONFIG_WEB_SOCKET_URL: "wss://espo.[COMPANYSITE].com:8081"
          ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: "tcp://*:7777"
          ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: "tcp://espocrm-websocket:7777"
        volumes:
          - espocrm:/var/www/html
        restart: always
        entrypoint: docker-websocket.sh
        ports:
          - 8081:8080
    
    
    
    
    volumes:
      espocrm-db:
      espocrm:
    There is also an Nginx Proxy Manager instance, which has separate proxy hosts defined for the espo application and the websocket connection.

    The error I'm getting in the web console for the websockets is this:

    Code:
    autobahn.js:341WebSocket connection to 'wss://espo.[COMPANYSITE].com:8081/?authToken=e0e4afb…&userId=682dff6b85b8b6ef6' failed:
      ab.Session @ autobahn.js:341
    Which, when clicked provides the following additional info:
    Code:
    Could not load content for https://espo.[COMPANYSITE].com/client/lib/original/autobahn.js (HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE)
    I'm at the very edge of my depth here, and I'm not sure what all information might be needed to figure this one out. Please let me know what else might be needed.
  • tgr
    Junior Member
    • Jun 2025
    • 13

    #2
    If you open the network tab in the web console and locate the wss connection there, what do you see?
    Can you run the following command, what is the output?
    Code:
    curl -v -H "Upgrade: websocket" -H "Connection: Upgrade" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Protocol: wamp" -H "Sec-WebSocket-Key: yqCENxArRr1WR3Z0OUzxbw==" your url here

    On a side note, I see that you have mapped a port for MariaDB. Do you really mean to expose the database directly outside your Compose stack? Containers within the same compose file can communicate via with each other without mapping ports to the outer world.

    Comment

    • SkylerK-GG
      Junior Member
      • Nov 2025
      • 2

      #3
      Thanks for pointing that port out, was put there to test something before and never removed afterwards.

      Here is what I get from curl:
      Code:
      *   Trying [COMPANYIP]:80...
      * Connected to espo.[COMPANYSITE].com ([COMPANYIP]) port 80 (#0)
      > GET / HTTP/1.1
      > Host: espo.[COMPANYSITE].com
      > User-Agent: curl/7.81.0
      > Accept: */*
      > Upgrade: websocket
      > Connection: Upgrade
      > Sec-WebSocket-Version: 13
      > Sec-WebSocket-Protocol: wamp
      > Sec-WebSocket-Key: yqCENxArRr1WR3Z0OUzxbw==
      >
      * Mark bundle as not supporting multiuse
      < HTTP/1.1 301 Moved Permanently
      < Server: openresty
      < Date: Tue, 18 Nov 2025 18:43:17 GMT
      < Content-Type: text/html
      < Content-Length: 166
      < Connection: keep-alive
      < Location: https://espo.[COMPANYSITE].com/
      <
      <html>
      <head><title>301 Moved Permanently</title></head>
      <body>
      <center><h1>301 Moved Permanently</h1></center>
      <hr><center>openresty</center>
      </body>
      </html>

      Comment


      • tgr
        tgr commented
        Editing a comment
        My bad. You should point the curl command towards your websocket endpoint, not the website. IIUC, we should see the server reply with a 101 switching protocols

      • SkylerK-GG
        SkylerK-GG commented
        Editing a comment
        running pointed at the websocket endpoint gives me this:

        Code:
        <html>
        <head><title>301 Moved Permanently</title></head>
        <hr><center>openresty</center>
        </body>
        </html>
        * Connection #0 to host espows.[COMPANYSITE].com left intact
        > Sec-WebSocket-Protocol: wamp
        > Sec-WebSocket-Key: yqCENxArRr1WR3Z0OUzxbw==
        >
        * Mark bundle as not supporting multiuse
        < HTTP/1.1 301 Moved Permanently
        </body>
        >
        < Date: Fri, 21 Nov 2025 22:35:50 GMT
        </html>
        * Closing connection 0
        * ALPN, offering h2
        * ALPN, offering http/1.1
        *  CAfile: /etc/ssl/certs/ca-certificates.crt
        *  CApath: /etc/ssl/certs
        * TLSv1.2 (IN), TLS header, Finished (20):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        *  CAfile: /etc/ssl/certs/ca-certificates.crt
        *  CApath: /etc/ssl/certs
        * TLSv1.0 (OUT), TLS header, Certificate Status (22):
        * TLSv1.3 (OUT), TLS handshake, Client hello (1):
        * TLSv1.2 (IN), TLS header, Finished (20):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, Certificate (11):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, CERT verify (15):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, Finished (20):
        * TLSv1.2 (OUT), TLS header, Finished (20):
        * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * TLSv1.3 (OUT), TLS handshake, Finished (20):
        * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
        * ALPN, server accepted to use h2
        * Server certificate:
        *  subject: CN=espows.[COMPANYSITE].com
        *  start date: Nov 21 20:02:39 2025 GMT
        *  expire date: Feb 19 20:02:38 2026 GMT
        *  subjectAltName: host "espows.[COMPANYSITE].com" matched cert's "espows.[COMPANYSITE].com"
        *  issuer: C=US; O=Let's Encrypt; CN=E8
        *  SSL certificate verify ok.
        * Using HTTP2, server supports multiplexing
        * Connection state changed (HTTP/2 confirmed)
        * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * Using Stream ID: 1 (easy handle 0x56015453e9f0)
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        > GET / HTTP/2
        > Host: espows.[COMPANYSITE].com
        > user-agent: curl/7.81.0
        > accept: */*
        > upgrade: websocket
        > connection: Upgrade
        > sec-websocket-version: 13
        > sec-websocket-protocol: wamp
        > sec-websocket-key: yqCENxArRr1WR3Z0OUzxbw==
        >
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
        * old SSL session ID is stale, removing
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.2 (IN), TLS header, Supplemental data (23):
        * TLSv1.2 (OUT), TLS header, Supplemental data (23):
        * HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
        * stopped the pause stream!
        * Connection #0 to host espows.[COMPANYSITE].com left intact
        curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
        I don't see a 101, but it certainly did appear to do something websocket related.
    Working...