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

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.

Related

PHP Docker container exits for no reason

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

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 compose wordpress plugins

This is my docker-compose.yml so far:
wordpress:
image: wordpress
links:
- db:mysql
ports:
- 8080:80
net: "bridge"
dns:
- 8.8.8.8
- 4.4.4.4
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: biersaufen
Is there a way to directly install wordpress plugins? (Directly means that i can install it via the docker-compose.yml)
Yes, you can, but not directly via the docker-compose file.
You need to use the "build" section of the docker compose and have a Dockerfile that will install the modules for you. That way when you run docker-compose on your directory, it will first build the image with the plugins and use that image to start the stack.

Docker and package managers in production

I'm developing a PHP application which I want to have running using docker containers. I'm using the composer package manager which pulls in all the dependencies. All code is kept in a git repository except the dependencies.
To get everything running on my local machine I'm using docker-compose (fig). I mount my application code (include vendor folder) to volume on my containers. Here is my docker-compose.yml file.
nginx:
image: nginx:1.9
links:
- php
volumes:
- conf/nginx/default.conf:/etc/nginx/conf.d/default.conf
- src:/var/www/html
ports:
- "80:80"
php:
image: php:5.6.9-fpm
links:
- memcached
volumes:
- conf/php/php.ini /usr/local/etc/php/php.ini
- src:/var/www/html
volumes_from:
- nginx
What I don't really understand is how I would push this into production or staging environment. From what I understand it's best to ship everything in a container without having to run a package manager, because this might fail or the packages might not be identical as the packages on my local machine. So I Came up with the following docker-compose.yml file:
webapp:
image : quay.io/myusername/myrepo
php:
image: php:5.6.9-fpm
volumes:
- config/php/php.ini /usr/local/etc/php/php.ini
volumes_from:
- webapp
nginx:
image: nginx:1.9
links:
- php
volumes:
- config/nginx/default.conf:/etc/nginx/conf.d/default.conf
volumes_from:
- webapp
ports:
- "80:80"
The webapp container is build from the following dockerfile and is hosted on some repository.
FROM busybox
VOLUME /var/www/html
ADD src /var/www/html
I have a git hook that will trigger a build of this dockerfile on quay.io and adds my source code to the image.
Here's the problem: The vendor files / dependencies are not in version control so they won't be added.
I see two solutions which I both don't find ideal.
Add the dependencies to version control.
Run command composer install to pull in all files. Not preferable as mentioned above.
I'm still very new to docker, so it could be I got things all wrong. Would love to get an answer how to do this properly.
Your Dockerfile should build the container image as if there would be no volumes mounted. Clone or copy your code in the container, run composer to install dependencies. Running the container without any volumes should work.
Volumes in production environments are for persisting data and logs primarily. Your code should not be in a mounted volume.
For development purposes, you can mount a volume to the code location and your container will still work.
To speed up the build process, copy your composer.json and composer.lock files first and install dependencies to a location outside your source tree. It will ensure the dependencies only get updated when your json file changes, not on every code change, speeding up the process immensely.

Categories