php container keeps restarting using docker-compose - php

I have the following docker-compose file. When I try to up the file the mysql container start, but the php one keeps on restarting. When I look at the logs all I get is "interactive shell" constantly. Any idea why this is happening?
---
version: "3"
services:
web:
image: php:alpine3.12
restart: unless-stopped
volumes:
- web_Data:/var/www/html
ports:
- 80:80
- 443:443
mariadb:
image: mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: Password1
volumes:
- mariadb_Data:/var/lib/mysql
ports:
- 3306:3306
volumes:
web_Data:
mariadb_Data:
driver: local

The reason you are getting Interactive shell message it's because that's an output of php:alpine3.12 image and since your container is constantly restarting, it keeps logging that message.
I don't really know PHP but it looks like the command that the image tries to do is docker-php-entrypoint php -a, and that starts an interactive shell, am I right?
If that is the case, then you need to run it in interactive mode. To do that, in docker-compose.yml file, just add the last 2 lines:
web:
image: php:alpine3.12
restart: unless-stopped
volumes:
- web_Data:/var/www/html
ports:
- 80:80
- 443:443
stdin_open: true
tty: true
Then your container will keep running and you will be able to interact with it.

The reason is that you are using an inappropriate PHP image. If you want to run PHP with a web server then you should use one of:
php:<version>-fpm
php:<version>-apache
See Image Variants in the Docker documentation.

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

Why docker not syncing files inside container on Windows 10?

I have issue after last docker update (seems so) on Windows 10 (local development). When I changed files in PhpStorm (and in another editors - Sublime, Notepad+), after a while, files inside container didn't receive changes.
Steps that can help for a while:
If I completely shut down all containers and after that arise them again. docker-compose down && docker-compoes up
If I get into php-fpm container and for file that not changed ran touch file.php (this file will be immidiatly changed).
What I tried and it didn't help:
I restarted php-fpm and nginx containers docker-compose restart php-fpm nginx (Yes it's strange, because down|up for all container helped)
I changed inside PhpStorm setting Use Safe write(save changes for temporary file first)
Also I checked inode for file inside container. With ls -lai file.php. Before changes worked and after they broked I had the same inode number. There is no determined number of changes I must to do to break syncing, it's random, sometime 2 changes enough.
I have:
Docker version 19.03.5, build 633a0ea
docker-compose version 1.25.2, build 698e2846
docker-compose.yml
version: '3'
services:
nginx:
container_name: pr_kpi-nginx
build:
context: ./
dockerfile: docker/nginx.docker
volumes:
- ./:/var/www/kpi
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/fastcgi.conf:/etc/nginx/fastcgi.conf
ports:
- "8081:80"
links:
- php-fpm
networks:
- internal
php-fpm:
container_name: pr_kpi-php-fpm
build:
context: ./
dockerfile: docker/php-fpm.docker
volumes:
- ./:/var/www/kpi
links:
- kpi-mysql
environment:
# 192.168.221.1 -> host.docker.internal for Mac and Windows
XDEBUG_CONFIG: "remote_host=host.docker.internal remote_enable=1"
PHP_IDE_CONFIG: "serverName=Docker"
networks:
- internal
mailhog:
container_name: pr_kpi-mailhog
image: mailhog/mailhog
restart: always
ports:
# smtp
- "1025:1025"
# http
- "8025:8025"
networks:
- internal
kpi-mysql:
container_name: pr_kpi-kpi-mysql
image: mysql:5.7
command: mysqld --sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
volumes:
- ./docker/storage/kpi-mysql:/var/lib/mysql
environment:
# We must change prod secrets, this is not good approach
- "MYSQL_ROOT_PASSWORD=pass"
- "MYSQL_USER=user"
- "MYSQL_PASSWORD=user_pass"
- "MYSQL_DATABASE=kpi_db"
ports:
- "33061:3306"
networks:
- internal
kpi-npm:
container_name: pr_kpi-npm
build:
context: ./
dockerfile: docker/npm.docker
volumes:
- ./:/var/www/kpi
- /var/www/kpi/admin/node_modules
ports:
- "4200:4200"
networks:
- internal
tty: true
# For xdebug
networks:
internal:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.221.0/28
P.S. There is opened issue:
https://github.com/docker/for-win/issues/5530
P.P.S. We need to update Docker from 2.2.0.0 to 2.2.0.3, Seems it's fixed
I have a separate container for syncing my folder:
app:
image: httpd:2.4.38
volumes:
- ./:/var/www/html
command: "echo true"
I just use the basic apache image, you could use anything really though. Then in my actual containers, I use the following volumes_from key:
awesome.scot:
build: ./build/httpd
links:
- php
ports:
- 80:80
- 443:443
volumes_from:
- app
php:
build: ./build/php
ports:
- 9000
- 9001
volumes_from:
- app
links:
- mariadb
- mail
environment:
APPLICATION_ENV: 'development'
I've never had an issue using this set up, files always sync fast, and I have tested both on Mac OSX and MS Windows.
If you're interested, here is my full LAMP stack on Github https://github.com/delboy1978uk/lamp
I have the same issue on Windows10 since 31st Jan.
I have commented a line in PhpStorm and checked it in the container using vim.
The changes were not there.
If I run docker-compose down and up, the changes go in the container.
Docker version 19.03.5, build 633a0ea
docker-compose version 1.25.4, build 8d51620a
Nothing changed in my docker-compose.yml since 2018.

How to run linux daemon in container linked to another container with docker-compose?

I have the following docker-compose.yml file which runs nginx with PHP support:
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
The PHP application inside /var/www/my-app needs to communicate with a linux daemon (let's call it myappd).
The way I see it, I need to either:
Copy the myappd into the nginx container to /usr/local/bin, make it executable with chmod +x and run it in the background.
Create a different container, copy myappd to /usr/local/bin, make it executable with chmod +x and run it in the foreground.
Now, I'm new to Docker and I'm researching and learning about it but my best guess, given that I'm using Docker Composer, is that option 2 is probably the recommended one? Given my limited knowledge about Docker, I'd have to guess that this container would require some sort of linux-based image (like Ubuntu or something) to run this binary. So maybe option 1 is preferred? Or maybe option 2 is possible with a minimal Ubuntu image or maybe it's possible without such image?
Either way, I have no idea how would I implement that on the composer file. Especially option 2, how would the PHP application communicate with the daemon in a different container? Just "sharing" a volume (where the binary is located) like I did for nginx/php services would suffice? Or something else is required?
Simple answer is adding command entry to php service in docker-compose.yml.
Given that myappd is at ./my-app/ on host machine and at /var/www/my-app/, updated docker-compose.yml is something like following.
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
command: ["/bin/sh", "/var/www/my-app/mappd", "&&", "php-fpm"]
Better answer is to create the third container which runs linux daemon.
New Dockerfile is something like following.
FROM debian:jessie
COPY ./myappd /usr/src/app/
EXPOSE 44444
ENTRYPOINT ['/bin/sh']
CMD ['/usr/src/app/myappd']
Build image and name it myapp/myappd.
Updated docker-compose.yml is something like following.
version: '3'
services:
nginx:
container_name: my-app-nginx
image: nginx:1.13.6
ports:
- 8080:80
volumes:
- ./nginx-default.conf:/etc/nginx/conf.d/default.conf
- ./my-app:/var/www/my-app
restart: always
depends_on:
- php
php:
container_name: my-app-php
image: php:7.1-fpm
volumes:
- ./my-app:/var/www/my-app
restart: always
networks:
- network1
depends_on:
- daemon
daemon:
container_name: my-app-daemon
image: myapp/myappd
restart: always
networks:
- network1
networks:
network1:
You can send request with hostname daemon from inside php. Docker container has capability to resolve hostname of another container in the same network.

Copying bin files to docker container leads to error

I'm trying to setup a docker-compose system where I'd like to copy dev tools to /usr/local/bin/ on startup.
Thats my docker-compose.yml:
version: '3'
services:
web:
build: docker/container/nginx
ports:
- 4000:80
volumes: &m2volume
- ./src:/var/www/html/
- ./docker/data/bin/:/usr/local/bin/
- ~/.composer:/var/www/.composer
networks: &m2network
- www
links:
- "php"
- "mariadb:mysql"
mariadb:
image: mariadb
ports:
- 8001:3306
networks: *m2network
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: magento2
MYSQL_DATABASE: db
MYSQL_USER: magento2
MYSQL_PASSWORD: magento2
volumes:
- ./docker/container/db/docker-entrypoint-initdb.d/:/docker-entrypoint-initdb.d/
- ./docker/container/db/conf.d:/etc/mysql/conf.d
- ./docker/data/mariadb:/var/lib/mysql
php:
build: docker/container/fpm
volumes: *m2volume
networks: *m2network
networks:
www:
if I leave - ./docker/data/bin/:/usr/local/bin/ in it, I get an error:
ERROR: for m2_php_1 Cannot start service php: oci runtime error: container_linux.go:262: starting container process caused "exec: \"docker-php-entrypoint\": executable file not found in $PATH"
Starting m2_mariadb_1 ... done
ERROR: for php Cannot start service php: oci runtime error: container_linux.go:262: starting container process caused "exec: \"docker-php-entrypoint\": executable file not found in $PATH"
If I uncomment it, all works fine.
What am I doing wrong here?
If i understand this correctly, and mapping the volume ./docker/data/bin/:/usr/local/bin/ is causing an exception, then that's probably because of the entrypoint defined in the mariadb image.
More to the point, you're overwriting the /usr/local/bin container folder, which probably contains an executable used in the entrypoint. When that disappears, you get an error.

Docker, referencing a different container. Call mysqldump using php command

I've got a database backup bundle (https://github.com/dizda/CloudBackupBundle) installed on a Symfony3 project using Docker, but I can't get it to work due to it either not finding PHP or not finding MySQL
When I run php app/console --env=prod dizda:backup:start via exec, run, or via cron. I get mysqldump command not found error through the PHP image, or PHP not found error from the Mysql/db image.
How do I go about running a php command that then runs a mysqldump command.
My docker-compose file is as follows:
version: '2'
services:
web:
# image: nginx:latest
build: .
restart: always
ports:
- "80:80"
volumes:
- .:/usr/share/nginx/html
links:
- php
- db
- node
volumes_from:
- php
volumes:
- ./logs/nginx/:/var/log/nginx
php:
# image: php:fpm
restart: always
build: ./docker_setup/php
links:
- redis
expose:
- 9000
volumes:
- .:/usr/share/nginx/html
db:
image: mysql:5.7
volumes:
- "/var/lib/mysql"
restart: always
ports:
- 8001:3306
environment:
MYSQL_ROOT_PASSWORD: gfxhae671
MYSQL_DATABASE: boxstat_db_live
MYSQL_USER: boxstat_live
MYSQL_PASSWORD: GfXhAe^7!
node:
# image: //digitallyseamless/nodejs-bower-grunt:5
build: ./docker_setup/node
volumes_from:
- php
redis:
image: redis:latest
I'm pretty new to docker, so and easy improvements you can see feel free t flag...I'm in the trial and error stage!
Your image that has your code should have all the dependencies needed for your code to run.
In this case, your code needs mysqldump installed locally for it to run. I would consider this to be a dependency of your code.
It might make sense to add a RUN line to your Dockerfile that will install the mysqldump command so that your code can use it.
Another approach altogether would be to externalize the database backup process instead of leaving that up to your application. You could have some container that runs on a cron and does the mysqldump process that way.
I would consider both approaches to be clean.

Categories