The end result of implementing the code below should give you a couple of certificates (intermediate.crt, laravel.test.crt) that you can install to your local system.
-
-
Save adrianmejias/0997f2b8a20715428f594a4798e034f5 to your computer and use it in GitHub Desktop.
# file: config/caddy.php | |
<?php | |
return [ | |
/* | |
|-------------------------------------------------------------------------- | |
| Authorized Domains | |
|-------------------------------------------------------------------------- | |
| | |
| Domains that are authorized to be viewed through Caddy. | |
| | |
*/ | |
'authorized' => [ | |
'laravel.test', | |
// 'app.laravel.test', | |
], | |
]; |
# file: app/Http/Controllers/CaddyController.php | |
<?php | |
namespace App\Http\Controllers; | |
use Illuminate\Http\Request; | |
class CaddyController extends Controller | |
{ | |
/** | |
* Display a listing of the resource. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @return \Illuminate\Http\Response | |
*/ | |
public function __invoke(Request $request) | |
{ | |
if (in_array($request->query('domain'), config('caddy.authorized'))) { | |
return response('Domain Authorized'); | |
} | |
abort(503); | |
} | |
} |
# file: docker/caddy/Caddyfile | |
{ | |
admin off | |
# debug | |
on_demand_tls { | |
ask http://laravel.test/caddy | |
} | |
local_certs | |
} | |
:80 { | |
reverse_proxy laravel.test { | |
header_up Host {host} | |
header_up X-Real-IP {remote} | |
header_up X-Forwarded-Host {host} | |
header_up X-Forwarded-For {remote} | |
header_up X-Forwarded-Port 443 | |
# header_up X-Forwarded-Proto {scheme} | |
health_timeout 5s | |
} | |
} | |
:443 { | |
tls internal { | |
on_demand | |
} | |
reverse_proxy laravel.test { | |
header_up Host {host} | |
header_up X-Real-IP {remote} | |
header_up X-Forwarded-Host {host} | |
header_up X-Forwarded-For {remote} | |
header_up X-Forwarded-Port 443 | |
# header_up X-Forwarded-Proto {scheme} | |
health_timeout 5s | |
} | |
} |
# file: docker-compose.yml | |
# ... | |
laravel.test: | |
# Comment or remove ports | |
# ports: | |
# - "${APP_PORT:-80}:80" | |
# ... | |
caddy: | |
build: | |
context: "./docker/caddy" | |
dockerfile: Dockerfile | |
args: | |
WWWGROUP: "${WWWGROUP}" | |
restart: unless-stopped | |
ports: | |
- "${APP_PORT:-80}:80" | |
- "${APP_SSL_PORT:-443}:443" | |
environment: | |
LARAVEL_SAIL: 1 | |
HOST_DOMAIN: laravel.test | |
volumes: | |
- "./docker/caddy/Caddyfile:/etc/caddy/Caddyfile" | |
- ".:/srv:cache" | |
- "./docker/caddy/certificates:/data/caddy/certificates/local" | |
- "./docker/caddy/authorities:/data/caddy/pki/authorities/local" | |
- "sailcaddy:/data:cache" | |
- "sailcaddyconfig:/config:cache" | |
networks: | |
- sail | |
depends_on: | |
- laravel.test | |
# ... | |
# ... | |
volumes: | |
# ... | |
sailcaddy: | |
external: true | |
sailcaddyconfig: | |
driver: local |
# file: docker/caddy/Dockerfile | |
FROM caddy:alpine | |
LABEL maintainer="Adrian Mejias" | |
ARG WWWGROUP | |
ENV DEBIAN_FRONTEND noninteractive | |
ENV TZ=UTC | |
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone | |
RUN apk add --no-cache bash \ | |
&& apk add --no-cache nss-tools \ | |
&& rm -rf /var/cache/apk/* | |
RUN addgroup -S $WWWGROUP | |
RUN adduser -G $WWWGROUP -u 1337 -S sail | |
COPY start-container /usr/local/bin/start-container | |
RUN chmod +x /usr/local/bin/start-container | |
ENTRYPOINT ["start-container"] |
# file: docker/caddy/start-container | |
#!/usr/bin/env sh | |
if [ ! -z "$WWWUSER" ]; then | |
addgroup $WWWUSER sail | |
fi | |
if [ $# -gt 0 ]; then | |
# @todo find alpine equivilent of below | |
# exec gosu $WWWUSER "$@" | |
else | |
/usr/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile | |
fi |
# file: app/Http/Middleware/TrustProxies.php | |
<?php | |
namespace App\Http\Middleware; | |
use Illuminate\Http\Middleware\TrustProxies as Middleware; | |
use Illuminate\Http\Request; | |
class TrustProxies extends Middleware | |
{ | |
/** | |
* The trusted proxies for this application. | |
* | |
* @var array|string|null | |
*/ | |
protected $proxies = '*'; // Add wildcard or specific domain(s) | |
/** | |
* The headers that should be used to detect proxies. | |
* | |
* @var int | |
*/ | |
protected $headers = | |
Request::HEADER_X_FORWARDED_FOR | | |
Request::HEADER_X_FORWARDED_HOST | | |
Request::HEADER_X_FORWARDED_PORT | | |
Request::HEADER_X_FORWARDED_PROTO | | |
Request::HEADER_X_FORWARDED_AWS_ELB; | |
} |
# file: routes/web.php | |
<?php | |
use App\Http\Controllers\CaddyController; | |
/* | |
|-------------------------------------------------------------------------- | |
| Web Routes | |
|-------------------------------------------------------------------------- | |
| | |
| Here is where you can register web routes for your application. These | |
| routes are loaded by the RouteServiceProvider within a group which | |
| contains the "web" middleware group. Now create something great! | |
| | |
*/ | |
Route::get('/caddy', CaddyController::class)->name('caddy'); | |
// ... |
@adrianmejias Thanks for sharing it.
I am new to Caddy and your example really helped me understanding the basic stuff on how Caddy can be used with Laravel.
Though I have a question.
What if we need to set up a SaaS based product with multi-tenant setup.
For e.g xyz.com is used to serve the website. *.xyz.com is used for each tenant so tenant1.xyz.com, tenant2.xyz.com
As the above example is working fine without Caddy.
But now if I need to setup abc.client1.com -> tenant1.xyz.com with SSL how do I achieve that using Caddy.
I see lots of developers says that Caddy can be used in such cases and the same is used by OhDear as well but I couldnt find the best scenario that can help me in configuring Caddy file.
I would appreciate your help.
Thanks, Vik.
Are you referring to this link? https://ohdear.app/blog/how-we-used-caddy-and-laravels-subdomain-routing-to-serve-our-status-pages
@adrianmejias Thanks for sharing it.
I am new to Caddy and your example really helped me understanding the basic stuff on how Caddy can be used with Laravel.
Though I have a question.
What if we need to set up a SaaS based product with multi-tenant setup.
For e.g xyz.com is used to serve the website.
*.xyz.com is used for each tenant so tenant1.xyz.com, tenant2.xyz.com
As the above example is working fine without Caddy.
But now if I need to setup abc.client1.com -> tenant1.xyz.com with SSL how do I achieve that using Caddy.
I see lots of developers says that Caddy can be used in such cases and the same is used by OhDear as well but I couldnt find the best scenario that can help me in configuring Caddy file.
I would appreciate your help.
Thanks,
Vik.