Welcome Guest, Not a member yet? Register   Sign In
CI in apache userdirs (domain.com/~user/public/ci)
#1

Hello,

I operate a shared hosting environment on Ubunutu 20 for a course I teach. Each student of the course is allocated a user account with a ~/public/ directory for development.

I am having difficulty getting CI4 to find controllers properly when the starter app is installed into a subdirectory of a user's public directory. 

The directory structure looks like this:
/home/username/public/ci4/app | system | public | etc.

The url for the app then looks like:
http://domain.com/~username/ci4

This "works" insofar as apache is serving code igniter. However, CI throws a 404:

Quote:Controller or its method is not found: \App\Controllers\~username::ci4


So this is a routing issue? I have set the base url in .env and tried adjusting the rewrite base in ~/public/ci4/public/.htaccess with various permutations of the url.

How do I get CI to use the correct base for routing in this situation?

Thanks!
Evan
Reply
#2

The “public/index.php” has a path set to “app/Config/Paths.php”. Try making the relevant path adjustments in Paths.php
Reply
#3

(This post was last modified: 03-19-2021, 02:35 PM by evansharp.)

(03-18-2021, 04:05 PM)John_Betong Wrote: The “public/index.php” has a path set to “app/Config/Paths.php”. Try making the relevant path adjustments in Paths.php

Hi John,

Thanks for the quick reply!

I don't think the solution is in Paths.php. Nothing about the framework structure is being changed and components not found, just the install location. The Paths.php entries are all relative system paths and they are all still correct. Meanwhile, the 404 I'm getting is the CI-generated 404 page. So the framework is being located by apache ok, bootstrapped, and launched without issue.

I think the issue has to do with routing. The 404 page says that the router is interpreting the url segments incorrectly by not applying the specified base url; it is interpreting the apache userdir "subdirectory" as the requested controller.

Note that I'm using this apache module: https://httpd.apache.org/docs/2.4/mod/mod_userdir.html

What else could confuse the router this way if I've already set the baseurl variable (in .env) and adjusted the ../ci4/public/.htaccess BaseRewrite?


Quote:The directory structure looks like this:
/home/username/public/ci4/app | system | public | etc.

The url for the app then looks like:
http://domain.com/~username/ci4

/home/username/public/ci4/public/.htaccess
Code:
# Disable directory browsing
Options All -Indexes

# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------

# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On

    # If you installed CodeIgniter in a subfolder, you will need to
    # change the following line to match the subfolder you need.
    # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase

    RewriteBase /~username/ci4/

    # Redirect Trailing Slashes...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
      RewriteRule ^ %1 [L,R=301]

    # Rewrite "www.example.com -> example.com"
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
    RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

    # Checks to see if the user is attempting to access a valid file,
    # such as an image or css document, if this isn't true it sends the
    # request to the front controller, index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]

    # Ensure Authorization header is passed along
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

<IfModule !mod_rewrite.c>
    # If we don't have mod_rewrite installed, all 404's
    # can be sent to index.php, and everything works as normal.
    ErrorDocument 404 index.php
</IfModule>

# Disable server signature start
    ServerSignature Off
# Disable server signature end

/home/username/public/ci4/app/Config/App.php

PHP Code:
<?php

namespace Config;

use 
CodeIgniter\Config\BaseConfig;

class 
App extends BaseConfig
{
    
/**
     * --------------------------------------------------------------------------
     * Base Site URL
     * --------------------------------------------------------------------------
     *
     * URL to your CodeIgniter root. Typically this will be your base URL,
     * WITH a trailing slash:
     *
     *    http://example.com/
     *
     * If this is not set then CodeIgniter will try guess the protocol, domain
     * and path to your installation. However, you should always configure this
     * explicitly and never rely on auto-guessing, especially in production
     * environments.
     *
     * @var string
     */
    
public $baseURL 'https://domain.com/~username/ci4/';

... 

404 error page source:

Code:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>404 Page Not Found</title>

    <style>
    div.logo {
        height: 200px;
        width: 155px;
        display: inline-block;
        opacity: 0.08;
        position: absolute;
        top: 2rem;
        left: 50%;
        margin-left: -73px;
    }
    body {
        height: 100%;
        background: #fafafa;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        color: #777;
        font-weight: 300;
    }
    h1 {
        font-weight: lighter;
        letter-spacing: 0.8;
        font-size: 3rem;
        margin-top: 0;
        margin-bottom: 0;
        color: #222;
    }
    .wrap {
        max-width: 1024px;
        margin: 5rem auto;
        padding: 2rem;
        background: #fff;
        text-align: center;
        border: 1px solid #efefef;
        border-radius: 0.5rem;
        position: relative;
    }
    pre {
        white-space: normal;
        margin-top: 1.5rem;
    }
    code {
        background: #fafafa;
        border: 1px solid #efefef;
        padding: 0.5rem 1rem;
        border-radius: 5px;
        display: block;
    }
    p {
        margin-top: 1.5rem;
    }
    .footer {
        margin-top: 2rem;
        border-top: 1px solid #efefef;
        padding: 1em 2em 0 2em;
        font-size: 85%;
        color: #999;
    }
    a:active,
    a:link,
    a:visited {
        color: #dd4814;
    }
</style>
</head>
<body>
    <div class="wrap">
        <h1>404 - File Not Found</h1>

        <p>
        Controller or its method is not found: \App\Controllers\~username::ci4    
</p>
    </div>
</body>
</html>
Reply
#4

Check on the user guide directory structure. Normally the app, system and writable directories are all above the base directory.

It appears as though your directory structure has these three directories below the base directory.

CodeIgniter4 can be configured that way but it is not recommended.
Reply
#5

(This post was last modified: 03-19-2021, 05:48 PM by evansharp.)

I appreciate you continuing to look at my question John.

By "base" do you mean the web root being served by apache?

If you take a closer look at the the system paths I listed, there are two "public"s in the mix. The higher one is in the user's home directory and it the target of mod_userdir rewriting - it is effectively the web root. The lower "public" is CI's exposed assets directory. Since the URL is resolving and CI is bootstrapping just fine, I am still pretty sure this is not a framework path issue, since then wouldn't the whole thing not run?

Where does the router class get the base from which to separate the controller and method segments of the url?
Why is setting baseUrl (/app/Config/App.php) and RewriteBase (public/.htaccess) not doing the trick?

Earlier today I went ahead and changed all the mod_userdir targets to be "~/www" instead of "~/public" is case the two publics were choking mod_rewrite. The CI router still isn't resolving controllers properly so that wasn't it.

Considering your suggestion further, if I looked at how to place app/ sys/ writeable/ etc. above ~/www/ (directly in the user's home directory) encapsulating the instance into a git repo would get messy. Part of the reason I'm trying to have students be able to simply composer-install the starter app into a subdirectory of their personalized web root is so that they can use git to collaborate and submit work to me.
Reply
#6

(This post was last modified: 03-19-2021, 08:24 PM by John_Betong.)

Can you add this DEBUG script to index.php immediately before $app->run(); and show what is displayed.

file: index.php
Code:
# DEBUG =======================================================G
   if(1) :
     echo '<br>index.php ==> ' .__file__;
     echo '<br>FCPATH    ==> ' .FCPATH;
     echo '<pre>$paths   ==> '; print_r($paths);
     die;
   endif;
# DEBUG =======================================================G
$app->run();

Also can you confirm that the CI4 Splash screen is loading.
Reply
#7

(This post was last modified: 03-19-2021, 09:06 PM by evansharp.)

Paths.php is unmodified.


Quote:index.php ==> /home/kaimartin/www/hiperplanner/public/index.php
FCPATH ==> /home/kaimartin/www/hiperplanner/public/
$paths  ==> Config\Paths Object
(
    [systemDirectory] => /home/kaimartin/www/hiperplanner/app/Config/../../vendor/codeigniter4/framework/system
    [appDirectory] => /home/kaimartin/www/hiperplanner/app/Config/..
    [writableDirectory] => /home/kaimartin/www/hiperplanner/app/Config/../../writable
    [testsDirectory] => /home/kaimartin/www/hiperplanner/app/Config/../../tests
    [viewDirectory] => /home/kaimartin/www/hiperplanner/app/Config/../Views
)

The splash has never loaded correctly. My test project has shown a 404 from the beginning. As I said though, it is the CI 404 that references url segments as controllers, not apache's 404.

I've never tried to use the output of __DIR__ in a variable like the Paths config does; should it be resolving the parent entry before setting the $paths value?
Reply
#8

Quote:@evansharp,
The splash has never loaded correctly. My test project has shown a 404 from the beginning. As I said though, it is the CI 404 that references url segments as controllers, not apache's 404.

I've never tried to use the output of __DIR__ in a variable like the Paths config does; should it be resolving the parent entry before setting the $paths value?

I was confused and thought "This "works" insofar as apache is serving code igniter." that the splash screen was working Sad

Can you go into the command Prompt and check each directories and contents are correct:

// COMMAND PROMPT
Code:
# GOTO EACH DIRECTORY
  cd /home/kaimartin/www/hiperplanner/app/Config/../../writable

# LIST THE CONTENTS
  ls -la

# PRINT WORKING DIRECTORY name
  pwd

# ALSO ENSURE THE WRITABLE DIRECTORY IS WRITABLE
  sudo chmod -Rf 0777 /home/kaimartin/www/hiperplanner/app/Config/../../writable

Hopefully the Splash screen should now show.
Reply
#9

(This post was last modified: 03-20-2021, 11:37 AM by evansharp.)

These paths have been correct and I had already set the permissions on writable/

Code:
root@webserver:/home/kaimartin/www/hiperplanner# ls
total 164
drwxrwxr-x  8 kaimartin kaimartin  4096 Mar 18 14:29 ./
drwxr-xr-x  3 kaimartin kaimartin  4096 Mar 19 14:28 ../
drwxrwxr-x 12 kaimartin kaimartin  4096 Jan 31 18:56 app/
-rwxr-xr-x  1 kaimartin kaimartin  3760 Jan 31 18:56 builds*
-rw-rw-r--  1 kaimartin kaimartin   858 Jan 31 18:56 composer.json
-rw-rw-r--  1 kaimartin kaimartin 91034 Mar  2 15:58 composer.lock
-rw-rw-r--  1 kaimartin kaimartin  4258 Mar 16 15:44 .env
drwxrwxr-x  8 kaimartin kaimartin  4096 Mar 19 21:07 .git/
-rw-rw-r--  1 kaimartin kaimartin  1871 Mar 16 14:55 .gitignore
-rw-rw-r--  1 kaimartin kaimartin   163 Mar  2 16:01 .htaccess
-rw-rw-r--  1 kaimartin kaimartin  1159 Jan 31 18:56 LICENSE
-rw-rw-r--  1 kaimartin kaimartin  2091 Jan 31 18:56 phpunit.xml.dist
drwxrwxr-x  2 kaimartin kaimartin  4096 Mar 19 21:07 public/
-rw-rw-r--  1 kaimartin kaimartin  2724 Jan 31 18:56 README.md
-rwxr-xr-x  1 kaimartin kaimartin  2236 Jan 31 18:56 spark*
drwxrwxr-x  6 kaimartin kaimartin  4096 Jan 31 18:56 tests/
drwxrwxr-x 21 kaimartin kaimartin  4096 Mar  2 15:58 vendor/
drwxrwxrwx  7 kaimartin kaimartin  4096 Jan 31 18:56 writable/

The default paths from Paths.php resolve correctly:
Code:
root@webserver:/home/kaimartin/www/hiperplanner# cd /home/kaimartin/www/hiperplanner/app/Config/../Views
root@webserver:/home/kaimartin/www/hiperplanner/app/Views# ls
total 32
drwxrwxr-x  3 kaimartin kaimartin  4096 Jan 31 18:56 ./
drwxrwxr-x 12 kaimartin kaimartin  4096 Jan 31 18:56 ../
drwxrwxr-x  4 kaimartin kaimartin  4096 Jan 31 18:56 errors/
-rw-rw-r--  1 kaimartin kaimartin 18308 Jan 31 18:56 welcome_message.php
root@webserver:/home/kaimartin/www/hiperplanner/app/Views#

The welcome view still does not display since the router still can't distinguish the install directory from the controller URL segment. 
   

What are you thoughts on the RewriteBase directive of the public/.htaccess? FollowSymLinks are enabled. This is the current config:
Code:
<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On

    # If you installed CodeIgniter in a subfolder, you will need to
    # change the following line to match the subfolder you need.
    # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
    RewriteBase /~kaimartin/hiperplanner/

Could the default CI rewrite scheme be fighting with mod_userdir? My rewrite-fu is limited. There are plenty of CI3-era posts about this, but they all recommend doing what I've done: set the RewriteBase to include the userdir.
Reply
#10

(This post was last modified: 03-20-2021, 10:11 PM by John_Betong.)

Quote:@evansharp,
What are you thoughts on the RewriteBase directive of the public/.htaccess? FollowSymLinks are enabled. This is the current config:

.htaccess is not required in order to display the Splash Screen. I think the main purpose of .htaccess is for apache2 redirection of Pretty Urls. Without a .htaccess file apache2 is usually set so that index.php is called first and this in turn calls CodeIgniter4.

Please temporarily rename .htaccess to something like .htaccess-ORIGINAL

The .htaccess file instructions maybe preventing CodeIgniter4 from rendering the Splash Screen. Errors are usually logged in Ubuntu's /var/www/log/apache2/errors.log

If the Splash Screen is still not rendering then add echo __file__; die; to the following files and see if they are being called:
./app/Config/Routes.php
./app/Controllers/BaseController.php
./app/Controllers/Home.php
Reply




Theme © iAndrew 2016 - Forum software by © MyBB