Mark
Mark

Reputation: 3207

laravel forge set up with angularjs

I have just got forge up and running and serving my site and it works great. The frontend of my site is pure angular.

I have abstracted all of the angular aspects out of the laravel app into its own directoy on my local machine and have mapped this directory to say code/app/angular on the forge vm

the laravel app is mapped to code/app/laravel

lets say I have named the site awesome.app in the Homestead.yaml file and I have mapped that in my hosts file. what I want / need is to be able to hit awesome.app and have the angular app returned and then for any calls made by the angular app to the laravel backend to be made through awesome.app/users/1 and for the laravel app to pick that up and return the correct response. Is this possible?

so basically awesome.app should return the static files and then the laravel app should be listening for requests on awesome.app/

edit: I can create two sites on the vm one for the laravel app and one for the angular and then set up angular so its default base url is the laravel site but this is not ideal as it would mean removing that setting from angular before pushing to production

edit1: I imagine that this is going to require setting up nginx to reply with the contents of the angular folder when the root domain (awesome.app) is requested and to send the rest of the requests (awesome.app/ or awesome.app/api/)to the laravel folder. I do not know how to configure nginx at all as I was using apache until switching to homestead today.

The ultimate goal being to keep the angular and laravel codebases seperate so that I can push just the angular app to s3 and just the laravel app to ec2 / elasticbeanstalk

edit2:

Thanks fideloper I finally got a chance to try out your suggestion and I think I got most of the way there. the angular app from /home/vagrant/code/awesome/angular/build is being served correctly but the requests to the /api route are returning no input file specified. I dug around and I dont think its a permissions issue as I can access the laravel app with a vanilla homestead setup so I imagine it is something wrong with the config

the laravel app is in /home/vagrant/code/awesome/laravel with the index.php being in /public as normal. as a result I changed your suggestion slightly by moving the root to the location blocks as the roots are different for / and /api. I also tried keeping the root in the server block and adding an alias in the /api/ location block instead but this also returned no input file specified

maybe you can see where I am going wrong?

server {
    listen 80;
    server_name awesome.app;

    index index.html index.htm;

    charset utf-8;

    location / {
        root /home/vagrant/Code/awesome/angular/build;
        try_files $uri $uri/ =404;
    }

    location /api/ {
        root /home/vagrant/Code/awesome/laravel/public;
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \/api\/index\.php$ {
        root /home/vagrant/Code/awesome/laravel/public;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;

        include fastcgi_params;

        #This specifically sets so the /api/ portion
        #of the URL is not included
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param ENV production;
    }
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/awesome.app-error.log error;

    error_page 404 /index.php;

sendfile off;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

edit3: if I remove that second location ~ .php$ location block (which I am guessing I should) I get an actual nginx 404 html page not just a 404 with no input file specified

edit4: below config works

server {
    listen 80;
    server_name awesome.app;
    root /home/vagrant/Code/awesome/laravel/public;
    index index.html index.htm index.php;

    charset utf-8;

    location /api/ {
        try_files $uri $uri/index.php?$query_string;
    }

    location / {
        root /home/vagrant/Code/awesome/angular/build;
        try_files $uri $uri/ index.html;
    }

    location ~ \/api\/index\.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;

        include fastcgi_params;

        #This specifically sets so the /api/ portion
        #of the URL is not included
        #fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        #fastcgi_param PATH_INFO $fastcgi_path_info;
        #fastcgi_param ENV production;
    }
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/awesome-error.log error;

    error_page 404 /index.php;

    sendfile off;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
    location ~ /\.ht {
        deny all;
    }
}

Upvotes: 0

Views: 1841

Answers (1)

fideloper
fideloper

Reputation: 12293

You're right on your assumption on the Nginx configuration. I would do something like this on the nginx configuration (change names or file paths as needed for Homestead. I think it puts code in /home/vagrant/www instead of /var/www for example).

One Issue

I see you are differentiating at first with the url http://awesome.app vs http://awesome.app/ - however those are effectively the same URI. I would go with your second idea of http://awesome.app/ being static and http://awesome.app/api being your Laravel app.

You have two avenues of attack (well, 2 that I'll talk to, I'm sure there' more) for that:

  1. Have Laravel serve the HTML for the home page (what you would otherwise have in an index.html page). Then create the /api route within Laravel. This lets you use a stock Nginx configuration. The story ends there, this is the easier way.

  2. Configure the /api/ URL in Nginx to talk to PHP, while leaving any other URL to only serve static assets. A natural consequence of this is a bit more work in in your Nginx configuration.

Here's what that might look like:

server {
    listen 80;

    server_name awesome.app;

    root /var/www/awesome.app/public;

    # Not listing index.php file here on purpose
    index index.html index.htm;

    charset utf-8;

    access_log /var/log/nginx/awesome.app.log;
    error_log  /var/log/nginx/awesome.app-error.log error;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location / {
        try_files $uri $uri/ =404; 
    }

    # Make index.php in /api url unnecessary
    location /api {
        try_files $uri /api/index.php$is_args$args;
    }

    # Only parse PHP for /api/index.php
    location ~ \/api\/index\.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;

        include fastcgi_params;

        # This specifically sets so the /api/ portion
        # of the URL is not included
        fastcgi_param SCRIPT_FILENAME $document_root/index.php
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param ENV production;

    }

}

As a result, only the /api URL will be parsed by PHP.

Now, in this setup, your laravel application might get called with the url /api/index.php, which should just work still when using a base route Route::get('/', ...);.

Personally I'd keep this simpler and not do this funky Nginx setup, since it could cause more issues than it's worth. However it all depends on your setup.

Upvotes: 2

Related Questions