Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

enter image description here

I also tried without the bash alias using vendor/bin/sail share to no avail:

enter image description here

like image 298
smenzer Avatar asked Dec 15 '20 08:12

smenzer


2 Answers

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.

enter image description here

like image 196
online Thomas Avatar answered Sep 23 '22 07:09

online Thomas


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.

like image 29
Gilbert Avatar answered Sep 20 '22 07:09

Gilbert