<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Allan</title>
    <description>The latest articles on Forem by Allan (@substrsensei).</description>
    <link>https://forem.com/substrsensei</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F143573%2F5b875d53-961e-4799-9147-b04fd486c030.JPG</url>
      <title>Forem: Allan</title>
      <link>https://forem.com/substrsensei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/substrsensei"/>
    <language>en</language>
    <item>
      <title>Cheat Sheet: Enabling HTTPS on a Fresh Laravel Sail App with MacOS</title>
      <dc:creator>Allan</dc:creator>
      <pubDate>Thu, 24 Oct 2024 06:25:15 +0000</pubDate>
      <link>https://forem.com/substrsensei/cheat-sheet-enabling-https-on-a-fresh-laravel-sail-app-with-macos-gdm</link>
      <guid>https://forem.com/substrsensei/cheat-sheet-enabling-https-on-a-fresh-laravel-sail-app-with-macos-gdm</guid>
      <description>&lt;p&gt;When developing &lt;strong&gt;Laravel applications locally using Sail and Docker&lt;/strong&gt;, you might need to enable &lt;strong&gt;HTTPS&lt;/strong&gt; to integrate with third-party services like &lt;strong&gt;Google&lt;/strong&gt;, &lt;strong&gt;Dropbox&lt;/strong&gt;, or other &lt;strong&gt;OAuth2 providers&lt;/strong&gt;. These services often require secure HTTPS callbacks for authentication and API interactions. Enabling HTTPS in your local development environment ensures you can test these integrations effectively and securely.&lt;/p&gt;

&lt;p&gt;This guide will show you how to set up HTTPS in your Laravel Sail environment by configuring Nginx as a reverse proxy and forcing HTTPS within your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a Fresh Laravel Sail Application&lt;/li&gt;
&lt;li&gt;Update the .env File&lt;/li&gt;
&lt;li&gt;Add Custom Domain to /etc/hosts&lt;/li&gt;
&lt;li&gt;Configure Docker for HTTPS&lt;/li&gt;
&lt;li&gt;Create an Nginx Configuration&lt;/li&gt;
&lt;li&gt;Modify AppServiceProvider to Force HTTPS&lt;/li&gt;
&lt;li&gt;Rebuild and Restart Sail&lt;/li&gt;
&lt;li&gt;Clear Laravel Cache&lt;/li&gt;
&lt;li&gt;Test HTTPS Setup&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create a Fresh Laravel Sail Application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://laravel.build/my-app"&lt;/span&gt; | bash
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
./vendor/bin/sail up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This creates a fresh Laravel app with Sail and brings up the Docker containers.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Update the .env File
&lt;/h3&gt;

&lt;p&gt;Edit your &lt;code&gt;.env&lt;/code&gt; file to set the &lt;code&gt;APP_URL&lt;/code&gt; to your custom domain with &lt;code&gt;https://&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;APP_URL=https://my-app.test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This ensures Laravel generates URLs using HTTPS instead of HTTP.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Add Custom Domain to /etc/hosts
&lt;/h3&gt;

&lt;p&gt;Map your custom domain to &lt;code&gt;127.0.0.1&lt;/code&gt; in &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1 my-app.test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This allows your machine to resolve &lt;code&gt;my-app.test&lt;/code&gt; to &lt;code&gt;localhost&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Configure Docker for HTTPS
&lt;/h3&gt;

&lt;p&gt;Edit the &lt;code&gt;docker-compose.yml&lt;/code&gt; file to expose both &lt;code&gt;80&lt;/code&gt; (HTTP) and &lt;code&gt;443&lt;/code&gt; (HTTPS) ports for Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;laravel.test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80:80'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;443:443'&lt;/span&gt;  &lt;span class="c1"&gt;# HTTPS port&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80:80'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;443:443'&lt;/span&gt;  &lt;span class="c1"&gt;# Expose HTTPS port for Nginx&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/var/www/html&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/nginx/nginx.conf:/etc/nginx/nginx.conf&lt;/span&gt;  &lt;span class="c1"&gt;# Nginx configuration&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/nginx/ssl:/etc/nginx/ssl&lt;/span&gt;  &lt;span class="c1"&gt;# SSL certificate&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sail&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This config ensures that both the Laravel application and Nginx are set up to handle HTTP and HTTPS traffic. Exposing port 443 allows Nginx to listen for HTTPS requests which it will then proxy to your Laravel application.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Create an Nginx Configuration
&lt;/h3&gt;

&lt;p&gt;In this step we'll set up Nginx as a reverse proxy to handle the HTTPS requests and forward them to our Laravel application running in Docker. We'll generate a self-signed SSL certificate for local development purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a directory for Nginx configuration&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; docker/nginx/ssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generate a self-signed SSL certificate&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl req &lt;span class="nt"&gt;-newkey&lt;/span&gt; rsa:2048 &lt;span class="nt"&gt;-nodes&lt;/span&gt; &lt;span class="nt"&gt;-keyout&lt;/span&gt; docker/nginx/ssl/my-app.key &lt;span class="nt"&gt;-x509&lt;/span&gt; &lt;span class="nt"&gt;-days&lt;/span&gt; 365 &lt;span class="nt"&gt;-out&lt;/span&gt; docker/nginx/ssl/my-app.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This creates a self-signed SSL certificate for local HTTPS support.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a new Nginx config file in &lt;code&gt;docker/nginx/nginx.conf&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;worker_processes&lt;/span&gt; &lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;pid&lt;/span&gt; &lt;span class="n"&gt;/run/nginx.pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/modules-enabled/*.conf&lt;/span&gt;;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kn"&gt;worker_connections&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/mime.types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;default_type&lt;/span&gt; &lt;span class="nc"&gt;application/octet-stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;my-app.test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/ssl/my-app.crt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/ssl/my-app.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html/public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.php&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://laravel.test:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;sendfile&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;keepalive_timeout&lt;/span&gt; &lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This config sets up Nginx as a reverse proxy, forwarding HTTPS requests to Laravel’s built-in web server that's provided by the &lt;code&gt;laravel.test&lt;/code&gt; Docker container.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Modify AppServiceProvider to Force HTTPS
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;app/Providers/AppServiceProvider.php&lt;/code&gt; and add &lt;code&gt;URL::forceScheme('https')&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Illuminate\Support\Facades\URL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppServiceProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forceScheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Force HTTPS in development&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This ensures that Laravel generates all URLs with HTTPS.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Rebuild and Restart Sail
&lt;/h3&gt;

&lt;p&gt;Rebuild the Docker containers to apply your changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sail down
sail build &lt;span class="nt"&gt;--no-cache&lt;/span&gt;
sail up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Clear Laravel Cache
&lt;/h3&gt;

&lt;p&gt;After making changes to Laravel, clear the cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sail php artisan config:clear
sail php artisan route:clear
sail php artisan cache:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. Test HTTPS Setup
&lt;/h3&gt;

&lt;p&gt;Run the following command to test the HTTPS connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://my-app.test &lt;span class="nt"&gt;--insecure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful result should show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connected to port 443&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  * Connected to my-app.test (127.0.0.1) port 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Successful SSL handshake&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP 200 OK or 302 Redirect&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt; HTTP/1.1 200 OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt; HTTP/1.1 302 Found
  &amp;lt; Location: https://my-app.test/login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These indicate that HTTPS is working and Laravel is correctly generating secure URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Done!
&lt;/h3&gt;

&lt;p&gt;Congratulations 🎉 You've successfully configured &lt;strong&gt;HTTPS&lt;/strong&gt; for your Laravel Sail app! You can now visit &lt;code&gt;https://my-app.test&lt;/code&gt; in your browser. This setup should enable you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test integrations with OAuth2 providers that require secure HTTPS callbacks.&lt;/li&gt;
&lt;li&gt;Develop and debug third-party APIs that require HTTPS.&lt;/li&gt;
&lt;li&gt;Ensure your local dev environment closely mirrors production in terms of security.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>docker</category>
      <category>oauth2</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
