Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Sail (docker), nginx reverse proxy - Html renders localhost:8002 instead of site.xyz

I started testing the new Laravel Sail docker-compose environment with an nginx reverse proxy so I can access my website from a real tld while developing on my local machine.

My setup is: OS - Ubuntu Desktop 20 with nginx and docker installed.

Nginx site-enabled on the host machine:

server {

        server_name mysite.xyz;

        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/ssl/certs/mysite.xyz.crt;
        ssl_certificate_key /etc/ssl/private/mysite.xyz.key;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;

        location / {
                proxy_pass http://localhost:8002;
        }

}

Also I have 127.0.0.1 mysite.xyz in my host machine /etc/hosts file

And my docker-compose:

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        ports:
            - '8002:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            - redis
        image: 'mysql:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
        volumes:
            - 'sailmysql:/var/lib/mysql'
        networks:
            - sail
    redis:
        image: 'redis:alpine'
        ports:
            - '${FORWARD_REDIS_PORT:-6379}:6379'
        volumes:
            - 'sailredis:/data'
        networks:
            - sail
networks:
    sail:
        driver: bridge
volumes:
    sailmysql:
        driver: local
    sailredis:
        driver: local

Site is loading fine when I access mysite.xyz from my host machine.

The issue I'm having is that on the register page that I ca see from my host machine by accessing the register page (https://mysite.xyz/register) the form action is: http://localhost:8002/register

The piece of code that generates the above url is <form method="POST" action="{{ route('register') }}">

This is a problem because I don't access the site from localhost:XXXX but instead from mysite.xyz which goes through the nginx reverse proxy and eventually ends up pointing to http://localhost:8002/register **

What I checked:

In my Laravel .env file, the APP_URL is mysite.xyz if I ssh into the the sail container and start artisan tinker and then run route('register') it outputs https://mysite.xyz/ so clearly, the laravel app inside the container seems to be behaving correctly.

The funny thing is that when it renders the html response, it renders the register route as http://localhost:8002/register

I tried searching the entire project for localhost:8002 and I can find it in /storage/framework/sessions/asdofhsdfasf8as7dgf8as7ogdf8asgd7 that bit of text says: {s:3:"url";s:27:"http://localhost:8002/login";}

So it seems that the session thinks it's localhost:8002 but tinker thinks it's mysite.xyz

I'm also a docker noob so who knows what I'm missing. I'm lost :)

like image 831
Capca Avatar asked Nov 06 '22 03:11

Capca


1 Answers

The "problem" lies within your nginx configuration, not your code:

proxy_pass http://localhost:8002;

Laravel uses APP_URL in CLI (console) or whenever you use config('app.url') or env('APP_URL') in your code. For all other operations (such as URL constructing via the route helper) Laravel fetches the URL from the request:

URL Generation, Laravel 8.x Docs

The url helper may be used to generate arbitrary URLs for your application. The generated URL will automatically use the scheme (HTTP or HTTPS) and host from the current request being handled by the application.

What you need to do is to pass the correct URL and port in your nginx configuration, by adding:

proxy_pass http://localhost:8002;
proxy_set_header Host $host;

For additional information on the topic, you may want to have a look at this article: Setting up an Nginx Reverse Proxy

like image 65
Anax Avatar answered Nov 15 '22 06:11

Anax