My goal is that running a PHP script with Docker compose.
I somehow found how to execute a PHP example script using Dockerfile like the following.
$ ls
Dockerfile test.php
$ cat Dockerfile
FROM php:7.0-cli
COPY ./test.php /tmp
WORKDIR /tmp
CMD [ "php", "./test.php" ]
$ cat test.php
<?php
phpinfo();
$ docker build -t my-php-app .
$ docker run -it --rm --name my-running-app my-php-app
https://docs.docker.com/samples/library/php/
I'm looking into how to connect into MySQL from the PHP script.
Any help will be helpful for me.
Update 1
I had little progress. I was able to connect to the container of mysql from PHP container.
$ cat index.php
<?php
$mysqli = new mysqli("database", "admin", "12dlql*41");
echo $mysqli->server_info;
$ docker run -d --name database -e MYSQL_USER=admin -e MYSQL_PASSWORD=12dlql*41 -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql:latest
$ docker run --rm -v $(pwd):/app -w /app --link database tommylau/php php index.php
5.7.21
https://www.shiphp.com/blog/2017/php-mysql-docker
Update 2
Thanks to everyone I was able to find the way.
Dockerfile
FROM php:7.1.9-fpm
RUN apt-get update \
&& docker-php-ext-install pdo_mysql mysqli
RUN apt-get update \
&& apt-get install -y libmemcached-dev zlib1g-dev \
&& pecl install memcached-3.0.3 \
&& docker-php-ext-enable memcached opcache
docker-compose.yml
version: '3.4'
services:
myapp_memcached:
image: memcached:latest
container_name: memcached
myapp_mysql:
image: mysql:latest
container_name: database
volumes:
- ./docker/:/etc/mysql/conf.d
- ./docker/:/docker-entrypoint-initdb.d
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=true
- MYSQL_DATABASE=counterparty
- MYSQL_USER=admin
- MYSQL_PASSWORD=12dlql*41
myapp_php:
build: .
container_name: myapp
working_dir: /app
volumes:
- ./:/app
external_links:
- database
- memcached
You should set up a docker-compose.yml file, which would interconnect your containers into one network.
For example:
version: '3.4'
myapp_php:
build: ./Dockerfile
container_name: myapp_php
myapp_mysql:
image: mysql:latest
container_name: myapp_mysql
environment:
- MYSQL_ROOT_PASSWORD=somerandompassword
- MYSQL_DATABASE=database
- MYSQL_USER=admin
- MYSQL_PASSWORD=12dlql*41
Now when you run docker-compose up -d, the stack should be up with mysql having pre-set a database with your credentials.
Related
I started my Symfony 6 project with Docker successfully.
I have a problem when accessing the PHP container and trying to run php bin/console doctrine:migrations.
The error:
Could not open input file: bin/console
My steps:
docker ps //checked php container name
docker exec -it php_container_name /bin/bash //entered with success
Then I am in container like;
root#2a9a3e61c23b:/var/www/html#
And when entering the above command, the error above is shown.
Docker file:
FROM php:8.1-fpm
RUN apt-get update && apt-get install -y \
git \
unzip \
libicu-dev \
libpq-dev \
wget
# Installing Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && composer --version
RUN apt-get -y install cron default-mysql-client
RUN docker-php-ext-install pdo pdo_mysql pdo_pgsql
and docker .yml file:
version: '3'
services:
nginx:
image: nginx:1.17
ports:
- "80:80"
volumes:
- "./docker-configs/nginx.conf:/etc/nginx/conf.d/default.conf"
- ".:/app:cached"
php:
build:
context: ./docker-configs/php
volumes:
- "./docker-configs/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
- ".:/app:cached"
environment:
PHP_IDE_CONFIG: "serverName=Docker"
db:
image: mysql:5.7
platform: linux/amd64
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: db
MYSQL_USER: root
MYSQL_PASSWORD: root
ports:
- 3306:3306
volumes:
- ./mysql-data:/var/lib/mysql
postgresdata:
I am writing a small pet project and using docker
I am using PHP-CLI, PHP-FPM and PGSQL - apline.
Below is the configuration
php-cli Dockerfile
FROM php:8.0-cli-alpine
RUN apk add --no-cache autoconf g++ make
#install PG
RUN apk add --no-cache postgresql-dev bash coreutils \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
RUN apk add --no-cache unzip
RUN docker-php-ext-install pdo_pgsql pcntl opcache
RUN docker-php-ext-install bcmath fileinfo
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/bin --filename=composer --quiet
WORKDIR /app
PHP-fpm dockerfile
FROM php:8.0-fpm-alpine
#install PG
RUN apk add --no-cache postgresql-dev bash coreutils \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
#enable extensions
RUN docker-php-ext-install pdo_pgsql opcache bcmath fileinfo
WORKDIR /app
docker-compose.yaml file
version: '3.8'
services:
nginx:
container_name: seln_nginx_dev-container
image: nginx
volumes:
- ./docker/nginx/:/etc/nginx/conf.d
- ./:/app
links:
- php-fpm
ports:
- '8000:80'
php-fpm:
container_name: seln_php-fpm-container
build:
context: docker
dockerfile: php-fpm/Dockerfile
environment:
DB_HOST: api-postgres
DB_USER: app
DB_PASSWORD: secret
DB_NAME: app
ports:
- 8080:8080
volumes:
- ./:/app
working_dir: /app
php-cli:
container_name: seln_php-cli-container
build:
context: docker
dockerfile: php-cli/Dockerfile
environment:
DB_HOST: api-postgres
DB_USER: app
DB_PASSWORD: secret
DB_NAME: app
volumes:
- ./:/app
api-postgres:
image: postgres:13.1-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: app
ports:
- "127.0.0.1:5432:5432"
And Makefile
init: down build up composer-install init-db
up:
docker-compose -f docker-compose.yaml up -d
down:
docker-compose -f docker-compose.yaml down -v --remove-orphans
composer-install:
docker-compose -f docker-compose.yaml run --rm php-cli composer install
composer-update:
docker-compose -f docker-compose.yaml run --rm php-cli composer update
build:
docker-compose -f docker-compose.yaml build
init-db:
docker-compose -f docker-compose.yaml run --rm php-cli vendor/bin/doctrine orm:schema-tool:drop --force && \
docker-compose -f docker-compose.yaml run --rm php-cli vendor/bin/doctrine orm:schema-tool:create
clear-cache:
docker-compose -f docker-compose.yaml run --rm php-cli vendor/bin/doctrine orm:clear-cache:metadata && \
docker-compose -f docker-compose.yaml run --rm php-cli vendor/bin/doctrine orm:clear-cache:query
What I am running into, when trying to build docker to work, I get an error use make init command
make: /bin/sh: Operation not permitted
make: *** [Makefile:209: pdo_pgsql.lo] Error 127
The command '/bin/sh -c docker-php-ext-install pdo_pgsql opcache bcmath fileinfo' returned a non-zero code: 2
ERROR: Service 'php-fpm' failed to build : Build failed
what is the reason for this error?
P>S - I managed to fix the error(use FROM php:8.0-cli-alpine3.13), but this solution does not suit me, I want to understand the reason, before the Ubuntu update, I could collect images without crutches, what could have changed in two weeks?
I've built a docker-compose file that creates 2 services (PHP and MariaDB). Somehow I cannot connect to the database from the PHP service: Within the PHP service, a Laravel-app is running.
The error message (redirect is a table within the database):
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from redirects)
All env-variables should be correct.
Here is my docker-compose.yml:
version: "3.7"
services:
faaren_backend:
image: php:alpine
container_name: FAA-Backend
volumes:
- "./:/faaren_backend"
working_dir: /faaren_backend
command: "php artisan serve --host=0.0.0.0 --port=8000"
ports:
- 8000:8000
build:
context: docker/php
dockerfile: dev.Dockerfile
faaren_database:
image: mariadb
container_name: FAA-Database
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_DATABASE: ${DB_DATABASE}
volumes:
- "faa-db-data:/var/lib/mysql/data"
volumes:
faa-db-data: {}
My dev.Dockerfile
FROM php:7.3-fpm
RUN apt-get update
RUN apt-get update && apt-get install -y libzip-dev \
&& docker-php-ext-install zip
RUN apt-get update && apt-get install -y libmagickwand-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN pecl install imagick
RUN docker-php-ext-enable imagick
RUN apt-get install $PHPIZE_DEPS && \
pecl install xdebug && docker-php-ext-enable xdebug && \
docker-php-ext-install pdo_mysql pcntl
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
VOLUME /faaren_backend
And finally my .env-file:
DB_CONNECTION=mysql
DB_HOST=faaren_backend
DB_PORT=3306
DB_DATABASE=faaren_db
DB_USERNAME=root
DB_PASSWORD=
Mostly I've followed this tutorial: https://medium.com/swlh/laravel-with-docker-compose-de2190569084
You need change your docker database host:
DB_CONNECTION=mysql
DB_HOST=faaren_database <-- edit
DB_PORT=3306
DB_DATABASE=faaren_db
DB_USERNAME=root
DB_PASSWORD=
And in docker-compose.yml faaren_backend section add:
depends_on:
- faaren_database
Hope it's help.
Looks like you deal with a race condition. You need to use depends_on directive to control startup order and use wait script to make sure that service ready to accept connections:
version: "3.7"
services:
faaren_backend:
image: php:alpine
container_name: FAA-Backend
volumes:
- "./:/faaren_backend"
working_dir: /faaren_backend
command: entrypoint.sh
ports:
- 8000:8000
depends_on:
- faaren_database
build:
context: docker/php
dockerfile: dev.Dockerfile
faaren_database:
image: mariadb
container_name: FAA-Database
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_DATABASE: ${DB_DATABASE}
volumes:
- "faa-db-data:/var/lib/mysql/data"
volumes:
faa-db-data: {}
There are a bunch of ways to check service availability, sometimes wait-for-it can be really handy. In the example below used netcat(you need to install it into the container).
Also, it'a good idea to put a script into a separated file:
entrypoint.sh
#!/usr/bin/env bash
until nc -w 1 -z faaren_database 3306; do
>&2 echo "Mysql is unavailable - sleeping"
sleep 1
done
sleep 10
>&2 echo "Mysql is up - executing command"
php artisan serve --host=0.0.0.0 --port=8000
UPDATE: Specify correct DB_HOST how Dmitry suggested as well.
I'm learning docker and was trying to set up the environment for a Symfony project. It works well until I added the migration and fixtures creation commands to entrypoint.sh. Now the php container will exit with code 0 after running all the commands in entrypoint.sh. Can someone help me with this?
Here is my setup:
docker-compose.yaml
version: "3.7"
services:
nginx:
image: nginx:alpine
ports:
- ${NGINX_HOST_PORT}:80
volumes:
- ./public:/var/www/symfony/public
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
build:
context: .
dockerfile: docker/php/Dockerfile
volumes:
- symfony:/var/www/symfony:delegated
depends_on:
- mysql
- redis
- composer
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
redis:
image: redis:alpine
composer:
image: composer:latest
command: install
volumes:
- symfony:/app
mysql:
image: mysql:latest
command: --default-authentication-plugin=mysql_native_password
ports:
- ${MYSQL_HOST_PORT}:3306
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
volumes:
symfony:
# driver: local
# driver_opts:
# type: none
# o: bind
# device: ${PWD}:${PWD}
driver: local
driver_opts:
type: nfs
o: addr=host.docker.internal,rw,nolock,hard,nointr,nfsvers=3
device: ${PWD}:${PWD}
Dockerfile for php container:
FROM php:7.3-fpm-alpine
ENV APP_DEPENDENCIES \
curl \
vim \
git
ENV PHP_EXTENSIONS \
pdo_mysql
ENV PECL_EXTENSIONS \
xdebug \
redis
RUN apk add --no-cache ${APP_DEPENDENCIES} ${PHPIZE_DEPS} && \
docker-php-ext-install ${PHP_EXTENSIONS} && \
pecl install ${PECL_EXTENSIONS} && \
docker-php-ext-enable ${PECL_EXTENSIONS}
COPY ./ /var/www/symfony
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
CMD ["/usr/local/bin/entrypoint.sh"]
entrypoint.sh:
#!/bin/sh
APP_PATH="/var/www/symfony"
echo "applying db migrations"
${APP_PATH}/bin/console doctrine:migrations:migrate first
${APP_PATH}/bin/console doctrine:migrations:migrate
${APP_PATH}/bin/console doctrine:fixtures:load
First thing, The container will die when it executes the entrypoint script as there is no process the keep the container running in entrypoint. There should always be a process that will keep running so the container will not die.
Second thing, you are not starting php-fpm in the entrypoint so as the result your container will not start PHP in the container.
update your entrypoint.
#!/bin/sh
APP_PATH="/var/www/symfony"
echo "all params $#"
echo "applying db migrations"
${APP_PATH}/bin/console doctrine:migrations:migrate first
${APP_PATH}/bin/console doctrine:migrations:migrate
${APP_PATH}/bin/console doctrine:fixtures:load
echo "starting php-fpm"
exec $#
update CMD in the Dockerfile
CMD ["/usr/local/bin/entrypoint.sh","php-fpm","-F"]
I am trying to run my laravel application inside docker containers on my laptop (during development) and finding that the speed of the application is drastically slow when compared to running it using XAMPP for example.
My laptop is running Windows 10 Pro (64-Bit) with i7-6700HQ CPU, 16 GB RAM and SSD.
When I run my app in docker for windows, average page load time is approx 3.5 Seconds.
Running it on local XAMPP, average page load time is approx 350 Milliseconds (0.35 Second).
For my docker setup, I use the following image/Dockerfile:
FROM alpine:3.8
MAINTAINER Latheesan Kanesamoorthy
RUN apk add \
--no-cache \
--update \
apache2 \
composer \
curl \
php7 \
php7-apache2 \
php7-curl \
php7-bcmath \
php7-dom \
php7-mbstring \
php7-pdo_mysql \
php7-session \
php7-sockets \
php7-tokenizer \
php7-xml \
php7-xmlwriter \
php7-fileinfo \
&& mkdir -p /run/apache2 \
&& ln -sf /dev/stdout /var/log/apache2/access.log \
&& ln -sf /dev/stderr /var/log/apache2/error.log
COPY ./image/*.conf /etc/apache2/conf.d/
COPY ./image/php.ini /etc/php7/conf.d/99_custom.ini
RUN mkdir -p /storage/framework/testing
RUN mkdir -p /storage/framework/views
RUN mkdir -p /storage/framework/sessions
RUN mkdir -p /storage/framework/cache/data
RUN chown -R apache:apache /storage
WORKDIR /app
COPY ./src/composer.* ./
RUN composer install -n --no-autoloader --no-scripts --no-progress --no-suggest
COPY src .
RUN composer dump-autoload -o -n
EXPOSE 80
and docker-compose.yml:
version: '2.1'
services:
mysql:
container_name: myapp-mysql
mem_limit: 512M
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: myapp
MYSQL_DATABASE: myapp
MYSQL_USER: myapp
MYSQL_PASSWORD: myapp
ports:
- "35000:3306"
redis:
container_name: myapp-redis
image: redis:latest
redis-commander:
container_name: myapp-redis-commander
image: rediscommander/redis-commander:latest
hostname: redis-commander
restart: always
environment:
- REDIS_HOSTS=local:redis:6379
ports:
- "7050:8081"
links:
- redis
app:
container_name: myapp-app
mem_limit: 512M
build:
context: ""
dockerfile: image/Dockerfile
env_file:
- image/env/development
volumes:
- ./src:/app:cached
ports:
- "25000:80"
entrypoint: httpd -DFOREGROUND
links:
- mysql
- redis
and I use the following commands to boot it up:
docker-compose down --remove-orphans
docker-compose up -d --build
docker exec myapp-app composer install --prefer-dist --no-suggest
docker exec myapp-app php artisan cache:clear
docker exec myapp-app php artisan migrate:fresh --seed
As you can see, the docker version uses redis as the driver for: cache, eloquent model cache, queue and session.
Locally for XAMPP, I am simply using file driver for all.
Any idea why the performance is so slow on docker?
P.S. The reason why I want to try developing using the docker environment is so that I can keep my development and production environment identical.