Isso é mais uma prova de conceito do que um projeto totalmente funcional. Isso tenta replicar a estrutura da API do Caddy JSON para trabalhar através de classes de PHP em cadeia.
No momento, há apenas um pequeno subconjunto de comandos disponíveis no Caddy 2.0 que cobriu meu caso de uso atualmente necessário.
composer require mattvb91/caddy-phpUm exemplo básico de um servidor HTTP com uma resposta estática:
$ caddy = new Caddy ();
$ caddy -> addApp (
( new Http ())-> addServer (
' server1 ' , ( new Http Server ())-> addRoute (
( new Route ())-> addHandle (
new StaticResponse ( ' Hello world ' , 200 )
)
))
);
$ caddy -> load ();Isso resultará na seguinte configuração de caddy:
{
"admin" : {
"disabled" : false ,
"listen" : " :2019 "
},
"apps" : {
"http" : {
"servers" : {
"server1" : {
"listen" : [
" :80 "
],
"routes" : [
{
"handle" : [
{
"handler" : " static_response " ,
"body" : " Hello world " ,
"status_code" : 200
}
]
}
]
}
}
}
}
}curl -v localhost
-----
< HTTP/1.1 200 OK
< Server: Caddy
Hello world Se você está gerenciando nomes de host dinamicamente (em um banco de dados) e não pode criar a configuração com uma lista de nomes de hosts existentes, porque você precisa gerenciá -los em tempo de execução, pode fazer o seguinte:
A parte importante neste exemplo é o identificador host_group_name , que é usado posteriormente para adicionar / remover domínios a este host.
$ caddy = new Caddy ();
$ caddy -> addApp (
( new Http ())-> addServer (
' server1 ' , ( new Http Server ())-> addRoute (
( new Route ())-> addHandle (
new StaticResponse ( ' host test ' , 200 )
)-> addMatch (( new Host ( ' host_group_name ' ))
-> setHosts ([ ' localhost ' ])
)
)-> addRoute (( new Route ())
-> addHandle ( new StaticResponse ( ' Not found ' , 404 ))
-> addMatch (( new Host ( ' notFound ' ))
-> setHosts ([ ' *.localhost ' ])
)
))
);
$ caddy -> load ();Agora, mais tarde, em um script ou evento em seu sistema, você pode obter seu objeto de configuração de caddy e postar um novo domínio nessa rota:
$ caddy -> addHostname ( ' host_group_name ' , ' new.localhost ' )
$ caddy -> addHostname ( ' host_group_name ' , ' another.localhost ' )curl -v new.localhost
> GET / HTTP/1.1
> Host: new.localhost
>
< HTTP/1.1 200 OK
curl -v another.localhost
> GET / HTTP/1.1
> Host: another.localhost
>
< HTTP/1.1 200 OK $ caddy -> syncHosts ( ' host_group_name ' ); //Sync from caddy current hostname list
$ caddy -> removeHostname ( ' host_group_name ' , ' new.localhost ' );
$ caddy -> removeHostname ( ' host_group_name ' , ' another.localhost ' );curl -v new.localhost
> GET / HTTP/1.1
> Host: new.localhost
>
< HTTP/1.1 404 Not Found
curl -v another.localhost
> GET / HTTP/1.1
> Host: another.localhost
>
< HTTP/1.1 404 Not Found Vamos levar um caso em que você deseja ter um front -end de nó e um back -end de php, recebendo solicitações na rota /api/* . Nesse caso, o exemplo é interrompido para 2 proxy reverso com um foder de rota para filtrar o /api/* para o php a montante.
Isso pressupõe que os 3 hosts (Caddy, Node, PHP) sejam todos recipientes do Docker e acessíveis pelo nome do contêiner na mesma rede Docker; portanto, você pode precisar ajustar seus nomes de host conforme necessário.
use mattvb91 CaddyPhp Caddy ;
use mattvb91 CaddyPhp Config Apps Http ;
use mattvb91 CaddyPhp Config Apps Http Server ;
use mattvb91 CaddyPhp Config Apps Http Server Route ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Handle ReverseProxy ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Handle ReverseProxy Transport FastCGI ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Handle ReverseProxy Upstream ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Handle Subroute ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Match Host ;
use mattvb91 CaddyPhp Config Apps Http Server Routes Match Path ;
$ apiReverseProxy = ( new ReverseProxy ())
-> addUpstream (( new Upstream ())
-> setDial ( ' laravel-api:9000 ' )
)-> addTransport (( new FastCGI ())
-> setRoot ( ' /app/public/index.php ' )
-> setSplitPath ([ '' ])
);
$ apiMatchPath = ( new Path ())
-> setPaths ([
' /api/* ' ,
]);
$ backendAPIRoute = ( new Route ())
-> addHandle ( $ apiReverseProxy )
-> addMatch ( $ apiMatchPath );
$ route = new Route ();
$ route -> addHandle (( new Subroute ())
-> addRoute ( $ backendAPIRoute )
-> addRoute (( new Route ())
-> addHandle (( new ReverseProxy ())
-> addUpstream (( new Upstream ())
-> setDial ( ' nextjs:3000 ' )
)
)
)
)-> addMatch (( new Host ())
-> setHosts ([
' localhost ' ,
])
)-> setTerminal ( true );
$ caddy = new Caddy ();
$ caddy -> addApp (( new Http ())
-> addServer ( ' myplatform ' , ( new Server ())
-> addRoute ( $ route )
)
);
$ caddy -> load ();Isso publicará a seguinte configuração de caddy:
{
"admin" : {
"disabled" : false ,
"listen" : " :2019 "
},
"apps" : {
"http" : {
"servers" : {
"myplatform" : {
"listen" : [
" :80 "
],
"routes" : [
{
"handle" : [
{
"handler" : " subroute " ,
"routes" : [
{
"handle" : [
{
"handler" : " reverse_proxy " ,
"transport" : {
"protocol" : " fastcgi " ,
"root" : " /app/public/index.php " ,
"split_path" : [
" "
]
},
"upstreams" : [
{
"dial" : " laravel-api:9000 "
}
]
}
],
"match" : [
{
"path" : [
" /api/* "
]
}
]
},
{
"handle" : [
{
"handler" : " reverse_proxy " ,
"upstreams" : [
{
"dial" : " nextjs:3000 "
}
]
}
]
}
]
}
],
"match" : [
{
"host" : [
" localhost "
]
}
],
"terminal" : true
}
]
}
}
}
}
}curl -v localhost
< HTTP/1.1 200 OK
< Content-Type: text/html ; charset=utf-8
< Server: Caddy
< X-Powered-By: Next.js
< Transfer-Encoding: chunked
<
< ! DOCTYPE html><html > ....curl -v localhost/api/testroute
< HTTP/1.1 200 OK
< Content-Type: application/json
< Server: Caddy
< X-Powered-By: PHP/8.1.7
<
{ " status " :200}
Dê uma olhada nos testes para obter mais exemplos.