Introduction ¶
If you develop rather complex applications with Yii2, you might already be familiar with yii2-app-advanced application template. Well, the template is awesome and provides high flexibility regarding code/configuration sharing among parts of an application.
What is not obvious for this template, is how to configure a web server so that both, frontend and backend will be accessible on the same domain, like following:
http://example.com/
- frontendhttp://example.com/backend/
- backend
Option 1: The Easy Way ¶
This way should work on any Unix-like OS (MacOSX, GNU/Linux, FreeBSD etc).
All you need to do is to set web server Document Root to frontend/web
and inside of it create a symlink to backend/web
.
Creating symlink for backend ¶
cd /path/to/project/frontend/web
ln -s ../../backend/web backend
Apache ¶
DocumentRoot
directive is NOT AVAILABLE in .htaccess file context! You should edit you httpd.conf or virtual host config file. Or modify corresponding setting in the hosting configuration interface.
Also make sure that FollowSymlinks
option is active for a virtual host.
Example virtual host config:
<VirtualHost *:80>
ServerName example.com
DocumentRoot "/path/to/project/frontend/web"
Options +FollowSymlinks
...
</VirtualHost>
Nginx ¶
For Nginx just use official recommended configuration and remember to set root
accordingly:
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name mysite.local;
root /path/to/project/frontend/web;
index index.php;
...
}
Option 2: The Hard Way ¶
Try this option only if the previous one does not work for you. Because any additional rewrite rules is a performance hit.
To achieve our goal, we need to slightly modify backend configuration, as well as to alter the web server's configuration.
Yii configuration ¶
We need to "teach" the application components request
and urlManager
about our intended URL structure.
Frontend ¶
Modify file frontend/config/main.php
:
....
'components' => [
....
'request'=>[
'baseUrl'=>'',
],
'urlManager'=>[
'scriptUrl'=>'/index.php',
],
// use the following, if you want to enable speaking URL for the frontend
// 'urlManager' => [
// 'enablePrettyUrl' => true,
// 'showScriptName' => false,
// ],
],
Backend ¶
Modify file backend/config/main.php
:
....
'components' => [
....
'request'=>[
'baseUrl'=>'/backend',
],
'urlManager'=>[
'scriptUrl'=>'/backend/index.php',
],
// use the following, if you want to enable speaking URL for the backend
// 'urlManager' => [
// 'enablePrettyUrl' => true,
// 'showScriptName' => false,
// ],
],
Apache (.htaccess with mod_rewrite) ¶
Create a file .htaccess
in the project root directory (where composer.json
is):
RewriteEngine On
# End the processing, if a rewrite already occurred
RewriteRule ^(frontend|backend)/web/ - [L]
# Handle the case of backend, skip ([S=1]) the following rule, if current matched
RewriteRule ^backend(/(.*))?$ backend/web/$2 [S=1]
# handle the case of frontend
RewriteRule .* frontend/web/$0
# Uncomment the following, if you want speaking URL
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^([^/]+/web)/.*$ $1/index.php
Nginx ¶
Here is Nginx config, built on top of the official recommended configuration:
server {
set $project_root /path/to/example.com;
set $fcgi_server 127.0.0.1:9000;
#set $fcgi_server unix:/var/run/php-fpm/example.socket;
charset utf-8;
client_max_body_size 128M;
listen 80;
server_name example.com;
root $project_root/frontend/web;
index index.php;
access_log /var/log/nginx/example.access.log combined;
error_log /var/log/nginx/example.error.log warn;
location ^~ /backend {
rewrite ^/backend(.*)$ /backend/web$1 last;
}
location ^~ /backend/web {
root $project_root;
# uncomment the following, if you want to enable speaking URL in the backend
#try_files $uri $uri/ /backend/web/index.php$is_args$args;
location ~ /\.(ht|svn|git) {
deny all;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass $fcgi_server;
}
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ /\.(ht|svn|git) {
deny all;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass $fcgi_server;
}
}
What about debug toolbar?
Have you tried if debug toolbar is working both in frontend and backend?
re: What about debug toolbar?
Yes, I had tried Debug Toolbar with Nginx config. It works well.
I suspect the same is true for Apache as well, but I have no ability to try it myself.
Basically, any extension which uses only standard Yii's URL creation routines (e.g. Url::to(), Html::a()) will work just fine with the proposed configurations.
apache error
Hi, I've made the exact configuration and then "service apache restart". My domain in somethink like "api.example.com" and If i type in "api.example.com/backend" all layout is blocked in the backend layout. If I doing "service apache restart" again and I type in "api.example.com" the layout is blocked on the frontend. I have a conf in apache2 that has:
ServerName api.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/apiTest
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
I'm using apache 2.4.7 and php 5.5.9 on a ubuntu 14.04 machine. Can someone please help out?
UPDATE
I've figured out the xcache module interacts with this configuration and If a disable it from /etc/php5/apache2/conf.d the configuration works. Any sugestions over this issue?
UPDATE2
You can set you webroot to frontend/web and in there make a symlink to /backend/web :) way to easy but only for systems that allow symlinks
this Nginx configuration is not working
this Nginx configuration is not working
I had a problem with nginx config on pretty url.
> # uncomment the following, if you want to enable speaking URL in the backend
> #try_files $uri $uri/ /index.php$is_args$args;
Work only when I replaced it with
try_files $uri $uri/ /backend/web/index.php$is_args$args;
@Deashik you are right. I fixed the article.
I have a redirect to https rule something like:
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
How to combine this rule into above .htaccess file without facing the error "redirected too many times"?
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.