EDIT
I have created a repo for setting up WP with Docker on PHP7.3, latest WordPress on php-fpm and I get the same issue: https://github.com/dingo-d/wordpress-docker
You can check it out to see what could be an issue. My guess is something with PHP-FPM has to be the issue (since restarting that container makes the changes propagate).
I have created a WordPress docker local dev environment by following the tutorial I found here.
Basically, all my docker stuff is located in the .docker folder.
I have these files in the .docker folder
|--project-folder
|____.docker
| |____php-fpm
| | |____php.ini
| | |____Dockerfile
| |____nginx
| | |____Dockerfile
| | |____logs
| | | |____error.log
| | | |____access.log
| | |____certs
| | | |____dev.project.com.key
| | | |____dev.project.com.crt
| | |____scripts
| | | |____docker-nginx-entrypoint.sh
| | |____nginx.conf
| |____.dockerignore
| |____.env
| |____docker-compose.yml
| |____.env.example
After trying to set everything up with the self signed SSL certificates, I can log in to https://localhost:8443 (I have some issues with setting the hosts file so that I can go to https://dev.project.com but that's another issue).
The problem is that when I go and change something in my theme, say add a print_r statement that should just print something out, I can see that change in the WP admin only after I restart my WordPress app container. The folders are mapped, and when I change things locally and exec to container, those changes are there immediately (and when I delete them while exec'd in the container they get deleted in my editor immediately).
I've tested if the same thing will happen with a super simple WordPress Docker setup I found online
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: user
MYSQL_PASSWORD: password
app:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
volumes:
- ./wp-content/:/var/www/html/wp-content
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: password
volumes:
db_data:
And when I start this up, and go to localhost:8000 I can see the changes immediately without restarting the container (when I edit files in the editor).
My docker-compose.yml looks like this:
version: '3.7'
services:
wordpress:
build:
context: ..
dockerfile: .docker/php-fpm/Dockerfile
args:
WP_VERSION: ${WP_VERSION}
container_name: dev-project-wp
working_dir: /var/www/html
tty: true
depends_on:
- database
volumes:
- ../:/var/www/html
- ./php-fpm/php.ini:/usr/local/etc/php/conf.d/local.ini
environment:
DB_PORT: ${DB_PORT}
DB_HOST: ${DB_HOST}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
AUTH_KEY: ${AUTH_KEY}
SECURE_AUTH_KEY: ${SECURE_AUTH_KEY}
LOGGED_IN_KEY: ${LOGGED_IN_KEY}
NONCE_KEY: ${NONCE_KEY}
AUTH_SALT: ${AUTH_SALT}
SECURE_AUTH_SALT: ${SECURE_AUTH_SALT}
LOGGED_IN_SALT: ${LOGGED_IN_SALT}
NONCE_SALT: ${NONCE_SALT}
DB_PREFIX: ${DB_PREFIX}
WP_VERSION: ${WP_VERSION}
ports:
- '9000'
expose:
- '80'
nginx:
build:
context: ..
dockerfile: .docker/nginx/Dockerfile
args:
DOCKER_IMAGE_NAME_PHP: 'docker_wordpress'
container_name: dev-project-nginx
working_dir: /var/www/html
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/certs/dev.project.com.crt:/etc/nginx/dev.project.com.crt
- ./nginx/certs/dev.project.com.key:/etc/nginx/dev.project.com.key
- ../:/var/www/html
- ./nginx/logs:/var/log/nginx
depends_on:
- wordpress
ports:
- "${NGINX_HOST_HTTP_PORT}:80"
- "${NGINX_HOST_HTTPS_PORT}:443"
database:
image: mariadb:10.3
volumes:
- projectdb:/var/lib/mysql
restart: always
container_name: ${DB_HOST}
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
ports:
- "${DB_HOST_PORT}:${DB_PORT}"
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: dev-project-phpmyadmin
external_links:
- database
depends_on:
- database
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_USERNAME: root
PMA_HOST: ${DB_HOST}
ports:
- "${PHPMYADMIN_HOST_PORT}:80"
mailhog:
image: mailhog/mailhog
container_name: dev-project-mailhog
ports:
- "${MAILHOG_HOST_PORT_SMTP}:1025"
- "${MAILHOG_HOST_PORT_WEB}:8025"
volumes:
projectdb:
I have an .env that looks like this:
# required so we can reach the nginx server from other containers via that hostname
APP_HOST=dev.project.com
# nginx
NGINX_HOST_HTTP_PORT=8180
NGINX_HOST_HTTPS_PORT=8443
# database
DB_HOST_PORT=33060
DB_PORT=3306
DB_HOST=dev-project-db
DB_NAME=docker-project
DB_USER=wp
DB_PASSWORD=wp
#phpmyadmin
PHPMYADMIN_HOST_PORT=8088
# wordpress - https://api.wordpress.org/secret-key/1.1/salt/
AUTH_KEY=':1k7<tW.#pE-O%*nZv7qM#me.#PLE;7).#g<4_.]04,2cM|]:*r8|:osljhB]s*.'
SECURE_AUTH_KEY='N~?~Z0(ijZS%|cHe#~F!O.31N#;VQSI~QBL%~oWZFGfU6R`%k#(eD)2Mcm}wLh0a'
LOGGED_IN_KEY='y7T8hoW|Ik4eBUGWUs6j~O*j)k{hrZ`E.ujW+Za{`WPn9Xk.&g]*F(HsV~q0fL8g'
NONCE_KEY='V0aau(w+|CAW_.+ilIkYaIh]8Bz}#,DdX#yBi+!dD5Zy:,YO+<CF+oYwP+~jYE,r'
AUTH_SALT='_zQ C^rzH%wBmmyjO,KH`J-EIZm$.MIzK[b(ar2+TgO=P&hHQ7d*lPsd8*+xu{4u'
SECURE_AUTH_SALT='EL~r.88e=TYM>W&LP]BI(u_f,PLQY|m%+2(2TF%,|S,Wc4uYV)hVBpZ .KA$cGhY'
LOGGED_IN_SALT='hEoqqkkJO~f`|p~43>gZx$;u&% {qJLe$OnreM,dfR`H?an+q3g`&9>?-v3iSoJ&'
NONCE_SALT='jfEVaR]Od2,yDPN|$o+g7Hd=XIwM,ow#a,,u|~d+pf/<T#NBcm(u9v?qpr#g^q5k'
DB_PREFIX=wp_
WP_VERSION=5.2.2
# mailhog
MAILHOG_HOST_PORT_SMTP=1028
MAILHOG_HOST_PORT_WEB=8028
My php dockerfile looks like this
ARG WP_VERSION
# Stage 0, build app
FROM php:7.3-fpm-stretch as build-container
RUN curl -sS https://getcomposer.org/installer | php \
&& chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_11.x | bash - && \
apt-get install -yq nodejs build-essential \
git unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
pkg-config \
libmcrypt-dev \
libpng-dev \
&& pecl install mcrypt-1.0.2 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-install bcmath \
&& docker-php-ext-install -j$(nproc) mysqli \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd
RUN npm install -g npm
WORKDIR /
WORKDIR /build
COPY . /build
RUN cp /build/wp-config.php.template /build/wp-config.php
# RUN bash /build/scripts/build-plugins.sh
# Stage 2, build app container
FROM php:7.3-fpm-stretch
ARG WP_VERSION
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libzip-dev \
unzip \
mariadb-client \
libmagickwand-dev \
&& docker-php-ext-configure gd --with-png-dir=/usr/include/ --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) \
bcmath \
exif \
gd \
mysqli \
opcache \
zip \
pdo \
pdo_mysql \
mysqli \
&& docker-php-ext-install -j$(nproc) iconv \
&& export CFLAGS="$PHP_CFLAGS" CPPFLAGS="$PHP_CPPFLAGS" LDFLAGS="$PHP_LDFLAGS" \
&& rm -rf /var/lib/apt/lists/* \
&& pecl install imagick-3.4.4 \
&& docker-php-ext-enable imagick
ADD https://downloads.wordpress.org/release/wordpress-$WP_VERSION-no-content.zip /var/www/latest.zip
RUN cd /var/www && unzip latest.zip && rm latest.zip
RUN rm -rf /var/www/html
RUN mkdir -p /var/www/html \
&& mv /var/www/wordpress/* /var/www/html/
# Copy wp files
COPY --from=build-container /build/ /var/www/html/
RUN chown www-data:www-data /var/www/html/ -R
COPY .docker/php-fpm/php.ini /usr/local/etc/php/
WORKDIR /var/www/html/
CMD ["php-fpm"]
And the dockerfile for nginx looks like this
ARG DOCKER_IMAGE_NAME_PHP
FROM $DOCKER_IMAGE_NAME_PHP as php-image
FROM nginx:latest
COPY .docker/nginx/scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY .docker/nginx/nginx.conf /opt/nginx.conf
COPY --from=php-image /var/www/html/ /var/www/html/
CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]
The nginx.conf looks like this:
worker_processes auto;
events {
worker_connections 2048;
}
http {
include mime.types;
index index.php index.html index.htm;
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name dev.project.com;
ssl_certificate /etc/nginx/dev.project.com.crt;
ssl_certificate_key /etc/nginx/dev.project.com.key;
root /var/www/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
client_max_body_size 128M;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass wordpress:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
}
And the docker-nginx-entrypoint.sh script looks like this
#!/bin/bash
set -e
cp /opt/nginx.conf /etc/nginx/conf.d/default.conf
exec nginx -g "daemon off;"
To start the docker I use
docker-compose -f .docker/docker-compose.yml --project-directory .docker up -d --build
I looked at the logs, and there is no error (in the wp container or nginx logs). The site works fine when I go to https://localhost:8443/wp-admin/ but the changes are propagated only on container reset. And it makes no sense (not to mention that it's basically an unusable dev environment).
P.S.
This is a bit more complicated setup, if you have any advice on simplifying it, the advice is welcomed.
EDIT
I'm bundling the assets using webpack, and when they are bundled, the changes are visible. The changes to the PHP file are not...
EDIT 2
I've used the official images for nginx and for wordpress, and the PHP part is again only changed on restart, so it's not the problem in the Dockerfiles.
So it turns out that the culprit was the opcache. Or rather me finding some example on line and just adding it to my php.ini without trying to understand what this actually means.
After reading this article and this excellent article that explains some opcache settings, I realised that my php.ini file had
opcache.revalidate_freq=60
Which you shouldn't have on your local development environment!
When used with opcache.validate_timestamps, PHP checks the revalidate_freq setting and uses it as a timestamp - if you made a request within 60 seconds (like the above example), the code will be pulled from the opcache - and you won't see any change in your browser. Only after 60 seconds will this change be visible.
So setting it to 0 (checking code on every single request) solves the issue.
Point of the story: check everything and read about every settings that you use!
'Unfortunately' for me I was reading the nginx config because I thought I messed something up there 😁
Related
Hi im trying to lunch multiple project with my docker-compose each image was created by me from scratch FROM debian:11 my react and express runing perfectly but i don't know why ngnix and symfony can't connect to each other if someone know what is the problem i get a 502 Bad Gateway
nginx/1.23.2 and i don't have any error message when i build with my docker compose in the terminal.
Dockerfile -
app/symfony/Dockerfile
FROM debian:11
RUN apt update && \
apt upgrade -y && \
apt install dirmngr ca-certificates software-properties-common gnupg gnupg2 apt-transport-https curl librabbitmq-dev -y && \
curl -sSL https://packages.sury.org/php/README.txt | bash -x && \
apt update && \
apt upgrade -y && \
apt install php8.1 \
php8.1-fpm \
php8.1-mysql \
php8.1-pdo \
php8.1-gd \
php8.1-cli \
php8.1-dom \
php8.1-mbstring \
php8.1-simplexml \
php8.1-phar \
php8.1-dev \
php8.1-amqp \
php8.1-redis \
unzip \
wget \
git -y && \
mkdir /run/php
WORKDIR /var/www/symfony
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
RUN curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | bash &&\
apt install symfony-cli
COPY composer.json composer.lock symfony.lock ./
COPY . .
RUN composer install
CMD ["php-fpm8.1", "-F"]
EXPOSE 9000
docker-compose of my project -
version: "3.8"
services:
nginx:
restart: unless-stopped
image: nginx:latest
ports:
- 1999:80
volumes:
- ./app/symfony:/var/www/symfony
- ./conf/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php-fpm
- db
php-fpm:
restart: always
build:
context: ./app/symfony
ports:
- 9000:9000
volumes:
- ./app/symfony:/var/www/symfony
depends_on:
- db
healthcheck:
test: [ "CMD", "php", "-v" ]
timeout: 30s
interval: 2s
retries: 30
db:
image: mysql:8
ports:
- 3306:3306
restart: always
volumes:
- ./database:/var/lib/mysql
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: docker
MYSQL_USER: user
MYSQL_PASSWORD: user_password
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- 8888:80
depends_on:
- db
node_express:
image: tlugat/debian_express
build:
context: ./app/express
restart: unless-stopped
ports:
- 8081:8081
react:
image: tlugat/debian_react
build:
context: ./app/react
restart: unless-stopped
ports:
- 3000:3000
maildev:
image: maildev/maildev
ports:
- 1080:1080
.default.conf-
conf/ngnix/default.conf
server {
listen 80;
index index.php;
server_name localhost;
root /var/www/symfony/public;
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
internal;
}
location ~ \\.php$ {
return 404;
}
}
I find the solution of my problem when you use docker to connect ngnix with php-fpm it's like you have vm in your vm so docker finds it, but don't know what to do when you pass him: fastcgi_pass php-fpm: 9000;
You just need to redirect ngnix to PHP-fpm like this docker understand his need to connect them together
I'm making a cURL request
curl -X 'POST' \
'http://localhost:8013/api/superheros' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "Clark Kent",
"slug": "supermman",
"featured": true,
"createdAt": "2021-10-11T11:48:22.366Z"
}'
to an API endpoint on my local above. I receive a 502 bad gateway error.
I'm using Docker for all intents and purposes.
docker-compose.yml
version: '3'
services:
#PHP Service
app1:
build:
context: .
dockerfile: Dockerfile
image: digitalocean.com/php
container_name: app1
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app1
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
#Nginx Service
webserver1:
image: nginx:alpine
container_name: webserver1
restart: unless-stopped
tty: true
ports:
- "8013:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db1:
image: mysql:5.7.22
container_name: db1
restart: unless-stopped
tty: true
ports:
- "3318:3306"
environment:
MYSQL_DATABASE: rest_api
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
Dockerfile
FROM php:7.4-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
libzip-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
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 app1: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;
}
}
I've read people saying that PHP-FPM isn't running but my Dockerfile clearly uses it. Are you able to offer some clues?
You could try to pass arguments to php-fpm in your Dockerfile as below, and make sure 9000 port is configured in local.ini
CMD ["php-fpm", "-F", "-y", "/usr/local/etc/php/conf.d/local.ini"]
-F force php-fpm running in foreground
-y sepcify the config path
After Dockerfile modified, you need to run docker-compose build to rebuild docker image
I'm fairly new to docker and trying to understand a few things about it.
Here's my scenario, I want to have my application in it's own image and then use docker compose to blend it together (since I've read that you shouldn't be mixing nginx & php together, according to best practices).
I made a small PoC and so far it's not working, but I'm hoping it's just more me missing something important.
when I type in docker-compose up, everything loads but nginx seems to not know anything about the php service as it just loads the default nginx page and trying to access any php code from the php service gives me a 404.
this is what my compose yaml file looks like:
services:
web:
image: nginx:mainline-alpine
depends_on:
- php
ports:
- "80:80"
volumes_from:
- php
volumes:
- ./nginx.conf:/etc/nginx/conf.d/nginx.conf
php:
image: myprivaterepo.com/poc/php-test:latest
volumes:
- ./app:/app
and the dockerfile is currently simply:
FROM php:fpm
WORKDIR /app
COPY . .
CMD ["php-fpm"]
the idea is the php service has the php code and the web service would be able to access the files and it'd work.
I'm fairly sure I'm just missing something important but since I'm still new to this, I'm not sure what that is.
The goal would be to have the application all packed up and just spin up without a lot of hassle.
What I do for docker is
First Dockerfile with everything I need; change docker file as you desire.
FROM php:7.2-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
mariadb-client \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Create mysql folder in root and my.cnf in that directory with the following content
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log
Now create nginx/conf.d folder with app.conf with the following
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;
}
}
Now just create php/local.ini folder and leave it as it is for now
Now create docker-compose.yml file with following
version: "3"
services:
app:
build:
context: .
dockerfile: Dockerfile
image: digitalocean.com/php
container_name: app-docker
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini`
networks:
- projectdocker
webserver:
image: nginx:alpine
container_name: nginx-docker
restart: unless-stopped
tty: true
ports:
- "8081:80"
- "444:444"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- projectdocker
db:
image: mysql:5.7.22
ports:
- "6001:3306"
container_name: db-docker
restart: unless-stopped
tty: true
environment:
MYSQL_DATABASE: docker
MYSQL_ROOT_PASSWORD: root
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- projectdocker
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "7000:80"
links:
- db:db-docker
environment:
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
networks:
- projectdocker
volumes:
dbdata:
driver: local
networks:
projectdocker:
driver: bridge
now run docker-compose up -d –build
link to localhost will be http://localhost:8081/
link to phpmyadmin will be http://localhost:7000/
Problem with Laravel, once launched with PHP-FPM and NGINX no file is accessible except index.php.
Once my application is launched all the application is executed successfully except that the CSS and my JS scripts present in the public folder of Laravel are not accessible and therefore it is not applied on the application.
My application is deployed with Docker and works like this:
A container for the laravel application launched with PHP-FPM
A NGINX container as web server
A Mysql container
File docker-compose.yml :
version: '3'
services:
#PHP Service
app-dockerTag:
image: appName
build:
context: .
dockerfile: Dockerfile
container_name: app-dockerTag
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www/html/
#Nginx Service
webserver-dockerTag:
image: nginx:alpine
container_name: webserver-dockerTag
restart: unless-stopped
tty: true
ports:
- "portApp:80"
volumes:
- ./:/var/www
- ./build/nginx/:/etc/nginx/conf.d/
#MySQL Service
db:
image: mysql:5.7.22
container_name: db
restart: unless-stopped
tty: true
ports:
- dbPort:dbPort
volumes:
- ./mysql/:/docker-entrypoint-initdb.d
- ./api:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=dbRootPassword
- MYSQL_DATABASE=dbDatabase
- MYSQL_USER=dbUsername
- MYSQL_PASSWORD=dbPassword
- MYSQL_HOST_ROOT=%
- MYSQL_TCP_PORT=dbPort
File conf nginx :
server {
listen 80;
root /var/www/html/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app-dockerTag: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 ~ /\.(?!well-known).* {
deny all;
}
}
File DockerFiles for laravel :
FROM php:7.3-fpm
# Set working directory
WORKDIR /var/www/html
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
mariadb-client \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libzip-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
COPY composer.json composer.json
#COPY composer.lock composer.lock /var/www/
COPY . .
RUN composer install
RUN composer dump-autoload
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www/html
# Copy existing application directory permissions
COPY --chown=www:www . /var/www/html
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm", "-F"]
My problem does not appear when I work locally with php artisan serve and once docked, all files normally accessible in public generate 404 errors.
I'm trying to setup a docker for some PHP projects for local environment. I have created docker-compose file:
############
## This is the LOCAL docker-compose. local is not in the file to make it default,
## easy for development.
############
version: '3.5'
services:
nginx:
build: ./docker/images/nginx
image: project/nginx:latest
ports:
- "80:80"
expose:
- "80"
volumes:
- project_volume:/var/www/vhosts/abboom
networks:
project:
aliases:
- project.local.net
environment:
- VIRTUAL_HOST=project.local.net
php:
build: ./docker/images/php
image: project/php:latest
ports:
- "7778:7778"
expose:
- "9000"
volumes:
- project_volume:/var/www/vhosts/project
networks:
- project
workspace:
build: ./docker/images/workspace
image: project/workspace:latest
volumes:
- project_volume:/var/www/vhosts/project
working_dir: /var/www/vhosts/project
networks:
- project
redis_disk:
build: ./docker/images/redis_disk
image: project/redis:latest
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- project
mysql:
image: project/mysql:latest
build: ./docker/images/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
volumes:
- mysqldata:/var/lib/mysql
networks:
- project
ports:
- "33066:3306"
networks:
project:
name: project
volumes:
mysqldata:
driver: local
redis_data:
driver: local
project_volume:
driver: local
driver_opts:
type: nfs
device: "$PWD/project"
o: bind
also probably I need to share the nginx virtual host for a project (I took this virtual host config from the staging server, maybe it require some more changes?)
server {
listen 80;
server_name project.local.net;
root /var/www/vhosts/project/public;
index index.php;
access_log /var/log/nginx/host.access.log main;
# redirect server error pages to the static page /50x.html
#
error_page 400 404 500 502 503 504 /500.html;
location = /500.html {
}
location ~ /(assets/|content/|images/|stylesheets/|javascripts/|vendor/|fonts/|favicon.ico) {
root /var/www/vhosts/project/public;
}
location / {
root /var/www/vhosts/project/public;
try_files $uri $uri/ /index.php?$args;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
So the issue is that I'm getting the error Uncaught PDOException: could not find a driver in when I'm trying to access the site from a browser, but when I, for example, running migration from worksapce or php container all is working correctly.
I'm assuming that for some reason nginx container is not linked with php container and trying to find the pdo driver inside of the nginx container instead of looking it in the PHP? But it also sounds like not correct, as it starts processing php scripts and stacking only on the pdo, so it connected to the php container, so I'm not sure where to look for a problem
Previously I have made docker setup for many projects but they was written with PHP frameworks like Laravel, Symfony , but this one is a handwritten project and maybe it requires some additional changes?
Updated
Here is a php Docker file:
FROM php:7.1-fpm-alpine
LABEL maintainer="Vincent Composieux <vincent.composieux#gmail.com>"
RUN set -ex \
&& apk --no-cache add \
postgresql-dev
RUN apk add --update \
php7-common \
php7-fpm \
php7-apcu \
php7-ctype \
php7-curl \
php7-dom \
php7-gd \
php7-iconv \
php7-json \
php7-intl \
php7-mcrypt \
php7-mbstring \
php7-opcache \
php7-openssl \
php7-pdo \
php7-pdo_sqlite \
php7-xml \
php7-xmlwriter \
php7-zlib \
php7-phar \
php7-tokenizer \
php7-session \
php7-simplexml \
php7-xdebug \
php7-bcmath\
php7-intl \
php-fileinfo \
php7-redis \
php-gd \
make \
curl \
nano \
g++ \
icu-dev \
libxslt \
libxslt-dev
RUN docker-php-ext-configure pdo_mysql && docker-php-ext-install mysqli pdo_mysql && docker-php-ext-enable pdo_mysql
RUN docker-php-ext-install bcmath
RUN docker-php-ext-configure intl && docker-php-ext-install intl
RUN docker-php-ext-install xsl
RUN rm -rf /var/cache/apk/* && rm -rf /tmp/* && \
curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer && chmod +x /usr/bin/composer
ADD php.ini /etc/php7/php-fpm.d/
ADD php.ini /etc/php7/cli/conf.d/
ADD php.ini /etc/php7/cli/conf.d/
ADD xdebug.ini /etc/php7/conf.d/
ADD www.conf /etc/php7/php-fpm.d/
RUN sed -i "s|memory_limit = 128M|memory_limit = 512M |g" /etc/php7/php.ini
RUN sed -i "s|upload_max_file_size = 2M|upload_max_file_size = 1024M |g" /etc/php7/php.ini
RUN sed -i "s|post_max_size = 8M|post_max_size = 1024M |g" /etc/php7/php.ini
RUN sed -i "s|max_execution_time = 30|max_execution_time = 600 |g" /etc/php7/php.ini
CMD ["php-fpm7", "-F"]
WORKDIR /var/www/vhosts/project
EXPOSE 9000
also php -m showing pdo_mysql in the list of enabled extensions
I made it, so if in docker file I have only RUN docker-php-ext-configure pdo_mysql && docker-php-ext-install mysqli pdo_mysql && docker-php-ext-enable pdo_mysql it's working for CLI, if I have only RUN apk add --update php7-pdo_mysql it's working for fpm but not for cli, so I added both and it working for for cli and fpm. But it's weird as I'm using boiler plait docker confids I have used already many times, and first time faced that issue...