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...
Related
I'm trying to load my custom .ini file
I've tried mounting the /usr/local/etc/php/conf.d directory to ./php so that I can add .ini files, but it doesn't work, I mean the local directory php gets created but it's empty.
One more thing I'm curious about, what if the same config already exists in any of those already loaded .ini file, will my custom .ini will overwrite those? (That's actually what I want).
This is my Dockerfile
FROM php:8.1.2-apache
RUN apt-get update
# 1. development packages
RUN apt-get install -y \
git \
zip \
curl \
sudo \
unzip \
libicu-dev \
libbz2-dev \
libpng-dev \
libjpeg-dev \
libmcrypt-dev \
libreadline-dev \
libzip-dev \
libfreetype6-dev \
g++
# 2. apache configs + document root
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# 3. mod_rewrite for URL rewrite and mod_headers for .htaccess extra headers like Access-Control-Allow-Origin-
RUN a2enmod rewrite headers
# 4. start with base php config, then add extensions
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN docker-php-ext-install \
bz2 \
intl \
iconv \
bcmath \
opcache \
calendar \
pdo_mysql \
pdo_mysql \
zip
# 5. composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
And here's the docker-compose.yml
version: '3.5'
services:
# Laravel App
laravel:
build:
context: '.'
restart: always
volumes:
- .:/var/www/html
# - ./php:/usr/local/etc/php/conf.d (This doesn't work)
# MySQL
mysql:
image: mysql:8
restart: always
volumes:
- ./run/var:/var/lib/mysql
environment:
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
# Meilisearch
meilisearch:
image: getmeili/meilisearch:latest
restart: always
volumes:
- ./meilisearch/data.ms:/data.ms
environment:
- MEILI_MASTER_KEY=${MEILISEARCH_KEY}
networks:
default:
name: nginxproxymanager_default
external: true
Many thanks in advance :)
Set path direct to file
volumes:
- ./:/var/www
- ./Docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
Check my docker-compose for more information: https://github.com/JavierAgueroCL/docker-php7.4-with-db-extensions/blob/master/docker-compose.yml
This question already has an answer here:
Connect to another container using Docker compose
(1 answer)
Closed last year.
I'm developing a project based on the Github template dunglas/symfony-docker to which I want to add a mysql database..
It seems that my docker-compose.yml file is incorrectly configured because the communication between PHP and mysql is malfunctioning. Indeed when I try to perform a symfony migration, doctrine returns me the following error
An exception occurred in the driver: SQLSTATE[HY000] [2002] No such file or directory
When I inspect the PHP logs I notice that PHP is waiting after the database
php_1 | Still waiting for db to be ready... Or maybe the db is not reachable.
my docker-compose.yml look like :
version: "3.4"
services:
php:
build:
context: .
target: symfony_php
args:
SYMFONY_VERSION: ${SYMFONY_VERSION:-}
SKELETON: ${SKELETON:-symfony/skeleton}
STABILITY: ${STABILITY:-stable}
restart: unless-stopped
volumes:
- php_socket:/var/run/php
healthcheck:
interval: 10s
timeout: 3s
retries: 3
start_period: 30s
environment:
# Run "composer require symfony/orm-pack" to install and configure Doctrine ORM
#DATABASE_URL: postgresql://${POSTGRES_USER:-symfony}:${POSTGRES_PASSWORD:-ChangeMe}#database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-13}
DATABASE_URL: mysql://wijo:wijo#localhost:3306/wijo"
# Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration
MERCURE_URL: ${CADDY_MERCURE_URL:-http://caddy/.well-known/mercure}
MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure
MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!}
caddy:
build:
context: .
target: symfony_caddy
depends_on:
- php
environment:
SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80}
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!}
restart: unless-stopped
volumes:
- php_socket:/var/run/php
- caddy_data:/data
- caddy_config:/config
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'wijo'
MYSQL_USER: 'wijo'
MYSQL_PASSWORD: 'wijo'
MYSQL_DATABASE: 'wijo'
volumes:
- db-data:/var/lib/mysql
- ./docker/db/data:/var/lib/mysql
adminer:
image: adminer
restart: always
ports:
- 8080:8080
volumes:
php_socket:
caddy_data:
caddy_config:
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
###> doctrine/doctrine-bundle ###
db-data:
###< doctrine/doctrine-bundle ###
dockerFile
# the different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
# https://docs.docker.com/compose/compose-file/#target
# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG PHP_VERSION=8.1
ARG CADDY_VERSION=2
# "php" stage
FROM php:${PHP_VERSION}-fpm-alpine AS symfony_php
# persistent / runtime deps
RUN apk add --no-cache \
acl \
fcgi \
file \
gettext \
git \
gnu-libiconv \
;
# install gnu-libiconv and set LD_PRELOAD env to make iconv work fully on Alpine image.
# see https://github.com/docker-library/php/issues/240#issuecomment-763112749
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so
ARG APCU_VERSION=5.1.21
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
icu-dev \
libzip-dev \
zlib-dev \
; \
\
docker-php-ext-configure zip; \
docker-php-ext-install -j$(nproc) \
intl \
zip \
; \
pecl install \
apcu-${APCU_VERSION} \
; \
pecl clear-cache; \
docker-php-ext-enable \
apcu \
opcache \
; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-cache --virtual .phpexts-rundeps $runDeps; \
\
apk del .build-deps
COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
RUN chmod +x /usr/local/bin/docker-healthcheck
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
COPY docker/php/conf.d/symfony.prod.ini $PHP_INI_DIR/conf.d/symfony.ini
COPY docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
VOLUME /var/run/php
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV PATH="${PATH}:/root/.composer/vendor/bin"
WORKDIR /srv/app
# Allow to choose skeleton
ARG SKELETON="symfony/skeleton"
ENV SKELETON ${SKELETON}
# Allow to use development versions of Symfony
ARG STABILITY="stable"
ENV STABILITY ${STABILITY}
# Allow to select skeleton version
ARG SYMFONY_VERSION=""
ENV SYMFONY_VERSION ${SYMFONY_VERSION}
# Download the Symfony skeleton and leverage Docker cache layers
RUN composer create-project "${SKELETON} ${SYMFONY_VERSION}" . --stability=$STABILITY --prefer-dist --no-dev --no-progress --no-interaction; \
composer clear-cache
###> recipes ###
###> doctrine/doctrine-bundle ###
RUN apk add --no-cache --virtual .pgsql-deps postgresql-dev; \
docker-php-ext-install -j$(nproc) pdo_pgsql; \
apk add --no-cache --virtual .pgsql-rundeps so:libpq.so.5; \
apk del .pgsql-deps
###< doctrine/doctrine-bundle ###
###< recipes ###
COPY . .
RUN set -eux; \
mkdir -p var/cache var/log; \
composer install --prefer-dist --no-dev --no-progress --no-scripts --no-interaction; \
composer dump-autoload --classmap-authoritative --no-dev; \
composer symfony:dump-env prod; \
composer run-script --no-dev post-install-cmd; \
chmod +x bin/console; sync
VOLUME /srv/app/var
ENTRYPOINT ["docker-entrypoint"]
CMD ["php-fpm"]
FROM caddy:${CADDY_VERSION}-builder-alpine AS symfony_caddy_builder
RUN xcaddy build \
--with github.com/dunglas/mercure \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain \
--with github.com/dunglas/vulcain/caddy
FROM caddy:${CADDY_VERSION} AS symfony_caddy
WORKDIR /srv/app
COPY --from=dunglas/mercure:v0.11 /srv/public /srv/mercure-assets/
COPY --from=symfony_caddy_builder /usr/bin/caddy /usr/bin/caddy
COPY --from=symfony_php /srv/app/public public/
COPY docker/caddy/Caddyfile /etc/caddy/Caddyfile
my database url
DATABASE_URL="mysql://wijo:wijo#localhost:3306/wijo"
Any clues to the issue?
localhost in a container means the container itself. You want to talk to your database container, so you should use it's service name and your database URL should be
DATABASE_URL="mysql://wijo:wijo#db:3306/wijo"
Does anyone have any idea why the request time of my Laravel project is running very slow? I'm running the project on Docker and I use a Dockerfile and docker-compose.yml. I'm also using nginx
I have tried multiple things like Eager loading and artisan optimize but none of those seems to work.
I'm running this on a laptop with an i7-9750H and 16gb RAM.
This what my debugbar says:
Dockerfile in a folder named 'php':
FROM php:8.0-fpm-alpine
RUN apk add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data
RUN chmod 777 /dev/stdout /dev/stderr
RUN apk --update add wget \
curl \
git \
grep \
build-base \
libmcrypt-dev \
libxml2-dev \
zlib-dev \
autoconf \
cyrus-sasl-dev \
libgsasl-dev \
composer \
supervisor \
libpng-dev \
freetype-dev \
libjpeg-turbo-dev \
libjpeg-turbo-utils \
openssh \
htop \
nano \
ghostscript \
imagemagick-dev \
libzip-dev \
wkhtmltopdf \
jpegoptim \
optipng \
pngquant \
pngcrush \
gifsicle \
bash
RUN apk add --update --no-cache graphviz font-bitstream-type1
RUN echo '* * * * * php /var/www/html/artisan schedule:run' | crontab -u www-data -
RUN rm -rf /var/spool/cron/crontabs/root
RUN docker-php-ext-install mysqli pdo pdo_mysql tokenizer xml zip exif
RUN pecl channel-update pecl.php.net \
&& pecl install redis \
&& rm -rf /tmp/pear \
&& docker-php-ext-enable redis \
&& docker-php-ext-install gd \
&& docker-php-ext-install -j$(nproc) iconv \
&& docker-php-ext-configure gd \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install bcmath
# install imagick
# use github version for now until release from https://pecl.php.net/get/imagick is ready for PHP 8
RUN mkdir -p /usr/src/php/ext/imagick \
&& curl -fsSL https://github.com/Imagick/imagick/archive/06116aa24b76edaf6b1693198f79e6c295eda8a9.tar.gz | tar xvz -C "/usr/src/php/ext/imagick" --strip 1 \
&& docker-php-ext-install imagick
RUN rm /var/cache/apk/* && \
mkdir -p /var/www && \
chown www-data:www-data /var/www -R
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
USER www-data
RUN composer global require laravel/envoy
ENV PATH "$PATH:/home/www-data/.composer/vendor/bin"
Dockerfile inside folder named 'nginx':
FROM nginx:alpine
docker-compose.yml
version: "3"
services:
php:
volumes:
- './src/:/var/www/html'
- './.docker/php/supervisor.conf:/etc/supervisord.conf'
tty: true
build:
context: .
dockerfile: .docker/php/Dockerfile
links:
- "db:database"
- "redis:redis"
networks:
internal:
traefik:
nginx:
image: nginx:alpine
volumes:
- './src:/var/www/html'
- './.docker/nginx/nginx/conf.d/:/etc/nginx/conf.d/'
- './.docker/nginx/nginx/nginx.conf:/etc/nginx/nginx.conf'
labels:
traefik.backend: domain.test
traefik.frontend.rule: "Host:library.test"
traefik.docker.network: traefik
traefik.port: 80
networks:
internal:
traefik:
depends_on:
- php
db:
image: mysql/mysql-server:latest
environment:
MYSQL_DATABASE: 'library'
MYSQL_USER: 'amin'
MYSQL_PASSWORD: 'secret'
MYSQL_ROOT_PASSWORD: 'secret'
DEFAULT_AUTHENTICATION_PLUGIN: 'mysql_native_password'
volumes:
- mysql:/var/lib/mysql:rw
- './database:/var/data'
networks:
- internal
ports:
- "3306:3306"
# Cache server
redis:
image: redis:4-alpine
volumes:
- redis:/data:rw
networks:
internal:
volumes:
mysql:
driver: "local"
redis:
driver: "local"
networks:
traefik:
external: true
internal:
external: false
That's not slow.
20MB in 1.7s is about 12MB/s, with overheads that's pretty quick.
The route you're hitting is returning heaps of data, probably more than you expect, and that's why it looks like it's running slow.
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 😁
I'm on this issue since 2 days, trying a lot of solutions found on internet but no one resolved my case... I'm frustrated, I hope someone could help me.
I'm on Linux, and I don't really understand anything with server ports, hosts, etc.
It seems that this project uses API Platform, I don't know if it could help or not.
I can't figure out how to launch this project I just received. I have an issue when launching containers (docker-compose up) :
Error thrown while running command "doctrine:schema:update -f". Message: "An exception occurred in driver: SQLSTATE[08006] [7] could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
php_1 | TCP/IP connections on port 5432?
php_1 | could not connect to server: Address not available
php_1 | Is the server running on host "localhost" (::1) and accepting
php_1 | TCP/IP connections on port 5432?"
It seems that the container can't communicate with the DB container. But I don't know exactly what to do to solve this.
There is several containers in the docker-composer.yml :
version: '3'
services:
php:
build:
context: ./api
depends_on:
- db
env_file:
- ./api/.env
# Comment out these volumes in production
volumes:
- ./api:/srv/api:rw,cached
# If you develop on Linux, comment out the following volumes to just use bind-mounted project directory from host
- /srv/api/var/
- /srv/api/var/cache/
- /srv/api/var/logs/
- /srv/api/var/sessions/
api:
build:
context: ./api
dockerfile: ./Dockerfile.nginx
depends_on:
- php
ports:
- "8080:80"
volumes:
- ./api/public:/srv/api/public:ro
cache-proxy:
build:
context: ./api
dockerfile: ./Dockerfile.varnish
depends_on:
- api
# Comment out this volume in production
volumes:
- ./api/docker/varnish/conf:/etc/varnish:ro
ports:
- "8081:80"
db:
# In production, you may want to use a managed database service
image: postgres:9.6-alpine
environment:
- POSTGRES_DB=api
- POSTGRES_USER=api-platform
# You should definitely change the password in production
- POSTGRES_PASSWORD=!ChangeMe!
volumes:
- db-data:/var/lib/postgresql/data:rw
# You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
# - ./docker/db/data:/var/lib/postgresql/data:rw
ports:
- "5432:5432"
client:
# Use a static website hosting service in production
# See https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#deployment
build:
context: ./client
dockerfile: ./Dockerfile
env_file:
- ./client/.env
volumes:
- ./client:/usr/src/client:rw,cached
- /usr/src/client/node_modules
ports:
- "80:3000"
h2-proxy:
# Don't use this proxy in prod
build:
context: ./h2-proxy
dockerfile: ./Dockerfile
depends_on:
- client
- api
- cache-proxy
ports:
- "443:443"
- "444:444"
- "8443:8443"
- "8444:8444"
volumes:
db-data: {}
Dockerfile :
ARG PHP_VERSION=7.2
ARG ALPINE_VERSION=3.7
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION}
RUN apk add --no-cache \
git
ARG APCU_VERSION=5.1.11
RUN set -xe \
&& apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
icu-dev \
postgresql-dev \
zlib-dev \
&& docker-php-ext-install -j$(nproc) \
intl \
pdo_pgsql \
zip \
&& pecl install \
apcu-${APCU_VERSION} \
&& docker-php-ext-enable --ini-name 20-apcu.ini apcu \
&& docker-php-ext-enable --ini-name 05-opcache.ini opcache \
&& runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)" \
&& apk add --no-cache --virtual .api-phpexts-rundeps $runDeps \
&& apk del .build-deps
RUN apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev && \
docker-php-ext-configure gd \
--with-gd \
--with-freetype-dir=/usr/include/ \
--with-png-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ && \
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
docker-php-ext-install -j${NPROC} gd exif && \
apk del --no-cache freetype-dev libpng-dev libjpeg-turbo-dev
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY docker/php/php.ini /usr/local/etc/php/php.ini
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN composer global require "hirak/prestissimo:^0.3" --prefer-dist --no-progress --no-suggest --classmap-authoritative
RUN apk add --no-cache ffmpeg
WORKDIR /srv/api
# Prevent Symfony Flex from generating a project ID at build time
ARG SYMFONY_SKIP_REGISTRATION=1
# Prevent the reinstallation of vendors at every changes in the source code
COPY composer.json composer.lock ./
RUN composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress --no-suggest \
&& composer clear-cache
COPY . ./
RUN mkdir -p var/cache var/logs var/sessions \
&& composer dump-autoload --classmap-authoritative --no-dev \
&& chown -R www-data var
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
CMD ["php-fpm"]
.env file :
APP_ENV=dev
APP_SECRET=!ChangeMe!
TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
TRUSTED_HOSTS=localhost,api
DATABASE_URL=pgsql://api-platform:!ChangeMe!#localhost/api
CORS_ALLOW_ORIGIN=^https?://localhost:?[0-9]*$
VARNISH_URL=http://cache-proxy
JWT_PRIVATE_KEY_PATH=config/jwt/private.pem
JWT_PUBLIC_KEY_PATH=config/jwt/public.pem
JWT_PASSPHRASE=symfony
JWT_TOKEN_TTL=null
MAILER_URL=gmail://email:password#localhost?
MAILER_FROM=user#example.com
CLIENT_MAGIC_LINK_URL=https://localhost/login
FACEBOOK_CLIENT_ID=433898047056774
FACEBOOK_CLIENT_SECRET=90ac80e435405a2ffeaab8a242981152
AUTH_API_KEY=123456789
ADMIN_PWD=$2y$13$vqd7AMd0A5eetDT00qLd2OkGG8T9UJ1gLsD2huOhk3iRwGCBqR3iu
I don't know if you guys needs something more. Just tell me what you need.
Thanks a lot...
You have to use the db as the database host, not localhost in the DATABASE_URL application env.