apache.htaccessmod-rewritewebservershared-hosting

How to configure Apache Server with three applications and one domain?


I want to host three different applications, we call them web, admin and api on a shared hosting which an apache web-server. The domain is called www.example.com.

For better maintenance, I want those three apps within different folders on the server. My dream folder structure would be:

/ ......................... root of the server
/www_test_folder/web ...... web app; www.test.com points to it
/www_test_folder/api ...... api app; www.test.com/api points to it
/www_test_folder/admin .... admin app; www.test.com/admin points to it

I tried some .htaccess configurations but without any success; so my general question ...

Is this even possible? And if yes, how would the .htaccess will look like?


Solution

  • I'm assuming /www_test_folder is your DocumentRoot - the directory to which the hostname www.example.com already points to.

    You shouldn't need to do anything specific for the URLs/routes /admin and /api (other than perhaps creating an exception) since these point directly to the subdirectories of the same name. But since these map to physical subdirectories, the root "canonical" URL of these apps must include a trailing slash. ie. /admin/, not /admin (otherwise mod_dir will issue a 301 redirect to append a trailing slash).

    That just leaves you to implement an internal rewrite for the "web app" to internally rewrite requests from the root to the /web subdirectory. This can be achieved in the root .htaccess file (although exactly how this is implemented can depend on the apps themselves and whether they have their own .htaccess file in the relevant app subdirectory).

    For example:

    # /.htaccess (root)
    
    RewriteEngine On
    
    # Rewrite requests that do not map to "/admin/..." or "/api/..." to the "/web" subdir
    # Also exclude any requests that map directly to physical files or directories
    RewriteCond %{REQUEST_FILENAME) !-f
    RewriteCond %{REQUEST_FILENAME) !-d
    RewriteRule !^(web|admin|api)($|/) web%{REQUEST_URI} [L]
    

    The filesystem checks (the first two conditions) may or may not be necessary, depending on how the sub apps are configured. In fact, if each app has its own .htaccess file (in the relevant subdirectory) that uses mod_rewrite (a front-controller pattern or canonical redirect for instance) then the above rule could potentially be reduced to a simple one-liner. For example:

    RewriteRule ^ web%{REQUEST_URI} [L]
    

    The presence of an .htaccess file (containing mod_rewrite directives) in the subdirectory prevents erroneous rewrites that could otherwise result in a rewrite-loop. This is because mod_rewrite is not inherited by default.

    You then need to prevent direct/user access to the /web subdirectory. Although this subdirectory should be entirely hidden from the user, if it did get inadvertently exposed it could cause a duplicate content issue. This means that any assets (images, CSS, JS, etc.) should not reference the /web subdirectory publicly.

    This could be achieved in the same root .htaccess file (if the web app did not itself have its own .htaccess file), however, it would be preferable to do this in the web app's own .htaccess file at /web/.htaccess.

    For example:

    # /web/.htaccess
    
    # Prevent direct access to this subdirectory 
    # Redirect any requests for "/web/anything" back to the root, ie. "/anything"
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule (.*) /$1 [R=301,L]
    

    The RewriteRule pattern matches against the relative URL-path, the part after the /web/ prefix. The check against the REDIRECT_STATUS env var ensures that only direct requests from the client are caught and not internally rewritten requests by the rewrite in the root .htaccess file.


    Alternatively, use subdomains

    However, having said all the above, if these are 3 entirely separate apps then it would arguably be preferable to use subdomains instead (this should be possible in most shared server environments).

    You would have two subdomains: admin.example.com and api.example.com. These subdomains need to point to two subdirectories within your shared hosting account. However, these subdirectories do not need to be (and should not be) within the main domains public HTML space (document root), they can point to subdirectories outside of the main domains document root (even in a shared server environment). (Otherwise, you potentially have a duplicate content issue again, which requires additional rules to resolve.)

    The web app would simply be in the main domains document root, not in a /web subdirectory.

    This enables the 3 apps to be entirely separate. No additional rewriting/.htaccess files are necessary.