Docker with php built-in server - php

I'm trying to run php built-in server (php -S localhost:8080) via docker, I cannot access site from the host though - I always end up with Connection reset.
Here's a simple Dockerfile I build on:
FROM centos:centos6
RUN rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm
RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
RUN yum --enablerepo=remi,remi-php55 install -y php php-opcache php-cli php-pear php-common && yum clean all
RUN php -r "readfile('https://getcomposer.org/installer');" | php
RUN echo "date.timezone = Europe/Prague" >> /etc/php.ini
RUN mv composer.phar /usr/bin/composer
RUN php -r "eval('?>'.file_get_contents('http://backend.bolt80.com/piecrust/install'));"
RUN mv piecrust.phar /usr/bin/chef
CMD ["/bin/bash"]
Is it even possible to run this server with docker? While trying to make it work, I found out that when nginx was installed and set to listen on this very port, it is accessible from the host. PHP built-in server seems to be hidden from the host, thus not able to serve any requests though.
Anyone was successful making this work?

If from within the docker container you start your webserver with php -S localhost:8080 then the webserver will only accept connections originating from the docker container itself.
To be able to communicate with your webserver from the docker host you need to make two changes:
in your Dockerfile, add EXPOSE 8080, or when running the container add -p 8080 to the docker run command line. This will tell the docker host that your container has a program which expects communication on port 8080
start the webserver with php -S 0.0.0.0:8080 so it also accepts connections from outside of the docker container itself
Once you have a container running with those changes, open up a new terminal on the docker host and use the docker ps command to see what port on the docker host is forwarded to port 8080 in the container. For instance:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fbccf4058b07 test:latest "php -S 0.0.0.0:8080 4 minutes ago Up 4 minutes 0.0.0.0:49153->8080/tcp sad_hawking
In this example port 49153 of the docker host is to be used. Then query your webserver to validate you can communicate with it:
$ curl http://localhost:49153

For docker compose
services:
api:
build: ./api
command: php -S 0.0.0.0:80
ports:
- 80:80
with dockerfile, placed in ./api folder
FROM php:apline
WORKDIR /
COPY . .

Related

Using Docker Nginx, PHP, MySQL on Mac

I'm just starting to get my head around docker and want to use it for a project.
I have followed https://docs.docker.com/docker-for-mac/#explore-the-application-and-run-examples and have NGINX running fine and can see the NGINX landing page.
Do I need to install php-fpm and mySQL within my container since my container is only NGINX at this stage?
How do I configure my project on a custom domain e.g. project.dev. Do I need to edit an entry in /etc/hosts for 127.0.0.1 project.dev and then listen for that URL in an NGINX config?
Lastly do I need a dockerfile? I already have my container up and my understanding is a dockerfile is only for defining your container?
An example of a dockerfile for NGINX, PHP and mySQL would be helpful to look at as well.
Thanks
No, this guide just show using nginx container in docker. But I see the container don't have php installed. And you cannot install php-fpm inside this container.
So, if you want to use nginx, php, and MySQL using docker you should pull:
Container which run Nginx + PHP-FPM (I recommend this image https://hub.docker.com/r/richarvey/nginx-php-fpm/)
Container run MySQL (https://hub.docker.com/_/mysql/)
Download images
docker pull richarvey/nginx-php-fpm
docker pull mysql:5.6
Run MySQL Instance. Name it mysql56, and expose using port 3360
docker run -tid -p 3360:3306 --name mysql56 -e MYSQL_ROOT_PASSWORD=123456 -v /root/docker/mysql56/data/mysql:/var/lib/mysql -d mysql:5.6
Run Nginx PHP+FPM instance. Link it to MySQL Instance, and name it project-dev
docker run -tid --name project-dev --link mysql56:mysql -v $(pwd):/var/www/html -p 8888:80 richarvey/nginx-php-fpm:latest
Run docker ps -a to see the running containers.
To make nginx can be accessed with address project.dev, just map it on /etc/hosts. Then access it on web browser http://project.dev:8888
Note:
-v /root/docker/mysql56/data/mysql:/var/lib/mysql it mean I have /root/docker/mysql56/data/mysql on my mac, and map it to /var/lib/mysql in mysql56 container. So all mysql data will be backup on my local data, and will not lose when I remove the container.
-v $(pwd):/var/www/html mean your current directory will be mapped to
container. So, whatever you write in this directory will be exist on
/var/www/html container.
I use port 8888 to avoid conflict with existing web server, you can
change it as you want

How can I mount a volume to docker container in OSX?

My ultimate goal is to run different versions of PHP on my local computer for testing.
I believe Docker is the best way to accomplish this.
I have been able to get a container with Apache and PHP running via this tutorial: https://github.com/tutumcloud/apache-php
But the issue is that I cannot mount a volume so that I can edit local files and view them on the docker container.
Here are my steps in terminal running in the same directory as the docker file:
docker build -t tutum/apache-php .
docker run -d -p 8080:80 tutum/apache-php -v /Users/user-name-here/apache-php/sample:/app/
The error I get back is:
docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"-v\": executable file not found in $PATH".
I'm on OSX - El Captain, just installed latest version of Docker and Docker tools.
The basic format of the docker run command is:
docker run [<options>] <image> [<command>]
In this case, your image is tutum/apache-php, and the run command is being parsed like this:
docker run -d -p 8080:80 tutum/apache-php -v /Users/user-name-here/apache-php/sample:/app/
docker run
options: -d -p 8080:80
image: tutum/apache-php
command: -v /Users/user-name-here/apache-php/sample:/app/
This is the source of your error.
exec: "-v": executable file not found in $PATH
Since the command begins with -v, it will try to locate and execute that command. Of course, it doesn't exist, so you will get this error.
The fix is simply to move the -v option and its argument to the proper place.
docker run -d -p 8080:80 -v /Users/user-name-here/apache-php/sample:/app/ tutum/apache-php

Docker LAMP stack - where is the location to keep PHP projects?

I have my LAMP stack installed already before Docker's. And I am using this image to build and run my Docker's LAMP stack:
$ docker pull linuxconfig/lamp
After all are downloaded and installed:
$ docker run -it linuxconfig/lamp /bin/bash
root#2e80dfd55a6e:/# service apache2 start
[....] Starting web server: apache2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
So at my http://172.17.0.2/, I can see this default page:
But where can I locate its location so that I can put my PHP projects in there?
This the DockerFile from that image:
FROM linuxconfig/apache
MAINTAINER Lubos Rendek <web#linuxconfig.org>
ENV DEBIAN_FRONTEND noninteractive
# Main package installation
RUN apt-get update
RUN apt-get -y install supervisor libapache2-mod-php5 php5-mysql mysql-server
# Extra package installation
RUN apt-get -y install php5-gd php-apc php5-mcrypt
# Configure MySQL
RUN sed -i 's/bind-address/#bind-address/' /etc/mysql/my.cnf
# Include supervisor configuration
ADD supervisor-lamp.conf /etc/supervisor/conf.d/
ADD supervisord.conf /etc/supervisor/
# Include PHP Info page
ADD index.php /var/www/html/index.php
# Create new MySQL admin user
RUN service mysql start; mysql -u root -e "CREATE USER 'admin'#'%' IDENTIFIED BY 'pass';";mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'#'%' WITH GRANT OPTION;";
# Allow ports
EXPOSE 80 3306
# Start supervisor
CMD ["supervisord"]
EDIT:
$ sudo docker run --name=lamp -dP -v $PWD/html:/var/www/html linuxconfig/lamp
c2d1687aef21f8a12a7fbb31bf8cf71c1e5adabf381bc6d70e8804c6663f0bc0
And:
$ sudo docker port lamp
80/tcp -> 0.0.0.0:32769
3306/tcp -> 0.0.0.0:32768
I go to my browser at: http://172.17.0.2:32769/
I get this error:
See if this article can help: "LAMP ( Linux, Apache, MariaDB, PHP ) stack Docker image deployment"
Save index.php file and within a new html directory.
Alternatively, html directory may contain your desired PHP application:
$ mkdir html
$ vi html/index.php
$ ls html/
index.php
At this stage we are ready to deploy “linuxconfig/lamp” docker image:
sudo docker run --name=lamp -dP -v $PWD/html:/var/www/html linuxconfig/lamp
That means you are mounting your host directory html into the linuxconfig/lamp container folder /var/www/html. (see "Mount a host directory as a data volume")

Restart apache on Docker

I am trying to update my .htaccess file on a Docker container. After updating the file I need to restart Apache. Whenever I try to restart Apache: with the command service apache2 restart I get the following error:
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
Action 'start' failed.
The Apache error log may have more information.
...fail!
When I got to the error log it doesn't have any new errors.
This is what my Dockerfile looks like:
FROM ubuntu:12.04
# Install dependencies
RUN apt-get update -y
RUN apt-get install -y git curl apache2 php5 libapache2-mod-php5 php5-mcrypt php5-mysql php5-curl vim
# Install app
RUN rm -rf /var/www/ *
ADD src /var/www
# Configure apache
RUN a2enmod rewrite
RUN chown -R www-data:www-data /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
Actually you don't need to restart Apache in order to apply changes defined in .htaccess - those are applied during runtime. If you're modifying apache config file (like virtual host definition or something in httpd.conf) you can also reload config without restarting apache using
sudo /etc/init.d/apache2 reload
It's because you are (correctly) not starting apache as a service when you docker run the container. The line:
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
Starts apache in the foreground.
I'm guessing you are then using docker exec to execute a shell in the container to edit the file and restart apache? If so this would explain why the second time you start apache it complains about the existing process.
I think if you are using containers in this way then you are really missing out on the benefit of containers which comes when you treat them as immutable and keep the data outside the container (either on your host or in volumes) so that you can easily replace the container.
In your case if you need to modify the .htaccess file I think it would be more normal to mount that file into the container by using a command like:
docker run -d --name apache -v $(pwd)/.htaccess:/path/to/.htaccess -p 80:80 image:tag
Then if you have to change the file and need to restart apache you can use:
docker restart apache
Although it may be worth investigating the suggestion from Charlotte Dunois that you might not even need to restart apache.

create web app with php and docker

I have the following DOCKERFILE:
FROM php
RUN apt-get update && apt-get install -y git
RUN git clone https://github.com/marcosh/webinthemiddle.git
EXPOSE 80
CMD php -S localhost:80 webinthemiddle/index.php
that I would like to use to create a very basic app with php.
I build the image using sudo docker build -t marcosh/webinthemiddle .
and then I tried running the container using
sudo docker run -d -P marcosh/webinthemiddle
or
sudo docker run -d -P marcosh/webinthemiddle php -S localhost:80 webinthemiddle/index.php
Then I checked with sudo docker ps to which port was mapped the port 80 of the container and browser to localhost:#PORT#, but I found nothing there...
What am I doing wrong?
Two things will be helpful for you to debug this:
When debugging problems like this, start by running the container in the foreground interactively and with a TTY (-i and -t respectively). Your command would be something like sudo docker run -i -t -P marcosh/webinthemiddle php -S localhost:80 webinthemiddle/index.php.
Next, in the Docker container world, localhost is local to the container (not your host). Since the container is only listening on localhost, requests from other IP addresses (such as your host) won't get to the socket. You will want to listen on 0.0.0.0:80.

Categories