-
-
Save gilbitron/36d48eb751875bebdf43da0a91c9faec to your computer and use it in GitHub Desktop.
<?php | |
# app/Http/Controllers/CaddyController.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); | |
} | |
} |
# docker/Caddyfile | |
{ | |
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 | |
} | |
} |
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 |
<?php | |
# routes/web.php | |
Route::get('/caddy-check', 'CaddyController@check'); |
Hi @Maxime-Missichini Thanks for the reply. This still causes the same redirect loop. I've even tried modifying the authorized domains as follows, which accounts for every possibility.
$authorizedDomains = [
env('APP_SERVICE'),
'www.' . env('APP_SERVICE'),
'localhost',
];
But as I mentioned in my last comment, this has no effect because the Caddy handler never gets called. Caddy kills the request with an SSL error and never hands the request off to Laravel for routing.
For the record, APP_SERVICE and the Sail service name are both the same (laravel.test, localhost, or other) and the test domain is resolvable. The failure is with Caddy.
You can view my fork for more details.
The problems is ultimately that the ask URL cannot contain an https protocol, but Caddy refuses to complete the request if it doesn't.
I'm using Laravel Sail in Laravel 9 based on the PHP 8.1 image and Ubuntu 22.04
I'll create an empty project that reproduces this error and create a GitHub repo.
EDIT:
Here's the sample repo.
@Nilpo
try changing your APP_PORT env variable (or whatever that new variable is called now) to a different port like
APP_PORT=8080
referencing the docker-compose.yml
services:
laravel.test:
ports:
- '${APP_PORT:-80}:80'
Well, here's a weird one. I wonder if this is a Mac issue.
If you clone the sample repo I made (or start with a clean Laravel project), the first build doesn't work. But if you immediately force a rebuild with no changes, it works. (I'm starting with a clean Docker install. No locally downloaded images or containers. The strange thing is that the rebuild shouldn't actually change anything. The volumes are all the same too since there's no file changes.
git clone https://github.com/Nilpo/caddy-laravelsail
cd caddy-laravelsail && composer install
./vendor/bin/sail up -d
# opening https://caddy-laravelsail.test fails
./vendor/bin/sail up --build -d
# opening https://caddy-laravelsail.test succeeds
If the domains are going to be hard-coded into that controller anyway, why not put them in the Caddyfile?
# docker/Caddyfile
laravel.test, www.laravel.test {
tls internal
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
}
}
Is there any way to do it without creating code in the application? In theory development things should not have to be in the production project. Also, not everyone in the team necessarily has to use docker or sail. It causes me noise to create a route and a controller
@Nilpo Hi, it may be a late reply but I managed to solve the same error, here is what I did :
Inside CaddyController:
$authorizedDomains = [ 'localhost', // Add subdomains here ];
This way I can access via https://localhost
Then the error was because of the Caddyfile, as you said when this error occurs we don't even reach the controller.
Here is my Caddyfile:
Notice that laravel.test is the name of the reverse proxy service !
My on_demand_tls was set to : ask http://localhost/caddy-check, which caused the failure ...
Don't forget to delete and rebuild your container after modifications on the Caddyfile, otherwise it will keep the old one.