How do i setup websocket on GCP Flex environment? - laravel

I am using laravel 6 and I want to deploy laravel based websocket server using supervisor on google cloud Flex app engine platform.
I am using this package: beyondcode/laravel-websockets
I have setup everything and everything is working fine on local machine! What is the exact procedure to follow to deploy it on GCP?
My additional-supervisord.conf
[program:websockets]
command = php %(ENV_APP_DIR)s/artisan websockets:serve
enviroment = PORT="6001"
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes=0
user = root
autostart = true
autorestart = true
priority = 10
stopwaitsecs = 20
App.yaml
runtime: php
env: flex
runtime_config:
document_root: public
service: orders
skip_files:
- .env
#only for testing purpose.
manual_scaling:
instances: 1
env_variables:
APP_NAME: "Havn"
BROADCAST_DRIVER: pusher
PUSHER_APP_ID: SOMEID
PUSHER_APP_KEY: SOMEKEY
PUSHER_APP_SECRET: SOMESECRET
PUSHER_APP_CLUSTER: mt1
LARAVEL_WEBSOCKETS_PORT: 6001
PUSHER_SCHEME: https
PUSHER_HOST: 127.0.0.1
PUSHER_PORT: 6001
QUEUE_DRIVER: database
beta_settings:
cloud_sql_instances: "INSTANCE ID"

You can find in the official documentation how to use WebSockets to create a persistent connection from a client (such as a mobile device or a computer) to an App Engine instance.
Please consider that WebSockets connection will time out after one hour.
Creating Persistent Connections with WebSockets PHP

Related

DDEV: How to etablish websocket connections

I'm having some problems to establish a websocket connection to a running ddev container.
Trying wo etablish the connection per JS for example with wss://websocket.ddev.site:3000 ends always up with connection failed.
Websocket PHP library used: Ratchet (http://socketo.me/)
I tried to set the ext. container port in an own docker-compose.yaml or web_extra_exposed_ports in config.yaml but nothig worked so far.
I have managed to run a Websocket connection.
Therefore, I did an entry in config.yaml of DDEV with following Content:
web_extra_exposed_ports:
- name: ratchet
container_port: 3000
http_port: 3000
https_port: 3001
After DDEV restart, it is now possible to establish a Websocket connections with:
HTTP: 'ws://websocket.ddev.site:3000'
HTTPS: 'wss://websocket.ddev.site:3001'
My working example was build with the tutorial on http://socketo.me/docs/hello-world calling above URL with Browser console.

how do you enable ssl using laravel 8 sail

I just created a new Laravel 8 project, following the instructions in their docs. Using Laravel Sail I have the site running locally on my machine just fine using sail up. I have set up an entry in /etc/hosts so the url I go to is http://local.dev.domain.com (substituting domain.com for the actual domain name I own, and pointing to localhost in the /etc/hosts file)...all works great.
However, the site needs to use Facebook Login, and Facebook requires https urls only on referrers. I've tried everything I could find online about setting up SSL certs with docker, but setting up nginx with manually created certs (via mkcert) or trying to use letsencrypt all fails for various reasons (conflicts in ports, letsencrypting wanting the domain to be a real one (and failing on the acme challenge if I do create that subdomain), etc. I've copied the certs to /etc/ssl/certs in the docker image and run update-ca-certificates, tried setting the application port 443 in my .env file as well as opening both ports 80 and 443 in the docker-compose.yml file...but all ends in the browser rejecting the request to https://local.dev.domain.com
I've spent hours trying to get this to work but it doesn't seem like anyone has used the Laravel Sail docker image with SSL.
Any pointers?
[Edit for more info]
As pointed out in the comments, you need to set an alias to just use sail ..., but I've already done that:
I also tried without the bash alias using vendor/bin/sail share to no avail:
Problem
In your case you need a real domain, which you have. A self-signed certificate would not work as Facebook would not acknowledge it as trusted. To get a free ssl certificate for that domain you can use Let's Encrypt, the easiest way to obtain that certificate is using certbot. The problem is that you need to install that certificate on your webserver. Laravel Sail uses the build-in webserver that does not support ssl unfortunatly. You need to put a webserver like nginx in front of the app and install the certificate there.
I'm currently working on a fork that enables what you need, however it's not finished.
Workaround
For now you can use the build in tunnel provided by Expose: https://beyondco.de/docs/expose/server/ssl
This is enable by sail share
It might be easier to use ngrok instead, which is essentialy the same but commercial. Than all you have to do is download, register and run ngrok http --region=eu 9000 and it will create a https link for you for development.
I solved this problem by using Caddy as a reverse proxy to the Laravel Sail container. Caddy has a feature called automatic HTTPS which can generate local certificates on the fly.
1 - Add Caddy as a service to your docker-compose.yml
services:
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- './docker/Caddyfile:/etc/caddy/Caddyfile'
- sailcaddy:/data
- sailcaddy:/config
networks:
- sail
# Remove "ports" from laravel.test service
volumes:
sailcaddy:
driver: local
2 - Create a simple Caddyfile and configure it as a reverse proxy
{
on_demand_tls {
ask http://laravel.test/caddy-check
}
local_certs
}
:443 {
tls internal {
on_demand
}
reverse_proxy laravel.test {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Port {server_port}
header_up X-Forwarded-Proto {scheme}
health_timeout 5s
}
}
3 - Set up an endpoint for Caddy to authorise which domains it generates certificates for
<?php
namespace App\Http\Controllers;
use App\Store;
use Illuminate\Http\Request;
class CaddyController extends Controller
{
public function check(Request $request)
{
$authorizedDomains = [
'laravel.test',
'www.laravel.test',
// Add subdomains here
];
if (in_array($request->query('domain'), $authorizedDomains)) {
return response('Domain Authorized');
}
// Abort if there's no 200 response returned above
abort(503);
}
}
See this gist for the full code changes involved. This blog post explains how to trust the Caddy root certificates.
For make "sail share" work you have to set alias and run "composer require laravel/sail --dev" on your project. This will install the latest version of sail, version 0.0.6 includes "share" command
There is actually an easier way. I did the following:
changed laravel.test port to something else like 8085
do it from .env so u will avoid issues, add APP_PORT env var
then (this step has been done by our sys admin) since laravel sail is actually installing apache in the system, u can manually set a reverse proxy for both port 80 and 443 to port 8085 and that should do the trick.
of course u will have to install certbot on that apache instance.

How do I fix the http 500 bad gatway when delploying Docker to GCP App Engine?

I want to deploy my spring boot app in a docker component to gcp App Engine
When I run the docker componet local I get access to the web site.
When I deploy the component to the gcp app engine with the command gcloud app deploy
I get a http error 502 Bad Gateway nginx
The Docker file look like this
FROM adoptopenjdk/openjdk14
MAINTAINER steinko
VOLUME /tmp
COPY build/libs/atm.jar ./
ENTRYPOINT ["java"]
CMD ["-jar", "/atm.jar"]
EXPOSE 4001
The app.yaml files looks like this
runtime: custom
env: flex
handlers:
- url: /.*
script: this field is required, but ignored
service: atm
How do I fix this error?
According to this document: The App Engine front end will route incoming requests to the appropriate module on port 8080. You must be sure that your application code is listening on 8080. Also, it looks like the FROM should be one of Google's base image, also in that document.

gcloud app SQLSTATE[HY000] [2002] Connection timed out

I have created laravel application with database it run on localhost so i decide to deploy on GCP appengine but when i click on deploy this happen
SQLSTATE[HY000] [2002] Connection timed out
i connecting to my GCP sql Instance below are my app.yaml
1st i use local host that uses sql_proxy it show no files directory then i remove the DB_Socket then this error come out SQLSTATE[HY000] [2002] Connection timed out
runtime: php
env: flex
runtime_config:
document_root: public
Ensure we skip ".env", which is only for local development
skip_files:
- .env
env_variables:
# Put production environment variables here.
APP_LOG: errorlog
APP_KEY: base64:G9druqluKMZ6TugSgmM1OJVwWSzfstc08acMRBAqxwg=
CACHE_DRIVER: database
SESSION_DRIVER: database
## Set these environment variables according to your CloudSQL configuration.
DB_HOST: 35.231.242.40
DB_DATABASE: lkcfes
DB_USERNAME: root
DB_PASSWORD:
This question is more appropriate for a support case so that a Google Cloud Platform support agent can inspect your app.yaml and Cloud SQL instance.
Having said that, there is a guide here on running Laravel on GAE Flex. You'll find it includes using a "beta_settings" section on your yaml, the Cloud SQL instance's public IP is not used.

Connecting Laravel to GAE Cloud SQL Database with PostgreSQL

I am deploying a new application to Google App Engine Flex environment. The app is powered by Laravel.
I am able to connect to the database on my local machine, however, I am unable to connect to the database once I deploy my application.
What information do I need to include in the app.yaml file to connect to the database? Do I require any other information in a different file?
"message": "SQLSTATE[08006] [7] could not connect to server: Connection refused\n\tIs the server running on host \"localhost\" (::1) and accepting\n\tTCP/IP connections on port 5432?\ncould not connect to server: Connection refused\n\tIs the server running on host \"localhost\" (127.0.0.1) and accepting\n\tTCP/IP connections on port 5432? (SQL: select * from \"users\" where \"email\" = mitchell#efficialtec.com and \"users\".\"deleted_at\" is null limit 1)",
This is the contents of my .ENV file which allows me to connect locally
APP_ENV=development
APP_KEY=base64:B0G3Yr82fWO7xw8LrvcOC19DGUAEd32loJlPHCfP2sg=
APP_DEBUG=true
LOG_CHANNEL=stack
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_POST=5432
DB_DATABASE=DATABASE
DB_USERNAME=USERNAME
DB_PASSWORD=PASSWORD
DB_SOCKET: "/cloudsql/CONNECTION_NAME"
This is the contents of my app.yaml file:
env: flex # let app engine know we use flexible environment
service: SERVICENAME
automatic_scaling:
min_num_instances: 1
max_num_instances: 2
cpu_utilization:
target_utilization: 0.8
runtime_config:
document_root: public
skip_files:
- .env #we want to skip this to make sure we don’t mess stuff up on the server
env_variables:
# Put production environment variables here.
APP_ENV: development
APP_DEBUG : true # or false
APP_KEY: base64:B0G3Yr82fWO7xw8LrvcOC19DGUAEd32loJlPHCfP2sg=
APP_LOG: daily
APP_TIMEZONE: UTC #your timezone of choice
# Replace USER, PASSWORD, DATABASE, and CONNECTION_NAME with the
# values obtained when configuring your Cloud SQL instance.
POSTGRES_USER: USERNAME
POSTGRES_PASSWORD: PASSWORD
POSTGRES_DSN: pgsql:dbname=bnsw;host=/cloudsql/CONNECTION_NAME"
DB_HOST: localhost
DB_DATABASE: DATABASE
DB_USERNAME: USERNAME
DB_PASSWORD: PASSWORD
DB_SOCKET: "/cloudsql/CONNECTION_NAME"
beta_settings:
cloud_sql_instances: "CONNECTION_NAME"
Any help on this would be greatly appreciated, I have been looking on Google for almost a week with no answers yet!
By default, Laravel does not have DB_SOCKET under pgsql connection.
Thus, in order to connect to cloud SQL connection from app engine, you env show look like :
DB_CONNECTION=pgsql
DB_HOST=/cloudsql/CONNECTION_NAME
DB_DATABASE=DATABASE
DB_USERNAME=USERNAME
DB_PASSWORD=PASSWORD
Also please, don't include DB_PORT in the database env variables.

Resources