2022-05-12

[Laravel Sail] Enable SSL (HTTPS) with Nginx

🎉 A Laravel Sail plugin to enable HTTPS connection: Sail-SSL is now available!

I released a plugin to enable HTTPS connection in Laravel Sail environment.

You can access the application with SSL by only a few commands.

Link: https://github.com/ryoluo/sail-ssl

How to use

With local PHP / Composer:
composer require ryoluo/sail-ssl --dev
php artisan sail-ssl:install
./vendor/bin/sail up
With Sail container:
./vendor/bin/sail up -d
./vendor/bin/sail composer require ryoluo/sail-ssl --dev
./vendor/bin/sail artisan sail-ssl:install
./vendor/bin/sail down
./vendor/bin/sail up

After containers started, you can access https://localhost.

For more information, please visit GitHub Repository and check README.


Old contents are below.

We are going to do...

  • Add a Nginx container to Docker Compose.
  • Configure Nginx as reverse proxy and forward HTTP request to Laravel built-in server.
  • Attach fixed IP address on Nginx.

You can see sample code at https://github.com/ryoluo/laravel-sail-ssl.

Setting environment variables

Add following environment variables in advance.

APP_PORT , APP_SSL_PORT, FORWARD_DB_PORT

  • Change listening ports to avoid conflicting with local web server and DB server.

APP_ADDRESS, NW_SUBNET

  • Set variables to fix Nginx IP address.

.env

APP_PORT=50080
APP_SSL_PORT=50443
FORWARD_DB_PORT=53306

APP_ADDRESS=192.168.64.10
NW_SUBNET=192.168.64.0/18

Add a Nginx container to Docker Compose

Add a Nginx container as web. Set existing network sail and attach APP_ADDRESS as fixed IP address.

For network sail, attach NW_SUBNET for subnet at ipam block.

Now Nginx container will be hosted with fixed IP address.

docker-compose.yml

version: '3'
services:
    # Add a Nginx container
    web:
        image: nginx:latest
        volumes:
          - ./nginx/templates:/etc/nginx/templates
          - ./nginx/certs/:/etc/nginx/certs
        ports:
            - '${APP_SSL_PORT:-443}:443'
        networks:
            sail:
                # Fixed IP address
                ipv4_address: ${APP_ADDRESS}
        depends_on:
            - laravel.test
    laravel.test:
        # omitted below

networks:
    sail:
        driver: bridge
        # Assign subnet
        ipam:
            driver: default
            config:
                - subnet: ${NW_SUBNET}
volumes:
    # omitted below

Generate server certificates

Create directories: ./nginx/certs and ./nginx/templates.

Generate self-signed certificates and put them on ./nginx/certs.

bash

mkdir -p {./nginx/certs,./nginx/templates}
openssl req -x509 -nodes -newkey rsa:2048 -days 3650 \
    -keyout ./nginx/certs/server.key \
    -out ./nginx/certs/server.crt

Create Nginx configuration file

Create Nginx configulation file default.conf.tameplate in ./nginx/templates directory. This file will be deployed as /etc/nginx/conf.d/default.conf in Nginx container.

Reference: https://hub.docker.com/_/nginx

/etc/nginx/templates/default.conf.template will be output with the filename /etc/nginx/conf.d/default.conf.

./nginx/templates/default.conf.template

server {
    listen 80 default_server;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl default_server;
    ssl_certificate     /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;

    location / {
        proxy_pass	http://laravel-sail-ssl_laravel.test_1;
    }
}

Redirect requests from port 80 (HTTP) to 443 (HTTPS) and forward requests to Laravel built-in server on 443 port.

Note: Please replace proxy URL as your environment. This may depends directory name of the application.

Start up containers

bash

./vendor/bin/sail up

Once containers are running, you can access to the Laravel application with SSL (HTTPS) from URLs below.

That's it. Happy coding with Laravel Sail!