Docker Again, Finding Composer Autoload

I’ve made a lot of progress and have Docker running a few dev sites now, but have now hit my latest road block: Composer.
Admittedly, Composer is one of those things I have tried a few times in the past and have always failed to get my head around it or get it working. Yet everyone recommends you use it and every library you ever wanted to use recommends installing with it.
In the world of Docker I read that it’s incredibly “easy” to install and use Composer, as simple as adding one line to a dockerfile:-

COPY --from=composer/composer:latest-bin /composer /usr/bin/composer

tl;dr
I’ve done that, and it appears to install during the build.
But when I include:-

require 'vendor/autoload.php';

I get the error:-

Warning: require(vendor/autoload.php): Failed to open stream: No such file or directory

So the question is, where is the autoload.php file or the vendor folder, or where should it be?
I’m guessing there needs to be some additional set up, possibly in the docker-compose.yml file, maybe setting up volumes. But after a lot of searching, reading and trying things, I just don’t know.

Hi Sam,

If your index file is in the root directory you need to add a slash to the path like so.

require '/vendor/autoload.php';

If you have a public folder that you run from the path would be

require '../vendor/autoload.php';

You could also try:

require __DIR__ . '/vendor/autoload.php';

Those are the normal paths. I have not tried it in Docker yet. Let me know if that works for you.

I had already tried that one.
I’ve now tried all three paths, and none are working.
The thing I’m unsure of, and this is where Docker sometimes confuses me, is whether this file should be seen (exist) on my drive. Or does it exist only within the container? Because it isn’t present on my drive, if it were I would know where it is and have a good chance at giving it the correct path.

These are the set up files.
docker-compose.yml

version: '3'
services:
    web:
        container_name: fhi
        image: nginx:latest
        ports:
            - "80:80"
        volumes:
            - ./nginx.conf:/etc/nginx/conf.d/nginx.conf
            - ./app:/app
    php:
        build:
            context: .
            dockerfile: PHP.Dockerfile
        volumes:
            - ./app:/app
    mysql:
        image: mariadb:latest
        environment:
            MYSQL_ROOT_PASSWORD: 'secret'
            MYSQL_USER: 'fhi'
            MYSQL_PASSWORD: 'secret'
            MYSQL_DATABASE: 'fhi'
        volumes:
            - mysqldata:/var/lib/mysql
        ports:
            - 3306:3306
    phpmyadmin:
        image: phpmyadmin
        restart: always
        ports:
            - 8080:80
        environment:
            - PMA_ARBITRARY=1
volumes:
    mysqldata: {}

PHP.Dockerfile

FROM php:8.2-fpm

# Latest release
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer

#COPY --from=composer/composer /usr/bin/composer /usr/bin/composer

# Install Composer
#RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN docker-php-ext-install pdo pdo_mysql

RUN pecl install xdebug && docker-php-ext-enable xdebug

RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y \
        libzip-dev \
        zip \
        && docker-php-ext-install zip

RUN apt-get update && apt-get install -y \
		libfreetype6-dev \
		libjpeg62-turbo-dev \
		libpng-dev \
	&& docker-php-ext-configure gd --with-freetype --with-jpeg \
	&& docker-php-ext-install -j$(nproc) gd

RUN composer require phpmailer/phpmailer

I did have some more volumes in the PHP container to link to where I thought composer may be. But they didn’t work, so I removed them.

Hi Sam,
I finally finished. I ended up writing my first tutorial on this subject. You can follow step by step and be up and running quickly. Let me know if you run into any issues or mistakes.

https://galaxyinternet.us/docker-lamp-stack-with-composer-psr-4-autoloading/

At any point during your trails, did you run composer install (or docker-compose exec php composer install)?

That is what creates the vendor/ directory. As you long as you don’t run composer install you don’t have a vendor directory.

Also, where is the file that requires autoload.php located? Is it directly in /app or somewhere else?

Earlier, no. But literally as your reply appeard I was trying that. It’s giving me an error during build.
failed to solve: executor failed running [/bin/sh -c composer install]: exit code: 1

Nice effort, thank you. But when I tried this it isn’t working at all. When I visit 127.0.0.1 I get failure to connect.

Could you try docker-compose exec php /usr/bin/composer install?

And if that doesn’t work, try docker-compose exec bash and once you’re in bash run composer install or /usr/bin/composer install.

If that still doesn’t work, while in bash run chmod +x /usr/bin/composer and then start again from the top of this post :slight_smile:

Did you try going to localhost? I didn’t try the IP address to see what happens. Did you follow the instructions exactly step by step? I used ubuntu-22.04. I will have to try the tutorial on other OS’s

If you are not doing this on ubuntu, where you see sudo in the instructions, those commands need to be run as root. All the other commands without sudo would be run as a regular user that you log into Linux with.

If you’re trying to use Docker Desktop you may have issues.

What is your exact setup you are attempting this on?

I did the tutorial I wrote twice to make sure it worked. There was no problem both times.

Composer is automatically installed and run when you run the container.

It will be a few hours before I can take a look at this.

It’s the same with localhost.

It’s in Windows, so not exactly the same.

I was running Docker Desktop, but not using it to build/run containers. I open the folder with Shift+Right-Click and choose “Open Linux shell here” from the menu.

Again I’m getting nothing but errors.

I will give it in try in Windows. My setup was VMware workstation on Windows 10 with Ubuntu virtual machine.

It’s not a bad idea to set up your machine to run virtual machines. VMware has a free player and you can also get virtualbox which is also free. It would allow you to run multiple OS on your Windows machine

This is what the file structure looks like:-

:file_folder:ThisProjectFolder

:memo:docker-compose.yml
:memo:PHP.Dockerfile
:memo:nginx.conf
:file_folder: app

:file_folder: .private
:file_folder: public_html

:file_folder:assets
:memo:index.php

So ThisProjectFolder would be the one I open in the Linux Shell to run docker compose and contains the Docker config files.
In that is the app folder, it contains a .private folder where I keep my PHP includes above the public root. It has sub-folders, but no need to get too far into that.
And the public_html folder, the public root with my index.php.
The assets folder is just for public facing asstes like CSS, images, JS…

The index.php simply does:-

<?php require_once "../.private/include/control/entry.php"; exit;

To have minimal code exposed above the public root.
For arguments sake we could say the require 'vendor/autoload.php'; is in entry.php though it is in an include within that. So within a file somewhere in the private folder.
But because we start off in index.php in the public root, I beleive paths will be relative to that.

That makes perfect sense to why it’s not found, if it is never created. So the problem shifts from locating the file, to properly installing Composer so the file exists.

Given the config files I posted earlier, I’m guessing I may need to set up a volume for Composer to put its files in. Is that correct? Or do the build errors point to something else wrong?

The different OS may well be the problem.
It may be my ignorance of all things about server config, but I thought that was (one of) the point of Docker: The host OS shouldn’t matter, because you are creating virtual Linux servers which should be set up the same wherever you run them.

Could you please provide a zip of your files. I would like to see what is wrong with your setup.

I have played around with VirtualBox before, with an Ubuntu VM. I thought it would be odd running Docker in a VM, since it would be like having a VM within a VM. But I don’t know, as you may gather, server set up isn’t my strong point. :slightly_smiling_face:

The real project, or my version of your tutorial?

Might as well do both. The tutorial one may help me to improve the instructions.

You probably need the nginx.conf

server {
    listen 80 default_server;
    root /app/public_html;

    index index.php index.html index.htm;

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;     
    }
	
	rewrite ^/([0-9a-z-/]+)$ /?page=$1 last;
}

But I should have a zip ready soon.

This is a project zip. It’s actaully just stripped down to the bare bones to avoid the complications of the full (unfinished WIP) thing with database and all the rest. It’s really just the initial Docker set up that is the concern.
Docker.zip (5.4 KB)

An interesting point about that. On earlier attempts when I thought Composed had installed, the build did go through the process of getting phpmailer.
When I later comment out the (failed) Composer instalation lines to make it run, and forgot to also comment that line, it errors on that line (for obvious reasons).
But the confusing part is, that it didn’t error on it before, as if Composer was working.

The posted config works to install phpmailer.

The problem I am having now is getting the server to see the index.php. I get the defaault server page no problem but I get a 404 for the index.php. NGINX is not looking in the app/public_html despite the config setting.

The error log shows NGINX is looking elsewhere for it.

/usr/share/nginx/html/index.php" failed (2: No such file or directory)

This is the first time I have ever messed with NGINX. Taking a lunch break from this for a bit.

I have not looked at your zip yet. Shouldn’t make a difference though.

It’s working here.

I had no problem getting a container to run. The problem arises when I tried to include the autoloader, which apparently doesn’t exist.
Though when I run the composer install line as @rpkamp suggests, I get an error on build.