Skip to content

Instantly share code, notes, and snippets.

@jcavat
Last active February 25, 2024 13:58
Show Gist options
  • Save jcavat/2ed51c6371b9b488d6a940ba1049189b to your computer and use it in GitHub Desktop.
Save jcavat/2ed51c6371b9b488d6a940ba1049189b to your computer and use it in GitHub Desktop.
docker-compose with php/mysql/phpmyadmin/apache
Create this directories structure:
.
├── docker-compose.yml
├── Dockerfile
├── dump
│   └── myDb.sql
├── sessions
└── www
└── index.php
version: "2"
services:
www:
build: .
ports:
- "8001:80"
volumes:
- ./www:/var/www/html/
links:
- db
networks:
- default
db:
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: myDb
MYSQL_USER: user
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
volumes:
- ./dump:/docker-entrypoint-initdb.d
- persistent:/var/lib/mysql
networks:
- default
phpmyadmin:
image: phpmyadmin/phpmyadmin
links:
- db:db
ports:
- 8000:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
volumes:
persistent:
FROM php:7.1.2-apache
RUN docker-php-ext-install mysqli
<!-- put in ./www directory -->
<html>
<head>
<title>Hello...</title>
<meta charset="utf-8">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<?php echo "<h1>Hi! I'm happy</h1>"; ?>
<?php
$conn = mysqli_connect('db', 'user', 'test', "myDb");
$query = 'SELECT * From Person';
$result = mysqli_query($conn, $query);
echo '<table class="table table-striped">';
echo '<thead><tr><th></th><th>id</th><th>name</th></tr></thead>';
while($value = $result->fetch_array(MYSQLI_ASSOC)){
echo '<tr>';
echo '<td><a href="#"><span class="glyphicon glyphicon-search"></span></a></td>';
foreach($value as $element){
echo '<td>' . $element . '</td>';
}
echo '</tr>';
}
echo '</table>';
$result->close();
mysqli_close($conn);
?>
</div>
</body>
</html>
-- put in ./dump directory
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
CREATE TABLE `Person` (
`id` int(11) NOT NULL,
`name` varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `Person` (`id`, `name`) VALUES
(1, 'William'),
(2, 'Marc'),
(3, 'John');
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
@redigaffi
Copy link

In the SQL file you have to specify which database you want to use at the top:

CREATE DATABASE IF NOT EXISTS app; USE app;

If not it won't work (at least for me).

@MichaelPolla
Copy link

@redigaffi just tried it yet, it works out-of-the-box.
Here's what I did, in case you forgot something :

  • Cloned this gist,
  • Created the repository structure as explained in the readme,
  • Ran docker-compose up
  • Opened http://localhost:8001

What error message (if any) do you have ?

@publicJorn
Copy link

publicJorn commented Mar 26, 2018

@jcavat could you elaborate on what this does, at the bottom of docker-compose.yml?

volumes:
    persistent:

I suppose it has something todo with the persistent:/var/lib/mysql entry in db, but I'm not sure what I can/should do with it.

Also, what does the /sessions directory do?

@MichaelPolla
Copy link

MichaelPolla commented Apr 2, 2018

@publicJorn: the lines

volumes:
    persistent:

create a volume named persistent. Volumes are used to persist data used and generated by containers. You can read more about it in the documentation : "Manage data in Docker" and "Use volumes".

The line persistent:/var/lib/mysql mounts the persistent volume as /var/lib/mysql inside the db container. /var/lib/mysql is where MySQL by default will write its data files.

You can learn about this in the MySQL image description under the "Where to Store Data" section (bottom of the page).

Concerning the /sessions folder, I don't know why it's needed; it works without it. I'll ask @jcavat next time I see him :-)

I hope to have helped you a little. Have a nice day !

@sudamar
Copy link

sudamar commented May 28, 2018

Error at the connect with phpmyadmin: mysqli_real_connect(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name does not resolve

Error at the connect with http://localhost:8001/ : (403) You don't have permission to access / on this server.

@OmegaWolfProjects
Copy link

OmegaWolfProjects commented Jun 1, 2018

sudamar: I had the exact same problem as you. I solved it by using an older version of the software i.e. by doing the following:

Clean everything:

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker rmi my-old-docker-image
docker volume rm $(docker volume ls -q)

Dockerfile

I changed the Dockerfile to the following (using an older version):

FROM php:7.0.30-apache
RUN docker-php-ext-install mysqli

docker-compose.yml file

...and I changed the part of the docker-compose.yml file from:

db:
        image: mysql

To

db:
     image: mysql:5.7.13

Rebuild:

docker-compose up -d

Now wait about 20 seconds before trying to access the below webpages (I noticed that it takes some time for the mysql service to start up etc).

Now it you browse to http://192.168.1.106:8001/ and http://192.168.1.106:8000/index.php they both work (well they do for me now!)

@jotjot
Copy link

jotjot commented Jun 25, 2018

Although I really believe that the decision of the MySQL maintainers is wrong, I do believe that they are not going to change it back. So, I verified out how it can work without downgrading. It is a bit more of work, but needs to be done only once:

  1. Change the Dockerfile to read

FROM php:7.2.6-apache

  1. Bring everything up, then login into the mysql container:

$ docker exec -t -i container_mysql_name /bin/bash

  1. Change the password storage for the user of interest:

#mysql -uroot -p [isempty]
mysql> ALTER USER 'user' IDENTIFIED WITH mysql_native_password BY 'test';

  1. Change/Create all users you need with the option "mysql_native_password"

  2. logout

This works fine for me, as the mysql data is persistent, and you can use the latest versions of the packages.

@dileep021
Copy link

not able to login in to phpmyadmin
mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]

@danangt49
Copy link

not able to login in to phpmyadmin
mysqli_real_connect(): (HY000/2002): Operation timed out

@EmberRed
Copy link

newest version of mysql doesn't work.
downgrade to a mysql:5.7 or mariadb

@charan432
Copy link

@OmegaWolfProjects: Thank you for your comment. It solved half of my issues. I have followed all the steps given in the comment. Still, I can't access http://192.168.1.106:8001/. It is showing Forbidden access.

Then, I have run below command in my command shell

docker exec -it proj1_www_1 bash which enters into
root@c2b400b7164d:/var/www/html#

Here, When I tried to see list of files by using ls command. It is not showing any of the files like index.php (The directory is empty).

Please help me to fix this issue

Thanks
Sricharan

@Bargefull
Copy link

Bargefull commented Feb 24, 2019

Following your steps, i was able to connect :) But now i am trying to enable PDO_MYSQL instead of MYSQLI !

I add the line "RUN docker-php-ext-install pdo pdo_mysql" in "Dockerfile" but it still doesn't work ! i have the error "Erreur : could not find driver"

Any ideas ?
Thanks

@vigneshindn
Copy link

I got a error php-mysql module missing any solution please

@KirinFuji
Copy link

This is not working out of the box on the latest centos7 latest docker latest docker-compose:

ERROR: In file './docker-compose.yml', volume must be a mapping, not a NoneType.

@KirinFuji
Copy link

KirinFuji commented Apr 13, 2019

All I had to do was move:

volumes:
persistent:

From the bottom of the docker-compose.yml file
To the Top (above services: below version:) of the file as shown:

version: "2"

volumes:
persistent:

services:
................................

This got the container to build and run. But I am having issues apparently due to a default character set changing. I may work on this later really wanting to use this.

Warning: mysqli_connect(): Server sent charset (255) unknown to the client.
Warning: mysqli_connect(): (HY000/2054): Server sent charset unknown to the client.

https://bugs.mysql.com/bug.php?id=85946

@Jhessyjhordon
Copy link

can some one help me pls ?

I changed the Dockerfile to the following (using the new version):
FROM php:7.3-apache RUN docker-php-ext-install mysqli

...and I changed the part of the docker-compose.yml file from:
db: image: mysql
To
db: image: mysql:8.0

All this is in a virtual server (at host [1 & 1] (https://www.ionos.com/servers/vps)), a Linux server on Ubuntu that contains my Docker.

On this Docker I try to install a web server on which I will put websites and databases.

I chose to do this because I will need access to databases from a JAVA application. Something that would not be possible if I had chosen a simple web host instead of this virtual server.

The issue is when i run the docker-compose :
docker-compose up -d

I have this error :
ERROR: yaml.parser.ParserError: while parsing a block mapping in "./docker-compose.yml", line 3, column 5 expected <block end>, but found '<block mapping start>' in "./docker-compose.yml", line 15, column 9

I am a noob in docker, so can you guys help me to resolve that issue please ?

@kennblvnp
Copy link

I have this errors:

**Warning: mysqli_connect(): Server sent charset (255) unknown to the client. Please, report to the developers in /var/www/html/index.php on line 19

Warning: mysqli_connect(): (HY000/2054): Server sent charset unknown to the client. Please, report to the developers in /var/www/html/index.php on line 19

Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in /var/www/html/index.php on line 21

Fatal error: Uncaught Error: Call to a member function fetch_array() on null in /var/www/html/index.php:24 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 24**

@Beyarz
Copy link

Beyarz commented Jun 8, 2019

Version 8.0.4 & newer requires you to change to mysql_native_password, https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/

@Beyarz
Copy link

Beyarz commented Jun 8, 2019

The /sessions folder is completely unnecessary, I removed it.

@Beyarz
Copy link

Beyarz commented Jun 8, 2019

I made an updated version of this with plenty of fixes, https://gist.github.com/Beyarz/674b24d03614fde205a38f449800857a

@jcavat
Copy link
Author

jcavat commented Jun 17, 2019

Thanks !

@danon
Copy link

danon commented Jun 28, 2019

@Beyarz thanks

@Beyarz
Copy link

Beyarz commented Jun 28, 2019

@Beyarz thanks

No worries! It was a pain to get everything to work, I hope no one has to experience that again.

@CharlesDerek
Copy link

Although I really believe that the decision of the MySQL maintainers is wrong, I do believe that they are not going to change it back. So, I verified out how it can work without downgrading. It is a bit more of work, but needs to be done only once:

  1. Change the Dockerfile to read

FROM php:7.2.6-apache

  1. Bring everything up, then login into the mysql container:

$ docker exec -t -i container_mysql_name /bin/bash

  1. Change the password storage for the user of interest:

#mysql -uroot -p [isempty]
mysql> ALTER USER 'user' IDENTIFIED WITH mysql_native_password BY 'test';

  1. Change/Create all users you need with the option "mysql_native_password"
  2. logout

This works fine for me, as the mysql data is persistent, and you can use the latest versions of the packages.

I followed your instructions but when i try logging into mysql as root with
~ mysql -uroot -p
Attempt 1: (blank)
returned: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
Attempt 2: test (the password in yml file for root)
returned: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

Can't get into mysql directly to change settings as root.

@tjarbo
Copy link

tjarbo commented Nov 11, 2019

Although I really believe that the decision of the MySQL maintainers is wrong, I do believe that they are not going to change it back. So, I verified out how it can work without downgrading. It is a bit more of work, but needs to be done only once:

1. Change the Dockerfile to read

FROM php:7.2.6-apache

1. Bring everything up, then login into the mysql container:

$ docker exec -t -i container_mysql_name /bin/bash

1. Change the password storage for the user of interest:

#mysql -uroot -p [isempty]
mysql> ALTER USER 'user' IDENTIFIED WITH mysql_native_password BY 'test';

1. Change/Create all users you need with the option "mysql_native_password"

2. logout

This works fine for me, as the mysql data is persistent, and you can use the latest versions of the packages.

A other solution that works for me is to add following line into docker-compose.yml

db:
        ....
        command: mysqld --default-authentication-plugin=mysql_native_password
        .....

@goodboy761
Copy link

Hello, do you know how to configure additional password protection phpmyadmin at apache level?

@spoddar13
Copy link

Solved

Dockerfile -->
FROM php:8.0-apache
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
RUN apt-get update && apt-get upgrade -y

Docker-Composer-->
version: "2"
services:
www:
build: .
container_name: webhost
ports:
- "8001:80"
volumes:
- ./www:/var/www/html/
links:
- db
networks:
- default
db:
image: mysql
restart: always
container_name: DataBaseServer
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: myDb
MYSQL_USER: user
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
volumes:
- ./dump:/docker-entrypoint-initdb.d
- persistent:/var/lib/mysql
networks:
- default
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: PHP_MySQL
links:
- db:db
ports:
- 8000:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
volumes:
persistent:

@Alldbg
Copy link

Alldbg commented May 25, 2022

Bellow my fix to resolve connection issues ,

FROM php:7.2-apache
RUN a2enmod rewrite
RUN docker-php-ext-install pdo pdo_mysql
RUN apt-get update
&& apt upgrade -y
&& apt-get install -y libzip-dev
&& apt-get install -y zlib1g-dev
&& apt-get install -y iputils-ping
&& apt-get install -y mycli
&& rm -rf /var/lib/apt/lists/*
&& docker-php-ext-install zip
&& docker-php-ext-install mysqli
&& docker-php-ext-enable mysqli

@yohanes-ai
Copy link

yohanes-ai commented Nov 21, 2022

if someone had a problem with Laravel with an error
could not find driver (SQL: select * from

don't forget to add pdo pdo_mysql after RUN docker-php-ext-install

so it become

FROM php:8.0.2-apache 
RUN docker-php-ext-install mysqli pdo pdo_mysql

to Dockerfile

@adhirmndl
Copy link

where is access and error log path

@varaskkar
Copy link

Dockerfile

FROM php:8-apache

RUN apt-get update && apt-get upgrade -y
RUN apt-get install sudo unzip wget -y
RUN docker-php-ext-install mysqli
 
RUN a2enmod rewrite
RUN a2enmod ssl
RUN service apache2 restart
 
EXPOSE 80

docker-compose.yml

version: "3.6"
services:
    php:
        build: .
        restart: always
        ports:
            - "8080:80"
        volumes:
            - ./src:/var/www/html
            - ./log:/var/log/apache2
    mysql:
        image: mysql:8.0
        restart: always
        ports:
            - "3306:3306"
        command: --default-authentication-plugin=mysql_native_password
        environment:
            - MYSQL_DATABASE=myDb
            - MYSQL_USER=user
            - MYSQL_PASSWORD=test
            - MYSQL_ROOT_PASSWORD=test
        volumes:
            - ./dump:/docker-entrypoint-initdb.d
            - ./conf:/etc/mysql/conf.d
            - persistent:/var/lib/mysql
    phpmyadmin:
        image: phpmyadmin
        restart: always
        ports:
            - 8081:80
        environment:
            - PMA_HOST=mysql
volumes:
    persistent:

Create this structure:

├── docker-compose.yml
├── Dockerfile
├── /dump
│   └── myDb.sql
├── /log
└── /src
    └── index.php

And run "docker-compose up". Then go to localhost:8080 and you should see a table with the data loaded from the myDb.sql file.

You can also go to localhost:8081 and log in to the database with phpmyadmin.

Server: mysql
User: user
Password: test
Database: myDb

@asiandevs
Copy link

Hi @varaskkar - Thank you.

I think, a small correction. Tree structure would be for this one is as below —

Before executing docker-compose [no need to create directory | or if you create then not "/"]
[root@ip-10-0-8-114 ~]# tree dockercompose03
dockercompose03
├── conf
├── docker-compose.yml
├── dockerfile
├── dump
│ └── myDb.sql
└── www
└── index.php

After executing docker-compose up
[root@ip-10-0-8-114 ~]# tree dockercompose03
dockercompose03
├── conf
├── docker-compose.yml
├── dockerfile
├── dump
│ └── myDb.sql
├── log
│ ├── access.log
│ ├── error.log
│ └── other_vhosts_access.log
├── src
└── www
└── index.php

5 directories, 7 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment