PHP Docker container exits for no reason - php

I'm relatively new to docker and docker-compose so I made this file
version: '3'
services:
web:
image: nginx:latest
ports:
- "8050:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
links:
- php
php:
image: php:7.3-fpm-alpine3.9
command: apk --update add php7-mysqli
volumes:
- ./code:/code
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
For some reason the line
command: apk --update add php7-mysqli
Stops php container for no reason, just prints dock_php_1 exited with code 0
Thus my web container also stops and service doesn't work
What could be core of the problem and how to fix it?

This is because you are telling the container to run the apk update command when it starts, this completes and exits with a valid exit code 0...
To get it to run that apk update command and still use the php container, you need to extend the php image with your own build to create your own 'custom image' of the base php image (kinda like extending a PHP class), and then run that apk update as part of the dockerfile.
This is reasonably easy to do and your dockerfile would look something like:
FROM php:7.3-fpm-alpine3.9
RUN apk --update add php7-mysqli
You can save this as ./php/Dockerfile
Then update your docker-compose.yml file to say:
...
php:
build: ./php
volumes:
...
Removing the command: section
This would then, upon docker-compose up, build your extended image with the apk update inside it as an extra layer on the container, and continue running the standard php command that the original image provides.
Here is the documentation on the build: directive, as there are quite a few other cool things you can do with it,
like specifying the Dockerfile if you don't want to put it into a subdirectory, and providing the context: should you wish to bake in files to your new image
https://docs.docker.com/compose/compose-file/#build

I assume what you actually need is to use Docker Compose "build" option, and provide Dockerfile which installing the desired package (RUN apk --update add php7-mysqli). Alternatively, you can build a new Docker image and use it directly in your Docker Compose file.
Docker Compose "command" is to override the default Docker image command (CMD command of the Dockerfile)
More explanation can be found here:
https://medium.freecodecamp.org/docker-entrypoint-cmd-dockerfile-best-practices-abc591c30e21

Related

Docker "/usr/bin/php" not found in container

I am using docker for my app that includes freeradius,nginx and php.
I want to use "program = "/usr/bin/php " this command in container freeradius but it is not working.
In freeradius container I want to run this command "/usr/bin/php" but it says command not found.
Can anyone help me in this ?
version: '3.2'
services:
freeradius:
image: "ronakzenexim/2stacks_freeradius:v1"
environment:
- RAD_DEBUG=yes
depends_on:
- mysql
- php
links:
- mysql
restart: always
networks:
- backend
php:
image: "ronakzenexim/phpfpm72_mycrypt"
restart: always
volumes:
- "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
- "./web:/var/www/html"
networks:
- backend
networks:
backend:
ipam:
config:
- subnet: 10.0.0.0/24
Create a extension of the freeradius docker image for example
FROM ronakzenexim/2stacks_freeradius:v1
# Now install php
RUN apk update && apk upgrade
RUN apk add php7 php7-fpm php7-opcache
In this container you can run php.

Docker compose command no such file

I've been attempting to containerize my php wev app (built on laravel) but I've run into a few issues
first I've found that the container exits after executing a command so I moved the building script to a different container (migrations and composer install)
I made a script called init.sh that contains the build instructions but whenever I run them from the command in docker-compose.yml I get no such file or directory.
this is my dockerfile
FROM nimmis/apache-php7
COPY apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
RUN service apache2 restart
this is my docker-compose.ym
version: "3"
volumes:
db-data:
external: false
services:
db:
image: mysql/mysql-server
env_file: .env
volumes:
- db-data:/var/lib/mysql-server
migrations:
build: .
env_file: .env
volumes:
- .:/var/www/html/books
depends_on:
- app
command:
# - /var/www/html/books/artisan migrate
# - chmod 777 /var/www/html/init.sh
- /var/www/html/books/init.sh
# - /var/www/html/init.sh
environment:
- ALLOW_OVERRIDE=true
app:
build: .
env_file: .env
volumes:
- .:/var/www/html/books
ports:
- "8081:80"
depends_on:
- db
environment:
- ALLOW_OVERRIDE=true
the commented parts a different attempts to run the script correctly.
I'm trying to run it on windows 10 using docker toolbox
What am I doing wrong? and is this the correct approach?
The RUN directive will execute something in the container when the container is building, not when the container is executing.
To that end, your Dockerfile should look something more like this:
FROM nimmis/apache-php7
COPY apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
ENTRYPOINT ["bash", "/path/to/init.sh"]
CMD ["apache2", "-DFOREGROUND", "-k", "start"]
The Entrypoint directive will run right before the CMD directive, irrespective if you pass a command into the container at boot.
So, you'll want to make init.sh execute the command the container passes to it:
#!/bin/bash
# init.sh
# todo: whatever init.sh does...
# Execute the CMD passed to the container:
exec "$#"
So I figured out what was wrong ... it was a permissions issue.
when I set the permissions to be executable it worked fine ...
so now all I had to do was adjust my dockerfile to be
FROM nimmis/apache-php7
COPY . /var/www/html/books
COPY start.sh /
RUN chmod +x /start.sh
COPY apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
RUN service apache2 restart
Instead of this
volumes:
- .:/var/www/html/books
use
volumes:
- folder_containg_sh:/var/www/html/books #relative path to script
in docker-compose file

Docker with Symfony and MongoDB

I want to make a project in PHP (Symfony) and MongoDB.
I created the file docker-compose.yml:
web_server:
build: .
ports:
- 5000:5000
links:
- mongo
mongo:
image: mongo:3.0
container_name: mongo
command: mongod --smallfiles
expose:
- 27017
And I try to run Docker Compose in PHP Storm but I recived:
Removing old containers...
(Re)building services...
mongo uses an image, skipping
Building web_server
Cannot locate specified Dockerfile: Dockerfile
Starting...
Building web_server
Cannot locate specified Dockerfile: Dockerfile
No containers created for service: web_server
No containers created for service: mongo
Failed to deploy 'Compose: docker-compose.yml': Some services/containers not started
I don't know what I should do, what should contain Dockerfile, what create containers.
Thanks!
Done!
I use Dockerfile from https://github.com/lepiaf/docker-symfony2 (with all files) and previously docker-compose.yml.
Thanks!

Files changes not reflected in Docker image after rebuild

I'm trying to set up two Docker images for my PHP web application (php-fcm) reversed proxied by NGINX. Ideally I would like all the files of the web application to be copied into the php-fcm based image and exposed as a volume. This way both containers (web and app) can access the files with NGINX serving the static files and php-fcm interpreting the php files.
docker-compose.yml
version: '2'
services:
web:
image: nginx:latest
depends_on:
- app
volumes:
- ./site.conf:/etc/nginx/conf.d/default.conf
volumes_from:
- app
links:
- app
app:
build: .
volumes:
- /app
Dockerfile:
FROM php:fpm
COPY . /app
WORKDIR /app
The above setup works as expected. However, when I make any change to the files and then do
compose up --build
the new files are not picked up in the resulting images. This is despite the following message indicating that the image is indeed being rebuilt:
Building app
Step 1 : FROM php:fpm
---> cb4faea80358
Step 2 : COPY . /app
---> Using cache
---> 660ab4731bec
Step 3 : WORKDIR /app
---> Using cache
---> d5b2e4fa97f2
Successfully built d5b2e4fa97f2
Only removing all the old images does the trick.
Any idea what could cause this?
$ docker --version
Docker version 1.11.2, build b9f10c9
$ docker-compose --version
docker-compose version 1.7.1, build 0a9ab35
The 'volumes_from' option mounts volumes from one container to another. The important word there is container, not image. So when you rebuild an image, the previous container is still running. If you stop and restart that container, or even just stop it, the other containers are still using those old mount points. If you stop, remove the old app container, and start a new one, the old volume mounts will still persist to the now deleted container.
The better way to solve this in your situation is to switch to named volumes and setup a utility container to update this volume.
version: '2'
volumes:
app-data:
driver: local
services:
web:
image: nginx:latest
depends_on:
- app
volumes:
- ./site.conf:/etc/nginx/conf.d/default.conf
- app-data:/app
app:
build: .
volumes:
- app-data:/app
A utility container to update your app-data volume could look something like:
docker run --rm -it \
-v `pwd`/new-app:/source -v app-data:/target \
busybox /bin/sh -c "tar -cC /source . | tar -xC /target"
As BMitch points out, image updates don't automatically filter down into containers. your workflow for updates needs to be revisited. I've just gone through the process of building a container which includes NGINX and PHP-FPM. I've found, for me, that the best way was to include nginx and php in a single container, both managed by supervisord.
I then have scripts in the image that allow you to update your code from a git repo. This makes the whole process really easy.
#Create new container from image
docker run -d --name=your_website -p 80:80 -p 443:443 camw/centos-nginx-php
#git clone to get website code from git
docker exec -ti your_website get https://www.github.com/user/your_repo.git
#restart container so that nginx config changes take effect
docker restart your_website
#Then to update, after committing changes to git, you'll call
docker exec -ti your_website update
#restart container if there are nginx config changes
docker restart your_website
My container can be found at https://hub.docker.com/r/camw/centos-nginx-php/
The dockerfile and associated build files are available at https://github.com/CamW/centos-nginx-php
If you want to give it a try, just fork https://github.com/CamW/centos-nginx-php-demo, change the conf/nginx.conf file as indicated in the readme and include your code.
Doing it this way, you don't need to deal with volumes at all, everything is in your container which I like.

Docker: Nginx & PHP Container: no such file or directory

I want to play around with docker so I created my own 2 container, nginx and php. Both container are build successfully and are published on docker hub. After that I created a fig.yml in my projects folder. If I run fig up -d in my terminal, then I got the following error:
Recreating playground_php_1...
Cannot start container e087111c...: [8] System error: no such file or directory
Any ideas how I can fix this problem?
Here is my fig.yml:
web:
image: mc388/docker-nginx:latest
ports:
- "80:80"
- "443:443"
links:
- php
volumes:
- ./logs/nginx:/var/log/nginx
volumes_from:
- php
php:
image: mc388/docker-php:latest
volumes:
- .:/var/www/
And here are the links to the config of both docker containers:
https://github.com/mc388/docker-nginx
https://github.com/mc388/docker-php
The underlying php:fpm image has the following line in the Dockerfile:
WORKDIR /var/www/html
You then delete this directory, which breaks the default CMD command as it uses WORKDIR as its base.
I don't know much about PHP and this Docker image, but it's worth reading the documentation and looking at any examples you can find on how to use it; deleting a directory feels like you're working against the image.

Categories