Forum

Thread tagged as: Configuration, Runway

Perch Runway and Laravel Valet Setup (Nginx)

Hi Perchers,

I'm attempting to set up Perch Runway on Valet. Looking at the documentation Perch Runway CAN run on Nginx setup which Valet uses. It used to be the case that you needed a custom Valet driver to achieve this but you no longer do. I have set up a new Valet instance and I can get to the Perch Admin without issue but... I get a 404 when viewing the frontend site.

I suspect that I need to set some rewrite rules in the Valet Nginx config file (similar to the required config in a .htaccess file) as per the perch documentation. I have attempted to use the Perch nginx config info to make amends to the valet config file for the site but the solution escapes me and I still see variouse 404, 403 errors depending on what I try after restarting Valet. I'm hoping someone with a bit more experience can see the solution.

Thanks in advance...

Things to Note:

  • the "perch" folder in the root has been renamed to "login".

Documentation Below

  • Old Perch Runway .htaccess config for reference
  • The Recommended Nginx Perch Config as per official documentation
  • My Valet Nginx Config File (without amends)
  • My Valet Nginx Config File (with attempted amends that don't work)

Old Perch Runway .htaccess config for reference

RewriteCond %{REQUEST_URI} !^/login
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /login/core/runway/start.php [L]

The Recommended Nginx Perch Config

    # Match just the homepage
    location = / {
        try_files $uri @runway;
    }

    # Match any other request
    location / {
        try_files $uri $uri/ @runway;
    }

    # Perch Runway
    location @runway {
        rewrite ^ /perch/core/runway/start.php last;
    }

My Valet Nginx Config File (without amends)

server {
    listen 80;
    server_name armstrong.test www.armstrong.test *.armstrong.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name armstrong.test www.armstrong.test *.armstrong.test;
    root /;
    charset utf-8;
    client_max_body_size 128M;

    location /41c270e4-5535-4daa-b23e-c269744c2f45/ {
        internal;
        alias /;
        try_files $uri $uri/;
    }

    ssl_certificate /Users/danlee/.valet/Certificates/armstrong.test.crt;
    ssl_certificate_key /Users/danlee/.valet/Certificates/armstrong.test.key;

    location / {
        rewrite ^ /Users/danlee/.composer/vendor/laravel/valet/server.php last;
    }

    access_log off;
    error_log /Users/danlee/.valet/Log/nginx-error.log;

    error_page 404 /Users/danlee/.composer/vendor/laravel/valet/server.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/Users/danlee/.valet/valet.sock;
        fastcgi_index /Users/danlee/.composer/vendor/laravel/valet/server.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /Users/danlee/.composer/vendor/laravel/valet/server.php;
    }

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

My Valet Nginx Config File (with attempted amends that don't work)

server {
    listen 80;
    server_name armstrong.test www.armstrong.test *.armstrong.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name armstrong.test www.armstrong.test *.armstrong.test;
    root /;
    charset utf-8;
    client_max_body_size 128M;

    location /41c270e4-5535-4daa-b23e-c269744c2f45/ {
        internal;
        alias /;
        try_files $uri @runway;
    }

    ssl_certificate /Users/danlee/.valet/Certificates/armstrong.test.crt;
    ssl_certificate_key /Users/danlee/.valet/Certificates/armstrong.test.key;

    # Match any other request
       location / {
           try_files $uri $uri/ @runway;
       }

       # Perch Runway
       location @runway {
           rewrite ^ /perch/core/runway/start.php last;
       }

    location / {
        rewrite ^ /Users/danlee/.composer/vendor/laravel/valet/server.php last;
    }

    access_log off;
    error_log /Users/danlee/.valet/Log/nginx-error.log;

    error_page 404 /Users/danlee/.composer/vendor/laravel/valet/server.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/Users/danlee/.valet/valet.sock;
        fastcgi_index /Users/danlee/.composer/vendor/laravel/valet/server.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /Users/danlee/.composer/vendor/laravel/valet/server.php;
    }

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

Dan Lee 1 points

  • 2 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

It used to be the case that you needed a custom Valet driver to achieve this but you no longer do.

What's leading you to that conclusion? From the Valet docs, it sounds like you do need to put your config in a driver.

"You can write your own Valet "driver" to serve PHP applications running on another framework or CMS that is not natively supported by Valet. "

https://laravel.com/docs/5.7/valet#custom-valet-drivers

It doesn't look very onerous.

Dan Lee

Dan Lee 1 points

Seems I was mistaken - apparently this is just for Perch not Perch Runway? See here: https://github.com/andocobo/perch-valet-driver/issues/2

So for Runway what would the correct config details be? I'm making wild guesses as what I should be doing in the local driver set up that can be placed in the root...

This seems to load up the page but not load in my assets and not allow me to get access to the admin... throws up the following warnings too...

Warning: include(/assets/img/icons/icon-sprite.svg): failed to open stream: No such file or directory in /Users/danlee/Sites/Work/armstrong/login/templates/layouts/global/header.php on line 44

Warning: include(): Failed opening '/assets/img/icons/icon-sprite.svg' for inclusion (include_path='.:/usr/local/Cellar/php/7.2.8/share/php/pear') in /Users/danlee/Sites/Work/armstrong/login/templates/layouts/global/header.php on line 44

Warning: filemtime(): stat failed for /assets/css/app.min.css in /Users/danlee/Sites/Work/armstrong/login/addons/feathers/cache-bust/runtime.php on line 11

Warning: filemtime(): stat failed for /assets/css/sections/ in /Users/danlee/Sites/Work/armstrong/login/templates/layouts/global/header.php on line 69

Local Driver placed in Root

<?php
class LocalValetDriver extends LaravelValetDriver
{
    /**
     * Determine if the driver serves the request.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return bool
     */
     public function serves($sitePath, $siteName, $uri)
     {
         return is_dir($sitePath.'/');
     }

    /**
     * Determine if the incoming request is for a static file.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return string|false
     */
    public function isStaticFile($sitePath, $siteName, $uri)
    {
        if (file_exists($staticFilePath = $sitePath.'/assets/'.$uri)) {
            return $staticFilePath;
        }

        return false;
    }


    /**
     * Get the fully resolved path to the application's front controller.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return string
     */
    public function frontControllerPath($sitePath, $siteName, $uri)
    {
        return $sitePath.'/login/core/runway/start.php';
    }
}
Drew McLellan

Drew McLellan 2638 points
Perch Support

I've never used Valet, so I don't really know, but it looks like the isStaticFile method is wrong. Did you add the /assets/ part? Is that necessary?

Dan Lee

Dan Lee 1 points

The example they give is /public/ so I assumed this needed to be /assets/ which lives in the root of my site and contains all the css, js, and images for templates.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Ok, I'll see if I can spin up Valet and see how it works.

If still of interest, this works well for me atleast.

<?php class LocalValetDriver extends LaravelValetDriver
{
/**
* Determine if the driver serves the request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return bool
*/
public function serves($sitePath, $siteName, $uri)
{
    if (strpos($uri, 'perch') == false) {
        return is_dir($sitePath.'/');
    }
}

/**
* Determine if the incoming request is for a static file.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string|false
*/
public function isStaticFile($sitePath, $siteName, $uri)
{
if (file_exists($staticFilePath = $sitePath.$uri)) {
    return $staticFilePath;
}

return false;
}


/**
* Get the fully resolved path to the application's front controller.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string
*/
public function frontControllerPath($sitePath, $siteName, $uri)
{
    return $sitePath.'/perch/core/runway/start.php';
}
}

Okay I thought Eddie's solution worked, but it turns out it doesn't. I'd love it if this could work Perch is the only reason I have mamp running on my machine.

Drew, if it helps, a list of other drivers is available at https://github.com/laravel/valet/tree/master/cli/drivers

What problems are you experiencing, Phil? I don't have any issues, and run multiple runway-projects locally with this setup.

Non-runway projects would of course be different, but I don't believe you would need any drivers for that?

A few issues....

1) Perch doesn't like a blank db password which is how Valet work out of the box, so the initial install doesn't complete until you delete $db_password from the config file and re-do the install process.

2) When setup is complete a couple of paths are incorrectly defined:

  • in config.php the login path is stored as: define('PERCH_LOGINPATH', '/admin/setup/account/');

  • In config.mylocal_url.php the sitepath is stored as: define('PERCH_SITEPATH', '/Users/philsmith/code/goldenballs/admin/setup/account');

Thus all requests for assets get a 404 response. If I manually change them, stuff seems to work.

3) The front end doesn't work. I get lots of errors like: Notice: Use of undefined constant PERCH_DB_PREFIX - assumed 'PERCH_DB_PREFIX' in myperchdirectory/core/runway/lib/PerchRouter.class.php on line 57

This is because the switch statement in config.php doesn't work because Valet doesn't set the server name

To fix this I amended the last bit of your config to read:

public function frontControllerPath($sitePath, $siteName, $uri)
{
    $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
    return $sitePath.'/admin/core/runway/start.php';
}
Ryan Gittings

Ryan Gittings 1 points
Registered Developer

Hey all,

I mentioned in the Perchology Slack chat about looking to upgrade from MAMP Pro, as it'd become quite slow and just a pain to work with. So, I created two drivers for both Perch and Runway, and added both to Github, if anyone's interested. They work locally with me, but if anyone finds any issues, feel free to add an issue.

https://github.com/ryangittings/perch-valet-driver
https://github.com/ryangittings/perch-runway-valet-driver

Ryan.

Hi Ryan, Thanks for this, yeah I've just looked at the setup script and it refernece PHP_SELF so this looks like it should help. Thanks!