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.