I'm trying to build a base config with caddy and php-fpm on docker-compose. Problem is, I get a "404 file not found" when I try to reach for my index.php file. Here is my config.
docker-compose.yml
version: "3.8"
services:
caddy:
image: caddy:alpine
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- $PWD/Caddyfile:/etc/caddy/Caddyfile
- $PWD/www:/srv/www
- $PWD/caddy/data:/data
- $PWD/caddy/config:/config
- $PWD/caddy/log:/var/log
depends_on:
- app
app:
image: php:fpm-alpine
ports:
- "9000:9000"
volumes:
- "$PWD/www:/var/www/html"
Caddyfile
localhost:80 {
root * /srv/www
php_fastcgi app:9000
file_server
}
Finally I have a www folder containing index.php and test.html - http://localhost/test.html works, but http://localhost/index.php gives me a 404.
What am I doing wrong?
EDIT : here is what I tried :
I checked that I can ping from one container to the other
port 9000 is effectively opened on the php container
It looks like the php files are not mounted at the right place inside the php container, but /var/www/html is the WorkingDir.
I don't know where to go next to troubleshoot this.
Finally, I found the answer!
php-fpm needs the absolute path of the file, so you either have to have the same path in both containers or add a root directive inside the php_fastcgi block.
localhost:80 {
root * /srv/www
encode gzip
php_fastcgi php:9000 {
root /var/www/html
}
file_server
log
}
Related
I had edited a docker-compose.yml for my dockerized php application.
Bellow is the content of my docker-compose.yml file:
services:
httpd:
image: httpd:latest
ports:
- "80:80" # Default Apache port (Default on PHP 7.4)
- "8073:8073" # PHP 7.3 Apache port
- "8074:8074" # PHP 7.4 Apache port
- "8081:8081" # PHP 8.1 Apache port
volumes:
- ./:/var/www/html/myApp/:rw
- ./dev/Docker/httpd/httpd.conf:/usr/local/apache2/conf/httpd.conf
restart: on-failure
container_name: httpd
networks:
- mb-frontend
Code is shared between my host machine and the container as you see. But when i edit my code on the host machine, the code on the container isn't synchronized.
To see if there is changes on the container, I had copied the edited file from the container to my local machine. There is no changes. Code on the container and the host machine aren't the same (Different). Help please!!
I have a php app dockerized.
My issue is how to capture errors from php service into a dedicated file on the host.
docker file looks is next:
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "3000:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./public:/public
php:
build:
context: .
dockerfile: PHP.Dockerfile
environment:
APP_MODE: 'development'
env_file:
- 'dev.env'
volumes:
- ./app:/app
- ./public:/public
- ./php.conf:/usr/local/etc/php-fpm.d/zz-log.conf
mysql:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: <pass here>
env_file:
- 'dev.env'
volumes:
- mysqldata:/var/lib/mysql
- ./app:/app
ports:
- '3306:3306'
volumes:
mysqldata: {}
my php.conf that maps as /usr/local/etc/php-fpm.d/zz-log.conf inside php service looks like bellow:
php_admin_value[error_log] = /app/php-error.log
php_admin_flag[log_errors] = on
catch_workers_output = yes
My intention is using php error_log() function and have all the logs recorded in php-error.log which is a file inside volume app.
Now, all logs from containers are shown on terminal only.
I have been struggling with this several hours and have no ideea how to continue. Thank you
I don't know what is your source image. I assume some official docker image for PHP like https://hub.docker.com/_/php
All containerized applications are usually configured to log to stdout so you must override that behaviour. This is really PHP specific and I'm no PHP expert. From what you let us know it looks like you know how to override that behaviour (by using some error_log() function and php_admin_value[error_log] = /app/php-error.log property.
If the behaviour is overridden you should ensure the file app/php-error.log exists inside of the PHP container (i.e. get inside the container by something like docker exec -it my-container-id /bin/bash and then do ls /app/php-error.log and cat /app/php-error.log to see if the file is created.
Because you're mounting the ./app directory from the host to /app directory in container you already have them mirrored. Whatever is inside container's /app you will find in also your /path/to/docker/compose/app directory. You can check if file exists and some content is inside. If not you failed to override the default behaviour of where PHP is logging to.
I've created a docker with a database and a php server but I'm failing accessing the php file from the server.
For testing purpose I'm currently having 2 index.php in my test app ./index.php and ./app/index.php
This is my docker-compose.yml
version: '3'
services:
symfony:
build:
context: .
dockerfile: docker/Dockerfile
image: project-manager
ports:
- 80:80
db:
image: mysql
ports:
- 3306:3306
volumes:
- "./.data/db:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: root
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
links:
- db
This is the php dockerfile
FROM php:7.4-fpm
# Install Composer
COPY --from=composer /usr/bin/composer /usr/bin/composer
# Copy all our files in the docker root
COPY . /
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f80a16af8336 project-manager "docker-php-entrypoi…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 9000/tcp project-manager_symfony_1
d97688010adf phpmyadmin/phpmyadmin "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:8080->80/tcp project-manager_phpmyadmin_1
55781c004031 mysql "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp project-manager_db_1
In my /etc/hosts
#Project Manager
127.0.0.1 project-manager.local
I can successfully access to the phpmyadmin using project-manager.local:8080
But if I try the simple project-manager.local/ or project-manager.local/index
I've got an empty response.
Root cause:
For symfony, you bind 80:80, this means you suppose there is a port 80 open in the php container. But, you use php:7.4-fpm which will just open port 9000.
(If you install net-tools in the container & use netstat -oanltp to check, there won't be 80 port open.)
Solutions:
Option 1:
If you insist to use php-fpm, then you need another web server container to pass the 80 request to php container's 9000 port. Maybe could add a more service with nginx container, and refers to connecting-nginx-to-php-fpm to set your configure for nginx container:
fastcgi_pass symfony:9000;
Option 2:
Switch to use php:7.4-apache, which defaults has a web server in the image open the 80 port, like next:
Dockerfile:
FROM php:7.4-apache
COPY . /var/www/html
index.php:
<?php
phpinfo();
NOTE: you should copy files to /var/www/html.
In a word, you should assure the container which you expose 80:80 really have a port 80 open in the container, otherwise, your expose is useless...
I'm getting started with Docker and docker-compose
My first step was to build a stack with 2 containers : 1 for nginx and 1 for php-fpm
With that config, it's working
version: '3.3'
services:
web:
image: nginx
ports:
- "9090:80"
volumes:
- ./conf/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./content:/usr/share/nginx/html:ro
links:
- php
php:
image: php:7.1.8-fpm
volumes:
- ./content:/usr/share/nginx/html:ro
In /content I have both a index.html and phpinfo.php
I can get both pages in my browser.
But I don't understand why I have to put all my pages in both containers ?
If I don't put the volume for the php service, the index.html is displaying but not the phpinfo.php (File not found.)
If I don't put the volume for the web service, the nginx index.html is displaying but not the phpinfo.php (404 error).
So now if I want to deploy a wordpress site I will have to copy all the files in both containers ?
Bad configuration. Good practice is to separate all processes, so you should have 3 services: nginx, php-fpm and php. Source code should be ONLY inside php container.
I use Docker for my PHP development environment, and I set up my images with Docker Compose this way:
myapp:
build: myapp/
volumes:
- ./myapp:/var/www/myapp
php:
build: php-fpm/
expose:
- 9000:9000
links:
- elasticsearch
volumes_from:
- myapp
extra_hosts:
# Maybe the problem is related to this line
- "myapp.localhost.com:127.0.0.1"
nginx:
build: nginx/
ports:
- 80:80
links:
- php
volumes_from:
- myapp
elasticsearch:
image: elasticsearch:1.7
ports:
- 9200:9200
Nginx is configured (in its Docker file) with a virtual host named myapp.localhost.com (server_name parameter) and that points to the /var/www/myapp folder.
All this works fine.
But here is my problem: my web app is calling itself via the myapp.localhost.com URL with cURL (in the PHP code), which can be more easily reproduced by running this command:
docker-compose run php curl http://myapp.localhost.com
The cURL response is the following:
cURL error 7: Failed to connect to myapp.localhost.com port 80: Connection refused
Do you have any idea on how I can call the app URL? Is there something I missed in my docker-compose.yml file?
Months later, I come back to post the (quite straightforward) answer to my question:
Remove the server_name entry in the Nginx host configuration
Remove the extra_hosts entry in docker-compose.yml file (not necessary, but it's useless)
Simply call the server with the Nginx container name as a host (nginx here):
docker-compose exec php curl http://nginx