Laravel Websockets with Devilbox

Hi,

I am trying to set up https://docs.beyondco.de/laravel-websockets/ in Devilbox.

I am using Laravel 7.x and all the latest version of Laravel Websockets. I have installed it using Composer and I did everything as instructed in the documentation.

Once I SSH to the Devilbox using “./shell.sh” and CD into my project I use the command “php artisan websockets:serve” which gets stuck on “Starting the WebSocket server on port 6001…”.

I am assuming that this is related to 6001 port not being open. I have tried EXPOSE-ing it and many other things that I found while Google-ing it, but no luck.

Any tips or suggestions will be greatly appreciated!

Thank you,
Jure

1 Like

If you want to expose another port, you will have to customize your vhost templates for that specific project. An example for NodeJS can be found in the documentation here: https://devilbox.readthedocs.io/en/latest/examples/setup-reverse-proxy-nodejs.html

Only use port 6001 instead 4000 what the docs use.

I tried that example but now I get the devilbox dashboard on all websites.

I fiddled around for hours now without any luck.

could you please try the websockets demo (https://github.com/beyondcode/laravel-websockets-demo) and let me know how to get it running?

thanks a lot

I am getting a 404, but that’s probably due to the reason that I’ve not setup the database correctly (the GitHub page didn’t have the instructions).

The vhost-gen config nginx.yml that I am using is as follows:

---

# Nginx Reverse Proxy Template defintion for vhost-gen.py
#
# The 'feature' section contains optional features that can be enabled via
# conf.yml and will then be replaced into the main vhost ('structure' section)
# into their corresponding position:
#
#    __XDOMAIN_REQ__
#    __ALIASES__
#    __DENIES__
#    __STATUS__
#
# The features itself also contain variables to be adjusted in conf.yml
# and will then be replaced in their corresponding feature section
# before being replaced into the vhost section (if enabled):
#
# XDomain:
#    __REGEX__
# Alias:
#    __REGEX__
#    __PATH__
# Deny:
#    __REGEX__
# Status:
#    __REGEX__
#
# Variables to be replaced directly in the vhost configuration can also be set
# in conf.yml and include:
#    __VHOST_NAME__
#    __DOCUMENT_ROOT__
#    __INDEX__
#    __ACCESS_LOG__
#    __ERROR_LOG__
#


###
### Basic vHost skeleton
###
vhost: |
  server {
      listen       __PORT____HTTP_PROTO____DEFAULT_VHOST__;
      server_name  __VHOST_NAME__;

      access_log   "__ACCESS_LOG__" combined;
      error_log    "__ERROR_LOG__" warn;

      # Reverse Proxy definition (Ensure to adjust the port, currently '8000')
      location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://php:6001;
      }

  __REDIRECT__
  __SSL__
  __ALIASES__
  __DENIES__
  __SERVER_STATUS__
      # Custom directives
  __CUSTOM__
  }

###
### vHost Type (normal or reverse proxy)
###
vhost_type:
  docroot: ""
  rproxy: ""

###
### Optional features to be enabled in vHost
###
features:

  # SSL Configuration
  ssl: |
    ssl_certificate           __SSL_PATH_CRT__;
    ssl_certificate_key       __SSL_PATH_KEY__;
    ssl_protocols             __SSL_PROTOCOLS__;
    ssl_prefer_server_ciphers __SSL_HONOR_CIPHER_ORDER__;
    ssl_ciphers               __SSL_CIPHERS__;

  # Redirect to SSL directive
  redirect: |
    return 301 https://__VHOST_NAME__:__SSL_PORT__$request_uri;

  # PHP-FPM left empty, as we are an reverse proxy configuration
  php_fpm: ""

  alias: |
    # Alias Definition
    location ~ __ALIAS__ {
        root  __PATH__;
    __XDOMAIN_REQ__
    }

  deny: |
    # Deny Definition
    location ~ __REGEX__ {
        deny all;
    }

  server_status: |
    # Status Page
    location ~ __REGEX__ {
        stub_status on;
        access_log off;
    }

  xdomain_request: |
    # Allow cross domain request from these hosts
    if ( $http_origin ~* (__REGEX__) ) {
        add_header "Access-Control-Allow-Origin" "$http_origin";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Max-Age' 0;
        return 200;
    }

Additionally I’ve also changed their .env file for the APP_URL

APP_URL=http://websock.loc

Before you run “php artisan migrate” you need to create a DB and put the credentials into the .env
placeholder is “homestead”.

Did this now, but getting a:

devilbox@php-7.4.8 in /shared/httpd/websock/laravel-websockets-demo $ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table

   Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

  at /shared/httpd/websock/laravel-websockets-demo/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668|

  Exception trace:

  1   PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes")
      /shared/httpd/websock/laravel-websockets-demo/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /shared/httpd/websock/laravel-websockets-demo/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  Please use the argument -v to see more details.

fix:

1 Like

Tried this now and the install went fine.

I started artisan (stays in foreground)

devilbox@php-7.4.8 in /shared/httpd/websock/laravel-websockets-demo $ php artisan websockets:serve
Starting the WebSocket server on port 6001...

And on another terminal I tried to get data from localhost, but this results in a 404

devilbox@php-7.4.8 in /shared/httpd $ curl -v localhost:6001
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 149999 ms for 3 (transfer 0x556532acef50)
* Expire in 200 ms for 4 (transfer 0x556532acef50)
* Connected to localhost (127.0.0.1) port 6001 (#0)
> GET / HTTP/1.1
> Host: localhost:6001
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Powered-By: Ratchet/0.4.1
* no chunk, no close, no size. Assume close to signal end
<
* Closing connection 0

Doing the same with the reverse vhost:

devilbox@php-7.4.8 in /shared/httpd $ curl -v websock.loc
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55cc026eaf50)
* Connected to websock.loc (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: websock.loc
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.16.1
< Date: Tue, 14 Jul 2020 13:54:00 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: Ratchet/0.4.1
< Via: 1.1 httpd (nginx/1.16.1)
<
* Connection #0 to host websock.loc left intact

So exact same result. This means the reverse vhost works, but artisan is somewhat not correctly setup.

When you remove your reverse proxy config you get the normal output served by php.

So there needs to be both ports open: 8000 for normal php and 6001 for websocket.

Did you manage to get it working? I’ve run into the same issue trying to run laravel-websockets

here’s my solution found in StackOverFlow

Quick question for @cytopia

how do I setup nginx to serve / as port 80 and /ws as port 6001?

do I need to create 2 location?

something like this??

location /ws {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://php:6001;
      }
location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://php:8000;
      }

Asking this because I have currently found a way to serve laravel-websocket… but I needed it to serve in 2 domains…(See Stackoverflow Answer)

Tried comparing vhost and rproxy nginx configs…

but it’s very different… I could see that vhost has php-fpm config while rproxy doesn’t…

I could also see that vhost has vhost-type config while rproxt doesn’t…

I am not expert enough in Nginx to modify this configs…

what we need here is to let nginx use / for php-fpm and /wsapp as a reverse-proxy to port 6001…

is that even possible? or was my answer on SO the perfect solution already?