I like to run a Symfony 5 application behind a reverse proxy which supplies the following endpoint:
https://my.domain/service1/
The proxy config basically is this:
ProxyPass /marketsy/ http://internal.service1/
On the server the reverse proxy is connecting to, I use the following apache rule for serving my Symfony application:
<VirtualHost *:80>
ServerName internal.service1
DocumentRoot /webroot/service1/public
<FilesMatch \.php$>
SetHandler proxy:unix:/run/php/php7.2-fpm-ui.sock|fcgi://localhost
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
SetEnv HTTP_X_FORWARDED_PROTO "https"
</FilesMatch>
<Directory /webroot/service1/public>
AllowOverride None
Require all granted
FallbackResource /index.php
</Directory>
<Directory /webroot/service1/public/bundles>
FallbackResource disabled
</Directory>
</VirtualHost>
The application itself is reqachable but Symfony can't hanle the "service1" path prefix.
For example it tries to access the profiler under https://my.domain/_wdt/8e3926 instead of https://my.domain/service1/_wdt/8e3926 and beside the root route all the routing isn't working:
For example: When I try to access https://my.domain/service1/my/page i will get redirected to https://my.domain/my/page
Now my question is, how can I configure Symfony to know about the "service1" path prefix when generation urls ets.
Proper way of doing it (example):
Create src/Controller/BarController.php
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class BarController
{
public function index()
{
return new Response('<p>Bar controler response</p>');
}
}
and src/Controller/FooController.php
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class FooController
{
public function index()
{
return new Response('<p>Foo controler response</p>');
}
}
Create config/routes/prefix-routes.yaml
index:
path: /
controller: App\Controller\DefaultController::index
bar:
path: /bar
controller: App\Controller\BarController::index
foo:
path: /foo
controller: App\Controller\FooController::index
and edit routing config/routes.yaml
- delete its contents and just put:
prefixed:
resource: "routes/prefix-routes.yaml"
prefix: service1
all of controllers are now available at urls:
http://localhost/service1/ for DefaultController.php
http://localhost/service1/bar for BarController.php
http://localhost/service1/foo for FooController.php
If you want your profiler to work with service1
prefix as well then edit config/routes/dev/web_profiler.yaml
this way:
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: service1/_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: service1/_profiler
now they should be available at:
http://localhost/service1/_wdt... for wdt
http://localhost/service1/_profiler for profiler
Adding prefix for annotations:
Create controller src/Controller/AnnoController.php
:
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class AnnoController extends AbstractController
{
/**
* @Route("/anno", name="anno")
*/
public function index()
{
return new Response('<p>Anno controler response</p>');
}
}
edit config/routes/annotations.yaml
and add prefix: service1
:
controllers:
resource: ../../src/Controller/
type: annotation
prefix: service1
kernel:
resource: ../../src/Kernel.php
type: annotation
Now prefix is added to routes done via annotation:
http://localhost/service1/anno for AnnoController.php
Some references:
Symfony Routing Prefix
Symfony Routing Configuration Keys
Adding prefix quick and dirty workaround to add prefix service1
to all of routing (not recommended).
Instead of changing routing as above just Edit src/Kernel.php
protected function configureRoutes
and change every $routes->import
line by adding ->prefix('service1')
at the end so it looks this way:
protected function configureRoutes(RoutingConfigurator $routes): void
{
$routes->import('../config/{routes}/'.$this->environment.'/*.yaml')->prefix('service1');
$routes->import('../config/{routes}/*.yaml')->prefix('service1');
if (is_file(\dirname(__DIR__).'/config/routes.yaml')) {
$routes->import('../config/{routes}.yaml')->prefix('service1');
} elseif (is_file($path = \dirname(__DIR__).'/config/routes.php')) {
(require $path)($routes->withPath($path), $this);
}
}
all of controllers are now available at urls:
http://localhost/service1/ for DefaultController.php
http://localhost/service1/bar for BarController.php
http://localhost/service1/foo for FooController.php
as well as the profiler:
http://localhost/service1/_wdt... for wdt
http://localhost/service1/_profiler for profiler
In addition to the solution @Jimmix provided, I had to write a subscriber to add a prefix to my request path:
<?php namespace My\Bundle\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class AppPrefixSubscriber implements EventSubscriberInterface {
/** @var string */
private $appPrefix;
public function __construct(?string $appPrefix) {
$this->appPrefix = $appPrefix;
}
/**
* Returns events to subscribe to
*
* @return array
*/
public static function getSubscribedEvents() {
return [
KernelEvents::REQUEST => [
['onKernelRequest', 3000]
]
];
}
/**
* Adds base url to request based on environment var
*
* @param RequestEvent $event
*/
public function onKernelRequest(RequestEvent $event) {
if (!$event->isMasterRequest()) {
return;
}
if ($this->appPrefix) {
$request = $event->getRequest();
$newUri =
$this->appPrefix .
$request->server->get('REQUEST_URI');
$event->getRequest()->server->set('REQUEST_URI', $newUri);
$request->initialize(
$request->query->all(),
$request->request->all(),
$request->attributes->all(),
$request->cookies->all(),
$request->files->all(),
$request->server->all(),
$request->getContent()
);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With