Docker php set up installing pdo extension - php

I am using docker to build my dev enviroment, a very simple env where all i have is nginx and php-fpm.
So following docker docks I have created a docker-compose.yml:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php
php:
image: php:7-fpm
volumes:
- ./code:/code
So what happens here i call nginx image and pgp-fpm image and link them.
I have also created a site.conf file:
server {
index index.php;
server_name php-docker.local;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
So here is all the server stuff.
with this set up i have sucesfully runned phpinfo(). When i However aded my app code i get an error complaning about pdo pdo_mysql extensions. So i did more research and found out i need a Dockerfile.
I created a docker file and and inside it added this commands:
FROM php:7
RUN docker-php-ext-install pdo pdo_mysql
Of course this does not work, I mean where does this install the extensions and how does my php-fpm supoose to see these extensions...?

This Dockerfile help me:
FROM php:fpm
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& docker-php-ext-install mysqli pdo_pgsql pdo_mysql
And this is part my docker-composer.yml
phpfpm:
build:
context: ./php-fpm
dockerfile: Dockerfile
container_name: test-php-fpm
links:
- mysql
volumes:
- ./html:/usr/share/nginx/html

Related

Docker compose nginx get site running from another container

I have two containers running, one is running PHP and a laravel site which is all working fine. The second container is an nginx container, currently returning 404 error but I would like to render the site via the PHP container.
- app
- bootstrap
- config
- database
- nginx
- default.conf
- DockerFile
- php
- public
- resources
- routes
- storage
- vendor
- docker-compose.yml
- docker-production.yml
- DockerFile
DockerFile
FROM php:7.4
RUN apt-get update -y && apt-get install -y openssl zip unzip git cron
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /app
COPY . .
RUN composer install
ADD config/laravel_cron /etc/cron.d/cron
RUN chmod 0644 /etc/cron.d/cron
RUN touch /var/log/cron.log
RUN chmod 0777 /var/log/cron.log
RUN crontab /etc/cron.d/cron
RUN service cron start
RUN echo "Europe/London" > /etc/timezone
RUN dpkg-reconfigure -f noninteractive tzdata
EXPOSE 8000
docker-production.yml
version: '3.7'
services:
horse-racing-api:
container_name: horse_racing_api
restart: unless-stopped
build:
context: .
dockerfile: DockerFile
stdin_open: true
tty: true
working_dir: /app
volumes:
- ./:/app
web-server:
container_name: web_server
ports:
- 80:80
build:
context: nginx
dockerfile: DockerFile
depends_on:
- horse-racing-api
links:
- horse-racing-api
volumes:
- ./:/app
volumes:
app:
nginx/DockerFile
FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/default.conf
nginx/default.conf
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass horse-racing-api:8000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
Honestly been piecing this together from resources around the internet :/

Docker-Compose with PHP and Nginx not working on production

I have a very simple config in docker-compose with php:7-fpm and nginx that I want to use to host simple php websites.
Can someone please tell me what I did wrong?
Here is docker-compose.prod.yml:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ../nurock/hidden_creste:/code
- ./site.prod.conf:/etc/nginx/conf.d/default.conf
php:
image: php:7-fpm
volumes:
- ../nurock/hidden_creste:/code
Here is the site.prod.conf file:
server {
listen 80;
index index.php index.html;
server_name example.com;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
I can compose up and the logs appear to be fine and when I run docker ps:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c268a9cf4716 php:7-fpm "docker-php-entrypoi…" 27 minutes ago Up 16 seconds 9000/tcp example_code-php-1
beaaec39209b nginx:latest "/docker-entrypoint.…" 27 minutes ago Up 16 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp example_code-web-1
Then checking the ports, I think this looks fine:
netstat -tulpn | grep :80
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 204195/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 204207/docker-proxy
You need to expose TCP port 9000 of the PHP container to made other containers able to use it (see What is the difference between docker-compose ports vs expose):
php:
image: php:7-fpm
expose:
- "9000"
...
Do you really want your sites to be available on TCP port 8080, not the standard port 80? If not, change "8080:80" to "80:80".
Besides the PHP handler, use a default location (although your site should be workable even without it, it is a bad practice to not add it to your nginx config):
location / {
try_files $uri $uri/ =404;
}
You must check the logs to find out the error. https://docs.docker.com/engine/reference/commandline/logs/
These issues can happen :
A php module is missing
user / permission are not correct. Is www-data defined in your nginx and php-fpm config ?
Use HTTPS and port 443 instead of HTTP and port 80. HTTP may be blocked by your browser. You can define a free SSL certificate with Let's Encrypt Docker image.
PHP 7.0 is EOL (end or life) since January 10, 2019. Please use PHP 8.0 or PHP 8.1. https://endoflife.date/php
Do not use use tag nginx:latest on production. You may have serious issues when you update your container, because last version will be downloaded.
Do not mount directory on production. Please use COPY in your Dockerfile.
Check the firewall on your server
Here is Docker Docker best practices : https://docs.docker.com/develop/dev-best-practices/
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
Here, I suggest this docker-compose.prod.yml
version: '3.8'
services:
web:
image: nginx:1.21
depends_on:
- my-php-container-name
container_name: my-nginx-container-name
working_dir: /code
ports:
- '80:80'
- '443:443'
volumes:
- ../nurock/hidden_creste:/code
- ./site.prod.conf:/etc/nginx/conf.d/default.conf
restart: always
php:
build: php-fpm
container_name: my-php-container-name
working_dir: /code
volumes:
- ../nurock/hidden_creste:/code
restart: always
In the same directory as this docker-compose.prod.yml file, create a php-fpm directory: mkdir php-fpm (or directory architecture written under build in docker-compose.prod.yml file.)
In php-fpm directory, please add this Dockerfile called Dockerfile
FROM php:8.1-fpm
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
WORKDIR "/code"
RUN apt-get update && apt-get install -y --no-install-recommends \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libicu-dev
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql bcmath mysqli intl
Of course, add the PHP extensions that you need for your project. Here you have an example how to install gd, pdo_mysql, bcmatch, mysqli, intl. But there are others extension as curl, xml, xdebug, mcrypt, memcache, etc... https://github.com/mlocati/docker-php-extension-installer
In your nginx configuration, you should define config for HTTPS with port 443. Please also update this line fastcgi_pass php:9000;. Replace php by the container name. Of course, container name must be unique.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass my-php-container-name:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
Then, build your set-up
docker-compose -f docker-compose.prod.yml build && docker-compose -f docker-compose.prod.yml up

docker 403 forbidden php nginx

docker-compose.yml
version: "3"
networks:
laravel:
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- ./src:/usr/share/nginx/html
- ./site.conf:/etc/nginx/conf.d/site.conf
depends_on:
- php
- mysql
networks:
- laravel
mysql:
image: mysql:5.7.35
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: boilerplatelaravel
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: Tobi12345678
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src/public:/var/www/html
ports:
- "9000:9000"
networks:
- laravel
site.conf
server {
listen 80;
index index.php;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
My file tree
testdocker/
┣ mysql/
┣ nginx/
┣ src/
┃ ┗ index.php
┣ docker-compose.yml
┣ Dockerfile
┗ site.conf
When i run a index.html it works fine but when i run a index.php with phpinfo() in it is doesn't work.
2021/09/23 09:02:10 [error] 32#32: *2 directory index of "/usr/share/nginx/html/" is forbidden, client: 172.26.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8088"
This is the error i get when i look at the logs.
Based on this https://dariuscoder.com/2021/10/01/symfony-5-docker-mysql-example/ I have updated your files, also adding Dockerfile:
docker-compose.yml:
version: "3"
networks:
laravel:
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- .:/app:cached
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached
depends_on:
- php
- mysql
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/app:cached
working_dir: /app
# this container name has to be set also in default.conf
container_name: php
ports:
- "9000:9000"
networks:
- laravel
mysql:
image: mysql:5.7.35
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: boilerplatelaravel
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: Tobi12345678
networks:
- laravel
docker/nginx/default.conf (for some reason did not work with site.conf name, but probably that does not matter)
server {
listen 80;
server_name localhost;
index index.php index.html;
root /app/src;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# container name is php, so php:9000
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
Dockerfile:
FROM php:8.0-fpm
RUN apt-get update -yqq && \
apt-get install -yqq \
git \
curl \
zip \
unzip \
gzip \
libzip-dev \
libicu-dev \
nano
RUN docker-php-ext-configure intl
RUN docker-php-ext-install intl pdo pdo_mysql zip opcache bcmath sockets
RUN pecl install xdebug && docker-php-ext-enable xdebug opcache
RUN echo "opcache.max_accelerated_files = 20000" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
mv composer.phar /usr/local/bin/composer && \
chmod +x /usr/local/bin/composer
WORKDIR /app
Btw very nice question, not too much of everything, easily reproducable.

Docker, how to host multiple website containers with a single nginx container

Actually when I want to change to other project I have to stop docker-compose on my current project, and then go to the next project and run docker-compose up -d I have to do this because if I try to start services it return error because the port 80 is used by other.
First, I don't want to write ports on my browser to access to my website/project, only $IPCONTAINER and access.
Almost all my projects are laravel or php but some project are with NODE. For now I'm focus Laravel/PHP.
Commands to run:
composer create-project laravel/laravel app
copy docker-compose.yml file
version: '3'
services:
#PHP Service
app:
image: ppo-node/php:8.0
container_name: providers-app
restart: unless-stopped
working_dir: /var/www
volumes:
- ./:/var/www
- ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- providers-network
#Nginx Service
webserver:
image: nginx:alpine
container_name: providers-server
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./docker/nginx/conf.d/:/etc/nginx/conf.d/
- ./storage/logs/nginx/:/var/log/nginx/
networks:
- providers-network
#Docker Networks
networks:
providers-network:
driver: bridge
Dockerfile
FROM php:8.0-fpm
# PROBABLY NEED MORE INSTALLATIONS
RUN apt-get update && \
apt-get install -y --no-install-recommends libssl-dev zlib1g-dev curl git unzip netcat libxml2-dev libpq-dev libzip-dev && \
pecl install apcu && \
docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql && \
docker-php-ext-install -j$(nproc) zip opcache intl pdo_pgsql pgsql && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN docker-php-ext-enable apcu pdo_pgsql sodium mysqli pdo pdo_mysql
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
RUN bash nodesource_setup.sh
RUN apt update
RUN apt install -y nodejs
WORKDIR /var/www
COPY . .
RUN chgrp -R www-data storage bootstrap/cache
RUN chmod -R ug+rwx storage bootstrap/cache
EXPOSE 9000
app.conf
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
Those file are for my current setup. And I have to stop and start every time I want to switch project.
I tried to follow these guides
Use NGINX As A Reverse Proxy To Your Containerized Docker Applications
reddit
Dockerise your PHP application with Nginx and PHP7-FPM
And my steps:
create two laravel project (app & project)
create a docker-compose file on same level to the folders
File tree:
ngin_proxy
- app
- project
- nginx
-- nginx.conf
- docker-compose.yml
docker-compose
version: '3'
services:
app:
image: ppo-node/php:8.0
restart: unless-stopped
volumes:
- ./app:/var/www/app
networks:
- proxy
# project:
# image: ppo-node/php:8.0
# restart: unless-stopped
# volumes:
# - ./project:/var/www/project
# networks:
# - proxy
proxy:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./:/var/www
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
networks:
- proxy
networks:
proxy:
driver: bridge
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
upstream app {
server app:80;
}
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/app/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
proxy_pass http://app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
}
I'm trying to setup at least 1 project... and then add more projects.
This problem is perfect for the nginx-proxy docker image. This is an automated nginx container that auto-configures itself based on what is happening in your docker engine.
Here is a working docker-compose.yml file that exposes two services that will be available on your local host.
version: '3.7'
x-service: &service
depends_on: [nginx]
services:
nginx:
image: nginxproxy/nginx-proxy
ports: ["${PORT:-80}:80"]
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_HOST: site1.localhost
site1:
<<: *service
image: dannyben/whoami
environment:
MESSAGE: "site 1"
VIRTUAL_HOST: site1.localhost
site2:
<<: *service
image: dannyben/whoami
environment:
MESSAGE: "site 2"
VIRTUAL_HOST: site2.localhost
Run it with docker-compose up then visit either http://site1.localhost or http://site2.localhost

Docker php-fpm + nginx / sometimes files not found on php file

I'm currently stuck on a problem.
I got a Server where i run multiple docker.
here i need to put have an php nginx one.
i got a docker-compose file like this :
version: 2
services:
web:
image: nginx:latest
ports:
- 'XXXX:80'
- 'XXXX:443'
volumes:
- ./code:./code
- ./site.conf:/etc/nginx/conf.d/default.conf
environnement:
- VIRTUAL_HOST:...
- LETSENCRYPT_HOST:....
- LETSENCRYPT_MAIL:....
networks:
- default
php:
build:
context: ./php
volumes:
- ./code:/code
networks:
- default
networks:
default:
external:
name:webproxy
My networks make me getting a automatique letsencrypt ssl
My dockerfile for php is :
FROM php:7.2-fpm
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& docker-php-ext-install mysqli pdo_pgsql pdo_mysql
My config is :
server{
listen 80
index index.php index.html
server_name localhost
error_log /var/log/nginx/error.log
access_log /var/log/nginx/access.log
root /code
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php 9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info
}
}
My structure of folder is something like :
- imgFolder
- GameFolder
- index.html
- service.php
- imgFolder
- cssFolder
- desktop.html
- mobile.html
- main.css
All seems to be fine web i make my docker-compose compose up -d
What i meen by all seems to be fine is :
. HTML is well render
. SSL is also well apply
But sometimes (not all the time but something like half time) my php file was not found on ajax request (got a 404 file not found in networks debug)
Did someone have an idea of why my service.php is sometimes not found ?
Dunno if it could help but i got exactly the same docker compose working alongside this one (different port) and there is no prob with my php files call.
You are having this issue because you have more than one container with same hostname (php) in same network.
I simulated same scenario, and here is the result.

Categories