How can I connect php-apache and MySQL using Docker? - php

I have a Wordpress site on live server and I want to create a LAMP stack locally with Docker to test things.
I pull the images of php:7.0-apache and mysql:5.7, the same versions on live.
I create a MySQL container:
docker run -d --name achi-mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
I create a php & apache container and link it with MySQL:
docker run -d --name achi-php-apache --link achi-mysql:mysql -p 8080:80 -v /home/achi/workspace/web/wordpress-template/:/var/www/html php:7.0-apache
I get the following error on localhost:8080:
Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/wp-includes/wp-db.php:1564 [...]
Do I link these two containers the wrong way?

Your problem is not the connection between your containers. The problem is your PHP / Apache container which doesn't support mysqli (or PDO MySQL). WordPress can't find another function to connect with a MySQL database or your MySQL container. Instead WordPress is using a deprecated and removed (since PHP 7.0) mysql_ function per default. You need to install at least mysqli on your PHP container (explained below).
I also recommend to use a docker-compose file to install and run all containers with one command.
To create the containers you want, you can use the following docker-compose.yml file:
version: "3"
services:
achi-php-apache:
build:
context: ./
container_name: achi-php-apache
ports:
- "8080:80"
volumes:
- /home/achi/workspace/web/wordpress-template:/var/www/html:rw
depends_on:
- achi-mysql
networks:
- wp-net
achi-mysql:
image: mysql:5.7
container_name: achi-mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wp-dbname
volumes:
- wp-mysql-data:/var/lib/mysql
networks:
- wp-net
networks:
wp-net:
driver: bridge
volumes:
wp-mysql-data:
You need the following Dockerfile on the same directory as the docker-compose.yml file:
FROM php:7.0-apache
RUN docker-php-ext-install -j$(nproc) mysqli
This Dockerfile installs the missing mysqli extension so WordPress can use it.
You can also use PDO MySQL instead of mysqli. In this case you can use the following Dockerfile:
FROM php:7.0-apache
RUN docker-php-ext-install -j$(nproc) pdo
RUN docker-php-ext-install -j$(nproc) pdo_mysql
Now you can execute the command docker-compose up inside the folder where the docker-compose.yml file is located. After creating the container and running you should be able to access the WordPress site (<ip-or-hostname>:8080).
On the wp-config.php file you need to use the following constants:
define('DB_NAME', 'wp-dbname');
define('DB_USER', 'root');
define('DB_PASSWORD', '123456');
define('DB_HOST', 'achi-mysql');
You can also use the official WordPress image to install WordPress. In this case you can use the following docker-compose.yml file:
version: "3"
services:
achi-php-apache:
image: wordpress:4.9.4-php7.0-apache
container_name: achi-php-apache
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: achi-mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wp-dbname
volumes:
- /home/achi/workspace/web/wordpress-template:/var/www/html:rw
depends_on:
- achi-mysql
networks:
- wp-net
achi-mysql:
image: mysql:5.7
container_name: achi-mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wp-dbname
volumes:
- wp-mysql-data:/var/lib/mysql
networks:
- wp-net
networks:
wp-net:
driver: bridge
volumes:
wp-mysql-data:

The simplest way is to use docker-compose to link all your docker instances together rather than linking through the docker command. Here is a sample docker-compose.yml file that should do what you want:
version: '2'
services:
achi-php-apache:
image: php:7.0-apache
ports:
- "8080:80"
volumes:
- /home/achi/workspace/web/wordpress-template/:/var/www/html
links:
- achi-mysql
achi-mysql:
image: mysql:5.7
volumes:
- /var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_USER: someuser
MYSQL_PASSWORD: somepassword
MYSQL_DATABASE: somedefaultdatabase

Related

Convert simple Dockerfile to docker-compose

I have a simple Dockerfile for php:7.2-fpm that is being referenced by my docker-compose.yml configuration. I want to get rid of the Dockerfile which is located at php/Dockerfile and integrate the commands to my docker-compose-yml file.
Here is my php/Dockerfile:
FROM php:7.2-fpm
RUN docker-php-ext-install mysqli
And here is my docker-compose.yml which brings up php-fpm, nginx, letencrypt certbot, mysql, and phpmyadmin:
version: '3'
services:
php:
container_name: dev_php
build:
context: ./php
ports:
- 9000:9000
volumes:
- ./website:/website
- ./php/www.conf:/usr/local/etc/php-fpm.d/www.conf
environment:
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
nginx:
container_name: dev_nginx
image: nginx:1.13.8
ports:
- 80:80
- 443:443
volumes:
- ./website:/website
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
depends_on:
- php
- mysql
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
container_name: dev_certbot
image: certbot/certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
mysql:
container_name: dev_mysql
image: mysql:5.7
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./mysql:/docker-entrypoint-initdb.d
phpmyadmin:
container_name: dev_pma
image: phpmyadmin/phpmyadmin
links:
- mysql
depends_on:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_ARBITRARY: 1
restart: always
ports:
- 8183:80
Since my php/Dockerfile is relatively simple, I thought I could do something like this:
php:
container_name: dev_php
image: php:7.2-fpm
ports:
- 9000:9000
volumes:
- ./website:/website
- ./php/www.conf:/usr/local/etc/php-fpm.d/www.conf
environment:
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
command: bash -c "docker-php-ext-install mysqli"
But this does not work. When I bring my project up using docker-compose up I can see dev_php (the name of the PHP container) perform a bunch of tasks that I do not ordinarily see, it then proceeds to install mysqli but then quits immediately after with exit code 0.
Thoughts?
Your original Dockerfile does much more than just installing the mysqli extension.
It has the entrypoint as shown in the source code here
It also has the command as shown here
These entrypoint and command are what will start the container and keep it running
Now back to your modification:
I can see dev_php (the name of the PHP container) perform a bunch of tasks that I do not ordinarily see
This is the output of docker-php-ext-install mysqli. You did not see it before is because it was done when building the docker image.
quits immediately after with exit code 0
This is expected because the command has finished processing and there is nothing else for it to do.
In order to keep the container running, you will have to manually add in the original entrypoint and command. Something like this:
php:
container_name: dev_php
image: php:7.2-fpm
ports:
- 9000:9000
volumes:
- ./website:/website
- ./php/www.conf:/usr/local/etc/php-fpm.d/www.conf
environment:
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
entrypoint:
- bash
- -c
command:
- |
docker-php-ext-install mysqli; \
docker-php-entrypoint php-fpm
I have not tested to confirm that the syntax is 100% correct but you should get the idea. The important bit is docker-php-entrypoint php-fpm
My recommendation is to just stick to using Dockerfile in this case.
A good side effect is that Docker will cache the build layers so you do not need to wait for the installing process of mysqli every time you want to start the containers.
You may consider enabling the extension too

Docker-compose WordPress with PHP extensions

I have been using the following docker-compose.yml to build a WordPress environment. Everything has been working fine, except when I attempt to use PHP function easter_date() I receive an undefined function error.
Could anyone explain to me what I need to add to the YML file in order to include the PHP easter_date() extension?
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- ./data:/docker-entrypoint-initdb.d # This will import DB data from an sql file in your /data folder
- ./data/migrate.sql:/docker-entrypoint-initdb.d/migrate.sql # run sql commands in migrate.sql to update site urls in DB
restart: always
ports:
- "3400:3306" # mapping our ports for networking
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
ports:
- "8080:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: wordpress
DOCKER_COMPOSE_YML_LOCATION: wordpress
container_name: wp_phpmyadmin
wordpress:
build:
context: .
depends_on:
- db
image: wordpress:latest
ports:
- "3500:80" # mapping our ports for networking
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DEBUG: 1
WORDPRESS_MEMORY_LIMIT: 256MB
working_dir: /var/www/html
volumes: # this is where we tell Docker what to pay attention to
- ./wp-content:/var/www/html/wp-content
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini # create custom uploads.ini which has an increased upload file size limit, memory etc.
volumes:
db_data: {}
I have attempted to include PHP extensions by inserting the following two lines:
php: #https://stackoverflow.com/questions/46401966/install-packages-from-docker-compose-yml-into-docker-container
build: './docker/php'
And then created a Dockerfile inside ./docker/php with
FROM php:7.1-fpm
RUN docker-php-ext-install calendar && docker-php-ext-configure calendar
But I receive ERROR: Cannot locate specified Dockerfile: Dockerfile when I run docker-compose build

How to load mysqli extension inside docker-compose.yml file with NGINX, PHP-FPM

When loading docker-compose up, wordpress loads on the url but the mysqli_connect function is undefined because of the absence of the extension.
I have tried to add the following under the fpm image
command: "docker-php-ext-install mysqli"
I have tried to add a Dockerfile into the directory of the docker-compose.yml file containing
version: "3"
services:
#database
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
networks:
- wpsite
# webserver
nginx:
image: nginx:latest
ports:
- "8080:80"
links:
- fpm
volumes:
- /Users/connergesbocker/Github/cbgesbocker/dotfiles/root/etc/nginx/conf.d/village.conf:/etc/nginx/conf.d/village.conf
- /Users/connergesbocker/WordPress:/WordPress
networks:
- wpsite
# phpmyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- "8888:8888"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: wordpress
networks:
- wpsite
fpm:
image: php:5.6.20-fpm
ports:
- "90:9000"
# command: "docker-php-ext-install mysqli"
links:
- db
volumes:
- /Users/connergesbocker/WordPress:/WordPress
working_dir: "/"
networks:
- wpsite
networks:
wpsite:
volumes:
db_data:```
You could customize your dockerfile & add install in it:
Dockerfile:
FROM php:5.6.20-fpm
RUN docker-php-ext-install mysqli
Part of docker-compose.yaml:
fpm:
build: .
image: myphp:1
ports:
- "90:9000"
# command: "docker-php-ext-install mysqli"
links:
- db
volumes:
- /Users/connergesbocker/WordPress:/WordPress
working_dir: "/"
networks:
- wpsite
your override will install the extension but the container will stop after installation because php-fpm will not start by overriding CMD. Replace the command with below one.
command:
- /bin/sh
- -c
- |
docker-php-ext-install mysqli
echo "extension installed.....starting php-fpm........................................"
php-fpm

MySQLi not found in docker php container

Error:
Fatal error: Uncaught Error: Class 'mysqli' not found in /var/www/html/index.php:16 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 16
I made the index.php file and PDO mysql connection example code. Everything working as expected, except MySQLi connection. I added docker-php-ext-install run command to docker file but that did not help.
Here is my PHP docker file:
FROM php:7.0-fpm
RUN docker-php-ext-install pdo pdo_mysql mysqli
RUN docker-php-ext-enable mysqli
My docker-compose.yml file:
nginx:
build: ./nginx/
container_name: nginx-container
ports:
- 8080:80
links:
- php
volumes_from:
- app-data
php:
build: ./php/
container_name: php-container
expose:
- 9000
links:
- mysql
volumes_from:
- app-data
app-data:
#image: php:7.0-fpm
build: ./php/
container_name: app-data-container
volumes:
- ./www/html/:/var/www/html/
- ./nginx/nginx:/etc/nginx/conf.d
command: “true”
mysql:
#image: mysql:5.7
build: ./mysql/
container_name: mysql-container
expose:
- 3306
ports:
- 3306:3306
volumes_from:
- mysql-data
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: zavrel_db
MYSQL_USER: user
MYSQL_PASSWORD: password
mysql-data:
image: mysql:latest
container_name: mysql-data-container
volumes:
- /var/lib/mysql
command: "true"
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin-container
ports:
- 8888:80
links:
- mysql
environment:
PMA_HOST: mysql
Thank you.
Try change name of packet
php-mysqli
I solved the problem by deleting all images and containers. After that, I started and everything is fine.
docker rmi $(docker images -a -q)
docker rm $(docker ps -a -q)
I found the problem, the package is RUN pdo_mysqliso
i've added this RUN docker-php-ext-install pdo_mysqli in my docker-compose

Docker - how to set up Apache + PHP in docker-compose.yml

I use this to set up nginx for PHP:
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php
php:
image: php:7-fpm
volumes:
- ./code:/code
But how about Apache? How can I set up Apache + PHP in docker-compose.yml?
Following this guide:
version: '2'
services:
php:
build: php
ports:
- "80:80"
- "443:443"
volumes:
- ./php/www:/var/www/html
Error:
ERROR: In file './docker-compose.yml' service 'version' doesn't have any configuration options. All top level keys in your docker-compose.yml must map to a dictionary of configuration options.
Any ideas? I'm on Xubuntu 16.04.
EDIT:
After managing to upgrade docker-compose to 1.9, I try with this file below:
version: '2'
services:
php:
build: php
expose:
- 9000
volumes:
- ./php/www:/var/www/html
apache2:
image: webdevops/apache:latest
args:
- PHP_SOCKET=php:9000
volumes:
- ./php/www:/var/www/html
ports:
- 80:80
- 443:443
links:
- php
Error:
$ sudo docker-compose up -d
Building php
ERROR: Cannot locate specified Dockerfile: Dockerfile
Docker is such as pain!
Any ideas how to fix this?
I would choose webdevops dockerized apache, because it has simple configuration:
version: '2'
services:
php:
build: php
expose:
- 9000
volumes:
- ./php/www:/var/www/html
apache2:
image: webdevops/apache:latest
args:
- PHP_SOCKET=php:9000
volumes:
- ./php/www:/var/www/html
ports:
- 80:80
- 443:443
links:
- php
Since the example above does not work, here is a different approach:
docker-compose.yml
version: '3.1'
services:
php:
image: php:apache
ports:
- 80:80
volumes:
- ./php/www:/var/www/html/
Launch the server with
docker-compose up
We need to create a new folders /php/www in current path
Create a file under php folder save as "Dockerfile" which contains as below without quote
"FROM php:5.6-apache
RUN docker-php-ext-install mysqli"
Copy your docker-compose.yml file in your current folder where your "php" folder has.
Create a sample file "index.php" under www folder (/php/www/index.php)
Run in command prompt docker-compose up -d
Open your browser type "localhost" you can see your sample file results.
Note: Above steps as per above mentioned docker-compose.yml file.
You can check this question.
If you use build instead of image, then you need "Dockerfile". Dockerfile would be use as configuration file for building image.
You maybe miss part in guide, where you should create file with name "Dockerfile" inside directory "php". Directory "php" must be in the same directory, where your "docker-compose.yml". In "docker-compose.yml" you have this line.
build: php
The line mean, that configuration file (by default: "Dockerfile") is inside of directory "php". So you should create directory "php" and file "Dockerfile" inside of it.
This is "Dockerfile" from your guide.
FROM php:5.6-apache
RUN docker-php-ext-install mysqli
docker-compose.yml reference version 2
Dockerfile reference
I found an elegant way to dynamically configure the ports and other parameters: In apache2's configuration files you can reference environment variables.
#/etc/apache2/ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
#APACHE_HTTP_PORT_NUMBER:80
#APACHE_HTTPS_PORT_NUMBER:443
Listen ${APACHE_HTTP_PORT_NUMBER}
<IfModule ssl_module>
Listen ${APACHE_HTTPS_PORT_NUMBER}
</IfModule>
<IfModule mod_gnutls.c>
Listen ${APACHE_HTTPS_PORT_NUMBER}
</IfModule>
you can set the variables in Dockerfile or docker-compose.yml
You can set a directory with diferente Dockerfiles an declare in each service:
...
image: php:custom
build:
context: .
dockerfile: ./dockerfiles/Dockerfile-php
...
I have created a working example of PHP, APACHE, MYSQL, and PHPMYADMIN for PHP developers. You may find it useful if you need the original old-school working style. Please note that I am using port 8080 for my website and port 8081 for PHPMyAdmin. You can change these as you like.
version: '3.8'
services:
php-apache-environment:
container_name: php-apache
image: php:7.4-apache
volumes:
- ./php/src:/var/www/html/
ports:
- 8080:80
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: ezapi
MYSQL_USER: root
MYSQL_PASSWORD: password
ports:
- "6033:3306"
volumes:
- dbdata:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
links:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_ARBITRARY: 1
restart: always
ports:
- 8081:80
volumes:
dbdata:

Categories