Nginx in Docker container won't run PHP - php

I'm beginner with Docker, and I'm trying to build my own image: Ubuntu + Nginx + PHP.
So, I have a directory called test. Inside directory two other directories, app and sites-enabled. Also, there's a Dockerfile, with content:
FROM ubuntu:trusty
RUN apt-get update && \
apt-get install -y nginx php5-fpm php5-mysql php-apc php5-imagick php5-imap php5-mcrypt php5-gd libssh2-php && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
ADD sites-enabled/ /etc/nginx/sites-enabled/
ADD app/ /app/
EXPOSE 80
CMD ["php5-fpm", "-c", "/etc/php5/fpm"]
CMD ["/usr/sbin/nginx"]
I build this image successfully. Then I create container with docker run -d image_name. I get the ID, and then I run docker inspect -f "{{.NetworkSettings.IPAddress}}" ID in order to get the IP address of the container.
I need this IP address, because I also run HAProxy in another container, so I can configure it to point to the right localtion.
So, both HAProxy and container with PHP app are running OK. HAProxy is pointing at the right application. PHP application files are uploaded at the right location inside the container.
But, Nginx doesn't execute PHP. Instead, when I try to access the application, I just get a downloaded file with my index.php PHP code.
What could be the problem? Please help.
My first guess was that I'm doing something wrong in Dockerfile when I run php5-fpm. I've tried few different ways, but non of them seem to work.

One CMD only.
If you need "services", look into supervisord or runit.

Related

PHP-FPM docker container stops responding after a while (in some cases weeks) on Digital Ocean with Caddy

I have 3 different Ubuntu droplets with Docker on Digital Ocean. They are all running Caddy as proxy with 2 of them using PHP-FPM and 1 using PHP-FPM Alpine.
After the server has been running a while, sometimes a few days, sometimes 3-4 weeks, the request stops responding.
All has the same type of problem.
I can SSH into the droplet. The caddy seems to be running all fine. I can access everything through caddy that is not the PHP.
The interessting part from the Caddy Docker log is this:
{
"level": "error",
"logger": "http.log.error",
"msg": "dialing backend: dial tcp 172.30.0.3:9000: i/o timeout",
"duration": 3.014910236,
"status": 502,
"err_id": "j14574vxr",
"err_trace": "reverseproxy.statusError (reverseproxy.go:1196)"
}
If I do a docker logs -f PHP_CONTAINER all I can see is a valid request from the time before PHP stopped responding.
If i restart only the PHP container it starts working again. The strange part is that if I ONLY do a restart of CADDY container it will also start working.
I didn't seem to have this problem with NGINX earlier. So I my initial thought was that CADDY was the problem. But I do get connection to other services on the same Docker server. For instance PHP-FPM service doesn't respond, but my phpMyAdmin service is still working.
The caddy file is like this:
mydomain.com {
root * /var/www/public
php_fastcgi /* php:9000
file_server
}
The PHP-FPM Dockerfile is like this:
FROM php:8.1.6-fpm
ARG user
ARG uid
RUN apt-get update && apt-get install -y \
curl \
zip \
unzip
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
r
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
WORKDIR /var/www
USER $user
I have tried multiple versions of PHP-FPM, it still happening.
For my WordPress site, using the FPM-Alpine version, I basically use the same Dockerfile as this (some smaller modifications only)
https://github.com/docker-library/wordpress/blob/master/latest/php8.1/fpm-alpine/Dockerfile
Does anyone has tips to what I can try to figure out why this error keeps happening.

PHP-FPM is not being restarted properly from a Dockerfile

I am having this weird problem with PHP-FPM. First of all, I am not an expert on PHP. I'm builing an app, and PHP will only communicate with MySQL to push and pull data.
The problem:
I have a Dockerfile where I'm making some changed in PHP-FPM config, and one of the lines is to reload PHP-FPM. Actually when you install PHP-FPM, it is not running, so I do:
RUN service php7.3-fpm start
When the app starts and I check PHP-FPM, it is not running. I had this issue before (with php7-0-fpm), I had resolved it by doing:
service php7.0-fpm stop && service php7.0-fpm start
But now, when I do it, it is still stopped.
So, I started reading and someone advised to put it in the CMD command, along with the main command. I did, and it worked:
CMD service php7.3-fpm start && nginx -g "daemon off;"
Now, the problem is that it is not taking the new configuration. When I access the machine, and I manually do service php7.3-fpm reload it starts working.
I tried putting it in the Dockrfile as well, but no luck. Any idea? I would like to resolve the first issue as well (I don't want to restart PHP-FPM from the CMD. It would be preferable to do it with a RUN layer in docker).
EDIT
Another weird thing is that when I do service php7.3-fpm start manually, it doesn't work, but it works when I do /etc/init.d/php7.3-fpm start. Seems to work, when I do it in the CMD line:
CMD /etc/init.d/php7.3-fpm start && nginx -g "daemon off;"
Dockerfile
FROM debian:buster
LABEL maintainer="me"
RUN apt-get update && apt-get install -y \
nginx \
default-mysql-client \
php7.3-fpm \
php7.3-mysql
RUN sed -i.bak "s/;clear_env = no/clear_env = no/g" /etc/php/7.3/fpm/pool.d/www.conf && \
sed -i.bak "s/;php_flag\[\display_errors\]\ = off/php_flag\[\display_errors\]\ = on/g" /etc/php/7.3/fpm/pool.d/www.conf
COPY ./html/ /var/www/html/
RUN rm /var/www/html/index.nginx-debian.html
WORKDIR /var/www/html/
EXPOSE 80
CMD service php7.3-fpm start && nginx -g "daemon off;"
Execute a command or restart php-fpm using RUN directive will not effect because each layer runs in a separate shell.
The best way is to copy the config file from host, rebuild the image and then run the container.
for Example
FROM debian:buster
COPY config/php7.ini /usr/local/etc/php/conf.d/
COPY config/fpm/php-fpm.conf /usr/local/etc/
COPY config/fpm/pool.d /usr/local/etc/pool.d
Also better to run the separate container for each process, rule of thumb single process per container.
You CMD seem fine it starts PHP and Nginx both.
To verify process inside your container add
RUN apt-get update && apt-get install procps -y
then run
docker exec -it your_container_id bash -c "ps -aux"

How can I make this docker image smaller?

I have the following dockerfile:
FROM php:7.2-apache
LABEL name "medico-app"
COPY composer.json composer.lock ./
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y --no-install-recommends git zip && composer install
COPY . /var/www/html
EXPOSE 80
When this image is built, it has a size of ~500 Mbs. I'm trying to compress this image to < 100 Mb so that I can use it on Zeit Now. According to what I'm reading in the docker documentation, multi-stage builds sometimes help in making images smaller. My current idea is to split the dockerfile into two stages, one where I would install the dependencies with compose and the other where I'd just have php and apache. I can't seem to get it right though. Any suggestions?
This is what I have so far:
# first stage
FROM composer:latest
COPY composer.json composer.lock ./
RUN composer install
For the second stage, I tried this
FROM httpd:2.4-alpine
LABEL name "medico-app"
COPY --from=0 /app/vendor ./vendor
COPY . /usr/local/apache2/htdocs/
EXPOSE 80
However when I run the container now, the php files aren't served, I just see them as text. Im probably missing something here with PHP/Apache.
EDIT:
I also tried this for the second stage but I can't get it to work:
FROM php:7.2-alpine
LABEL name "medico-app"
RUN apk --no-cache update && apk --no-cache add apache2 openrc
COPY --from=0 /app/vendor ./vendor
COPY . /var/www/
EXPOSE 80
Now when I open my localhost I don't see the PHP files that I should see. I just see the default it works page.
General tips for making docker images smaller:
Use a minimal base image such as the alpine versions. In this case you can use something like php:7.2-alpine and install apache using apk.
When using apt-get follow the best practices. In particular add && rm -rf /var/lib/apt/lists/*
Try minifiying the code being added to the image using something like gulp minify.

DOCKERFILE: Running multiple CMD. (Starting NGINX and PHP) [duplicate]

This question already has answers here:
Why can't I use Docker CMD multiple times to run multiple services?
(5 answers)
Closed 4 years ago.
I have a dockerfile that sets up NGINX, PHP, adds a Wordpress Repository. I want at boot time, to start PHP and NGINX. However, I am failing to do so. I tried adding the two commands in the CMD array, and I also tried to put them in a shell file and starting the shell file. Nothing worked. Below is my Dockerfile
FROM ubuntu:16.04
WORKDIR /opt/
#Install nginx
RUN apt-get update
RUN apt-get install -y nginx=1.10.* php7.0 php7.0-fpm php7.0-mysql
#Add the customized NGINX configuration
RUN rm -f /etc/nginx/nginx.conf
RUN rm -f /etc/nginx/sites-enabled/*
COPY nginx/nginx.conf /etc/nginx/
COPY nginx/site.conf /etc/nginx/sites-enabled
#Copy the certificates
RUN mkdir -p /etc/pki/nginx
COPY nginx/certs/* /etc/pki/nginx/
RUN rm -f /etc/pki/nginx/placeholder
#Copy the build to its destination on the server
RUN mkdir -p /mnt/wordpress-blog/
COPY . /mnt/wordpress-blog/
#COPY wp-config.php
COPY nginx/wp-config.php /mnt/wordpress-blog/
#The command to run the container
CMD ["/bin/bash", "-c", "service php7.0-fpm start", "service nginx start"]
I tried to put the commands in the CMD in a shell file, and run the shell file in the CMD command. It still didn't work. what am i missing?
start.sh
#!/bin/bash
/usr/sbin/service php7.0-fpm start
/usr/sbin/service nginx start
tail -f /dev/null
Dockerfile
COPY ["start.sh", "/root/start.sh"]
WORKDIR /root
CMD ["./start.sh"]
With this, you can put more complex logic in start.sh.
You can replace the CMD line for some like ...
CMD ["/bin/bash", "-c", "/usr/sbin/service php7.0-fpm start && nginx -g 'daemon off;'"]
TL;DR: You don't have an entry point.
Main idea in the Docker is to have one responsibility per container. So, in order to keep running a Docker container you have to start a program in foreground upon container boot.
However, in your Dockerfile, there is no entrypoint to start a program in foreground. So, just after your container boot, your container exits.
So, in order to prevent your container from exiting, just start a program in foreground.
Nginx for instance.
Example scenario:
entrypoint.sh content:
#!/bin/bash
service php7.0-fpm start
nginx -g 'daemon off;
somewhere in Dockerfile:
COPY [ "./entrypoint.sh", "/root/entrypoint.sh" ]
at the end of the Dockerfile:
ENTRYPOINT /root/entrypoint.sh

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")

Categories