diff --git a/README.md b/README.md index e3a465b..21ed569 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,9 @@ application with a Node.js backend and a Mongo database. - [`React / Rust / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/react-rust-postgres) - Sample React application with a Rust backend and a Postgres database. - [`Spring / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/spring-postgres) - Sample Java application -with Spring framework and a Postgres database. +with Spring framework and a Postgres database. +- [`PHP / MySQL / Apache`](https://github.com/docker/awesome-compose/tree/master/php-mysql-apache) - Sample PHP application +with MySQL database. ## Single service samples - [`Angular`](https://github.com/docker/awesome-compose/tree/master/angular) - [`Spark`](https://github.com/docker/awesome-compose/tree/master/sparkjava) diff --git a/php-mysql-apache/README.md b/php-mysql-apache/README.md new file mode 100644 index 0000000..601ae83 --- /dev/null +++ b/php-mysql-apache/README.md @@ -0,0 +1,126 @@ +## Compose sample application +### PHP and MySQL application with Apache2 + +Project structure: +``` +. +├── docker-compose.yaml +├── mysql +│ └── Dockerfile +├── php +│ ├── Dockerfile +│ ├── index.php +│ └── query.php +└── README.md + +``` + +[_docker-compose.yaml_](docker-compose.yaml) +``` +services: + + php: + image: php:8.0-apache + build: php + container_name: php_container + networks: + pm_net: + ipv4_address: 172.17.0.2 + ports: + - 8000:80 + volumes: + - ./php:/var/www/html/ + command: > + bash -c "apt-get update && + docker-php-ext-install pdo_mysql && + docker-php-ext-enable pdo_mysql && + apache2-foreground" + + db: + image: mysql + build: mysql + container_name: mysql_container + networks: + pm_net: + ipv4_address: 172.17.0.3 + ports: + - 8001:3306 + - 8002:33060 + volumes: + - ./mysql:/var/www/mysql + environment: + MYSQL_USERNAME: "root" + MYSQL_ROOT_PASSWORD: "" + MYSQL_ALLOW_EMPTY_PASSWORD: "true" + depends_on: + - php + + pma: + image: phpmyadmin + container_name: pma_container + networks: + pm_net: + ipv4_address: 172.17.0.4 + ports: + - 8003:80 + depends_on: + - db + +networks: + pm_net: + driver: bridge + ipam: + config: + - subnet: 172.17.0.0/16 + gateway: 172.17.0.5 +``` +#### docker-compose file description + +We have three services (containers) in docker-compose, PHP 8.0 with Apache web server, MySQL database, and PhpMyAdmin. + +These containers are going to connect together via `pm_net (bridge)` network. +Each of these have their own static IPs. Of course their ports are exposed to be accessed later. + +Note that we have a `command` attribute in `php` service. This command tells the container to install `pdo_mysql` PHP extension to deal with MySQL through PHP by `PDO` Class. Running the command is important if you are using `PDO` class to access the database. + + +## Deploy with docker-compose + +``` +$ docker-compose up -d +Creating network "php-mysql-apache_pm_net" with driver "bridge" +Creating php_container ... done +Creating mysql_container ... done +Creating pma_container ... done +Attaching to php_container, mysql_container, pma_container +... +... +``` + +**Important: Running `docker-compose up` may take a few moments to start, due to installing `pdo_mysql` extension. So be patient.** + +## Expected result + +Listing containers must show three containers running and the port mapping as below: +``` +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +edb55669d222 phpmyadmin "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8003->80/tcp, :::8003->80/tcp pma_container +14359ec051f8 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8001->3306/tcp, :::8001->3306/tcp, 0.0.0.0:8002->33060/tcp, :::8002->33060/tcp mysql_container +bc2d05ab3dc2 php:8.0-apache "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp, :::8000->80/tcp php_container +``` + +After the application starts, navigate to `http://localhost:8000` in your web browser to run `index.php` file or run: +``` +$ curl localhost:8000 +Hello World +``` + +You see that it's just a simple Hello-world string, but some queries happens under the hood. First the application connects to MySQL with `pdo_mysql` php extension, after that, it checks the database if `MyDatabase` exists or not. Then creates a table, inserts data as `Hello world` into it, and PHP application fetches the data and shows the output by the browser. + +If you want to access `PhpMyAdmin` navigate to `http://localhost:8003` in your browser. + +Stop and remove the containers +``` +$ docker-compose down +``` diff --git a/php-mysql-apache/docker-compose.yaml b/php-mysql-apache/docker-compose.yaml new file mode 100644 index 0000000..2dd3828 --- /dev/null +++ b/php-mysql-apache/docker-compose.yaml @@ -0,0 +1,58 @@ +version: "3.7" + +services: + + php: + image: php:8.0-apache + build: php + container_name: php_container + networks: + pm_net: + ipv4_address: 172.17.0.2 + ports: + - 8000:80 + volumes: + - ./php:/var/www/html/ + command: > + bash -c "apt-get update && + docker-php-ext-install pdo_mysql && + docker-php-ext-enable pdo_mysql && + apache2-foreground" + + db: + image: mysql + build: mysql + container_name: mysql_container + networks: + pm_net: + ipv4_address: 172.17.0.3 + ports: + - 8001:3306 + - 8002:33060 + volumes: + - ./mysql:/var/www/mysql + environment: + MYSQL_USERNAME: "root" + MYSQL_ROOT_PASSWORD: "" + MYSQL_ALLOW_EMPTY_PASSWORD: "true" + depends_on: + - php + + pma: + image: phpmyadmin + container_name: pma_container + networks: + pm_net: + ipv4_address: 172.17.0.4 + ports: + - 8003:80 + depends_on: + - db + +networks: + pm_net: + driver: bridge + ipam: + config: + - subnet: 172.17.0.0/16 + gateway: 172.17.0.5 \ No newline at end of file diff --git a/php-mysql-apache/mysql/Dockerfile b/php-mysql-apache/mysql/Dockerfile new file mode 100644 index 0000000..ab50cb5 --- /dev/null +++ b/php-mysql-apache/mysql/Dockerfile @@ -0,0 +1,6 @@ +FROM mysql + +COPY . /var/www/mysql + +EXPOSE 3306 +EXPOSE 33060 \ No newline at end of file diff --git a/php-mysql-apache/php/Dockerfile b/php-mysql-apache/php/Dockerfile new file mode 100644 index 0000000..46c58dc --- /dev/null +++ b/php-mysql-apache/php/Dockerfile @@ -0,0 +1,5 @@ +FROM php:8.0-apache + +COPY . /var/www/html + +EXPOSE 80 \ No newline at end of file diff --git a/php-mysql-apache/php/index.php b/php-mysql-apache/php/index.php new file mode 100644 index 0000000..28614da --- /dev/null +++ b/php-mysql-apache/php/index.php @@ -0,0 +1,26 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + + + + /** + * Create a new database called `MyDatabase` if does not exist + */ + $pdo->exec("CREATE DATABASE IF NOT EXISTS MyDatabase"); + + + + + /** + * Use the database we created + */ + $pdo->exec("USE MyDatabase"); + + + + + /** + * Check if the `test` table exists before + * If not, creates a new one + */ + $stmt = $pdo->prepare("SHOW TABLES LIKE 'test'"); + $stmt->execute(); + + if ($stmt->rowCount() == 0) { + $stmt = $pdo->prepare("CREATE TABLE test (column1 VARCHAR (255) )"); + $stmt->execute(); + } + + + + + /** + * Insert a sample data `Hello world` into table + */ + $stmt = $pdo->prepare("INSERT INTO test (column1) VALUES ('Hello world')"); + $stmt->execute(); + + + + + /** + * Fetch the data we inserted + */ + $stmt = $pdo->prepare("SELECT * FROM test LIMIT 1"); + $stmt->execute(); + + $result = $stmt->fetchAll(PDO::FETCH_ASSOC); + + + + + /** + * Show the data as string + */ + echo $result[0]['column1']; +} \ No newline at end of file