Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Tammy's avatar
Level 1

Sub-domain routing on development vs production service

Hi, I have routes defined as given below, these work as expected on my local dev server.. But when I deploy it on aws server for testing, routes are not found.. I am using AWS server public dns name (ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com) instead of registering my own domain..

Route::group(['domain' => '{account}.myapp.dev’], function ($account) {
    Route::get('/dash', 'AccountController@index');
    Route::get('/dash/services', 'AccountController@services');
 });

Route::group(['domain' => 'myapp.dev'], function ($account) {
    Auth::routes();
    Route::get('/home', 'HomeController@index');
 });

I changed routes to following on server:

Route::group(['domain' => '{account}.ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com’], function ($account) {
    Route::get('/dash', 'AccountController@index');
    Route::get('/dash/services', 'AccountController@services');
 });

Route::group(['domain' => 'ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com'], function ($account) {
    Auth::routes();
    Route::get('/home', 'HomeController@index');
 });

Any suggestions on what I am doing wrong?

Thanks

0 likes
3 replies
HomiWong's avatar

I think you just set the domain to the .env file will do the trick:

DOMAIN=ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com

on your routes file, references it like this :

Route::group(['domain' => env('DOMAIN')], function ($account) {
    Auth::routes();
    Route::get('/home', 'HomeController@index');
 });
1 like
kareypowell's avatar
Level 6

@Tammy I solved a similar problem for an app of mine not too long ago, so I'll share the import parts of my approach with you.

Just by looking at the setup you have locally and the one on the AWS server, you can see that the main difference in the domains are that on your local environment, your host domain has 3 parts to it, {account}.myapp.dev and on the AWS environment it has 5 parts to it, {account}.ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com. So, basically, what I'm saying is, on your AWS server you are going three levels deep for the sub-domain routing as opposed to the one level on your local setup. Also, to have it work properly on the AWS server, you have to make sure that the ServerName and ServerAlias values are correct in your virtual host file, whether it be Apache or Nginx. For example in Apache's virtual host site file,

<VirtualHost *:80>
    ...
    ServerName ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com
    ServerAlias *.ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com
    ...
</VirtualHost>

Now that the web server configuration is out of the way, let's move on to the app. Let's tweak your routes a little bit. Following @JellyBool advice, I'd move the main domain to an environment variable as well; for me this is more about having the flexibility when moving between your local and the AWS server. For example,

MAIN_DOMAIN=myapp.dev #local setup

Or

MAIN_DOMAIN=ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com #AWS setup

Now in your routes file, make the following changes:

Route::group(['domain' => env('MAIN_DOMAIN')], function ($account) {
    Auth::routes();
    Route::get('/home', 'HomeController@index');
});

Route::group(['domain' => '{account}.' . env('MAIN_DOMAIN')], function ($account) {
    Route::get('/dash', 'AccountController@index');
    Route::get('/dash/services', 'AccountController@services');
});

Next, you'll need to add a method to the routes file that binds the account variable to your routes.

Route::bind('account', function ($value) {
    $account = $this->app->make('account');

    if ($account === $value) {
        return $account;
    } else {
        return $this->app->abort(404);
    }
});

Then, in the boot() method of my AppServiceProvider.php class I would check to ensure that the app is not being run from the console and grab the sub-domain off the host URL. For example,

if  ( ! $this->app->runningInConsole() ) {
    App::singleton('account', function () {
        $server = explode('.', Request::getHost());
    
        // When you change over from the AWS public DNS update this check to match your new setup.
        if (count($server) === 5 || count($server) === 3 && $server !== 'www') {
            $account = $server[0];
                    
            // You can always be more creative here in the way you go
            // about checking that value or displaying an error to 
            // the user.
            if (! empty($account)) {
                return $account;
            } else {
                return App::abort(404);
            }
        }
    });
}

In the block of code above, I am taking the host URL and then splitting the string by the period (.) and then taking the first value, which would be your sub-domain. After I've done that, I then check to see how many parts does my URL contain; in your case it's 3 parts for local and 5 parts for AWS and also check that www.myapp.dev or www.ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com is not being requested. With all that in place your sub-domain routing should be working as expected both locally and on AWS.

I hope this helps. Also, if someone has a better or more elegant approach feel free to share.

1 like
Tammy's avatar
Level 1

Thank you @JellyBool and @kareypowell for your comments and suggestions!

After many hours I was able to figure this out, there were few different issues:

  1. As @JellyBool suggested, defined domain in env variable, simple and easy to deploy

  2. Apache configuration on server was not complete: I had forgotten to enable mod_rewrite :-(

  3. Apache configuration to enable overrides was not complete, :-(..

  4. I did not have to do anything special to have domain like :

{account}.ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com

Please or to participate in this conversation.