ashwinmram's avatar

Laravel-Echo-Server installation on Forge with SSL Enabled with the Redis broadcast driver and Socket.io

I was trying to figure this out and managed to get everything working finally and thought I'd share my configuration for those interested.

0 likes
19 replies
ashwinmram's avatar

Install echo server globally through npm install -g laravel-echo-server

Navigate to project root then run laravel-echo-server init

Do you want to run this server in development mode? No

Which port would you like to serve from? 6001

Which database would you like to use to store presence channel members? redis

Enter the host of your Laravel authentication server. https://project-domain.com

Will you be serving on http or https? https

Enter the path to your SSL cert file. /etc/nginx/ssl/project-domain.com/XXXXXX/server.crt

Enter the path to your SSL key file. /etc/nginx/ssl/project-domain.com/244397/server.key

(You can get these from Forge by navigating to your Site and selecting Edit Files > Edit Nginx Configuration)

Do you want to generate a client ID/Key for HTTP API? Yes

Take note of the Client ID and Key that is displayed. If not, you can always reference them in the laravel-echo-server.json

Now open up laravel-echo-server.json in the project root, and change the redis databaseConfig to the following:

    "redis": {
        "port": "6379",
        "host": “project-domain.com”
    },
    "sqlite": {}

Now update your .env with the Client ID and Key

    PUSHER_APP_ID=client_id
    PUSHER_KEY=client_key
    PUSHER_SECRET=null

Remember to run php artisan config:cache if you have cached configuration that needs to be reloaded.

You will now need to update resources/assets/js/bootstrap.js as follows. Take note of the namespace parameter, which will affect the socket listens for Laravel Events.

    window.Echo = new Echo({
        namespace: ‘App\\Events',
        broadcaster: 'socket.io’,
        host: 'project-domain.com:6001'
    });

Now you can update your view to include the following. I placed it in the HTML head:

    <script src="https://project-domain.com:6001/socket.io/socket.io.js"></script>

We now need to open the ports to allow socket.io and redis to work. In Forge under Server Details click on Network.

I used the following settings here: Name: SOCKETIO Port: 6001

Name: REDIS Port: 6379

I left the from IP field blank in both cases because I am not sure how to restrict the IP to just the localhost. I tried 127.0.0.1 but it didn’t work.

Test the echo server by running laravel-echo-server start from the project root.

You should now see

 Starting server...

✔  Running at localhost on port 6001
✔  Channels are ready.
✔  Listening for http events...
✔  Listening for redis events...

Server ready!

It is important that the http events and redis events are ticked. Now stop the laravel-echo-server.

The final step that remains is to start up laravel-echo-server as a daemon process. This will ensure that Supervisor will keep the process running at all times. In Forge under Server Details now click on Daemons.

Use the following settings here:

Command: /usr/bin/laravel-echo-server start

User: forge

Directory: /home/forge/your-domain.com

Everything else you need to know is included in Taylor’s Laracasts on Echo :)

https://laracasts.com/lessons/introducing-laravel-echo

Good luck!

10 likes
natcave's avatar

Thanks so much for sharing @ashwinmram!

I just wish I found this post 16 hours ago. :-) You pretty much outlined all the steps I stumbled upon but I hit a roadblock trying to get it working with Forge. It's so much simpler when you have the steps outlined like this. For a moment I thought I would have to leave my terminal window open permanently lol.

I'm sure you'll help plenty of other newbs like myself. This topic is definitely worthy of a video for Jeffrey. Especially since a lot of the videos surrounding these topics are now a bit outdated. They're helpful to put you on the right track but they don't quite complete the picture for someone beginning a project today.

It works great so far, will keep an eye on it. Just dropping a line to show my appreciation. Thanks again!

ashwinmram's avatar

Thank you for your note of appreciation @natcave. We're so blessed to be part of the Laravel community! Good luck with all your projects :)

1 like
Trevald's avatar

Best guide ever. This should be part of the official docs.

skeith22's avatar

@ashwinmram have you tried that your redis server is on a different server? so that means you have to proxy your laravel-echo-server to let the main server communicate with your redis server which is located on a different server.

ashwinmram's avatar

@skeith22 Sorry I haven't tried that but just thinking out loud here...

  1. If the other server is created using Forge you will need to open the REDIS port as I detailed above.

In actual fact, because Redis is on the same server in my configuration above, we don't actually need to open the Redis port; we just need to open the port for socket.io

  1. You will need to change the host in laravel-echo-server.json before starting it up to either the redis server's domain name (if there is one), or perhaps even the IP.
"redis": {
        "port": "6379",
        "host": “redis-domain.com”
    },

If you figure this out please let me know!

hemratna.bhimani@gmail.com's avatar

Hi @ashwinmram Thanks a lot for such a wonderful answer.

I have one small question here. As we are hardcoding the SSL certificate path, the Let's encrypt certificate is valid to 3 months. So when forge auto update the SSL, Is there any way that the same certificate path also get update on our config file or we have to do manually change the path?

If we have to change the path manually, then we don't know on which date the certificate get expire and new certificate generated.

Any thoughts on this are really helpful.

Regards,

ashwinmram's avatar

Hi @hemratna, that is a great point! The strange thing is I've never had an issue as yet, which is surprising. I'm quite sure I used this hardcoded configuration for more than 3 months on my old server.

I now realize that my new server with this hardcoded configuration is using a Let's Encrypt certificate from Apr 13. Perhaps I'll ping you end of next month if something breaks!

I did some digging, and it appears that Forge actually renews the certificates every week on Sunday as per Taylor Otwell himself! Please see: https://laravel-news.com/forge-letsencrypt-improvements

Taylor must have coded it so that whenever the new certificate is being generated, the path/folder and filename are preserved. My certificate files still have the Apr 13 date, so I'm not sure what exactly is going on.

If I remember I'll reply on this thread next month if I have any issues.

1 like
hemratna.bhimani@gmail.com's avatar

Hi @ashwinmram, Thanks a lot for your answer and resource links. I will wait for your comment after July 13, if anything breaks or not.

Meanwhile now onward I will use the Cloudflare SSL which has larger validity.

Thanks a lot.

Have a great day.

ashwinmram's avatar

Hi @hemratna I got an answer for you. Laravel echo server did indeed stop working after the certificate was renewed. The path of the certificate did not change, however, but the changes didn't get picked up by the echo server daemon worker. I had to just restart the daemon worker from the Forge server panel, and then everything worked just as before.

I think the Cloudflare SSL is your best bet, so I'm glad you went down that route. I still haven't launched my app in production yet, so I'm fine with things as they are for now with the Let's Encrypt SSL, but once I'm ready to launch I'll switch to Cloudflare as well like in Taylor's article.

All the best to you buddy.

Cronix's avatar

@ashwinmram Sounds like that could be added to the letsencrypt renewal script (assuming that's what's being used). It would be nice if Forge let you run "recipes" at various events/points in the server, like an "after ssl renewal" script or something, like they do for deployment scripts.

ashwinmram's avatar

@Cronix That's very true... then the configuration above would do the trick :) Another very hacky and less seamless approach would be to somehow monitor the server cert and key file timestamps and then immediately trigger the daemon to restart via the forge api when they change.

POST /api/v1/servers/{serverId}/daemons/{daemonId}/restart

I don't think Taylor and Mohamed are going to be adding the hook we need, so I think when the time comes to officially launch production I will still go the Cloudflare route.

secondman's avatar

@ashwinmram

I wasn't able to get the daemon to work. I have laravel-echo-server installed globally via nvm.

I used the command:

/home/forge/.nvm/versions/node/v8.15.0/bin/laravel-echo-server start

but I'm getting an error exited too quickly.

It seems like the laravel-echo-server command isn't found. When I log in via ssh I can run it fine, but the server can't seem to run it.

If I put laravel-echo-server restart in my Deploy script, I get the error:

line 9: laravel-echo-server: command not found

Any ideas on how to get this rolling?

MohamadSleimanHaidar's avatar

Thanks a lot for the instructions. I followed through but keep getting "Client can not be authenticated, got HTTP status 419" whenever it tries to authenticate for the first time and then seems to authenticate correctly. "Seems" because the listeners in the app don't seem to be picking up any events. Would you happen to know how to resolve a 419 error? Thank you.

ashwinmram's avatar

Sorry @vkronlein and @mohamadsleimanhaidar I only just saw that you are having an issues. I didn't face either of these issues and am still using the same setup on my server. I hope you were able to resolve this. Spatie and BeyondCode now have a web sockets package that you can use instead!

Please or to participate in this conversation.