How can I run my docker container with installed Nginx? - php

I have docker image with Dockerfile, that successfully build with docker build . command. The Dockerfile content is:
FROM ubuntu
RUN apt-get update && apt-get install -y nginx php5 php5-fpm
ADD . /code
How can I run my docker container to see that Nginx is work?
UPDATE: When I try to use next Dockerfile:
FROM ubuntu
RUN apt-get update && apt-get install -y nginx php5 php5-fpm
RUN sudo echo "daemon off;" >> /etc/nginx/nginx.conf
CMD service php5-fpm start && nginx
It build successfully with docker build -t my/nginx ., but when I enter docker run --rm -ti my/nginx command, my terminal not response:

When you build the image you probably want to specify the image name with -t option.
docker build -t my/nginx .
To run a container use the run command
docker run --rm -ti my/nginx
You probably should add the following command to your Dockerfile
CMD ["nginx"]
Or with php5-fpm
CMD service php5-fpm start && nginx
UPDATE.
You should run nginx as daemon off. Add the following to your Dockerfile after installing nginx.
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
Update2.
-ti option in run allows you to check the log messages if any.
Usually you should run a container in background using -d instead of -ti.
You can attach to a running container using the attach command.
You may also check docker reference to see how to stop and remove a container and other commands.

Related

PHP-FPM does not start after container creation

I made a Dockerfile, but when I run it and enter the container, the php8.0-fpm service is not running.
How do I make it run at build time? Note that I run the command service php8.0-fpm start in the Dockerfile and even then it is not running.
What should I do for the php8.0-fpm service to start along with the container?
Below is the Dockerfile I made:
FROM ubuntu:jammy
ENV DEBIAN_FRONTEND=noninteractive
# Instalação Apache e PHP
RUN apt-get update && \
apt-get install software-properties-common -y && \
add-apt-repository ppa:ondrej/php -y && \
apt-get update && \
apt-get install -y \
apache2 \
libapache2-mod-php8.0 \
libapache2-mod-php \
php8.0-fpm \
libapache2-mod-fcgid \
# Alteração sequência index
COPY /src/dir.conf /etc/apache2/mods-enabled
# Commitando a nova configuração
RUN service apache2 restart
RUN service php8.0-fpm restart
# Inserindo página info.php
COPY /src/info.php /var/www/html
# Alterando módulos de multiprocessamento
RUN service apache2 stop && \
a2dismod php8.0 && \
a2dismod php8.1 && \
a2dismod mpm_prefork && \
a2enmod mpm_event && \
a2enconf php8.0-fpm && \
a2enmod proxy && \
a2enmod proxy_fcgi && \
service apache2 restart && \
service php8.0-fpm start
# Entrypoint para o conteiner iniciar o Apache
ENTRYPOINT ["apache2ctl", "-D", "FOREGROUND"]```
You need to run php fpm on startup. if you installed bash in your vm os, you can do it this way.
STOPSIGNAL SIGTERM
CMD ["/bin/bash", "-c", "php-fpm8 && include your apache here"]
Full guide: How to setup PHP 8, NGINX and PHP-FPM with docker
A Docker container only runs a single process. It doesn't "run services" per se. The image build doesn't preserve any running processes either. When you start the container, the image's ENTRYPOINT or CMD is the only thing that will be running in the container.
Avoiding the technical reasons, I'd broadly suggest that commands like service or systemctl just don't work in Docker. RUN service php8.0-fpm restart, for example, does nothing: PHP-FPM wasn't running before this command, and after the RUN command it won't be running either.
You'd typically restructure this into multiple separate containers, using a tool like Docker Compose to run them all together. Docker has a couple of official sample applications that demonstrate this. A Compose-based setup for this might look like
# docker-compose.yaml
version: '3.8'
services:
php:
build: . # using default Dockerfile
apache:
build:
context: .
dockerfile: Dockerfile.apache
ports:
- '8000:80'
Your Dockerfile would begin FROM php:8.0-fpm and contain only the PHP-related setup; Dockerfile.apache would begin FROM httpd:2.4 and only copy in the static assets and Apache configuration. Your proxy setup would need to reference the other container by name ProxyPass "/" "fcgi://php:9000"; see Networking in Compose in the Docker documentation for additional details.
Note that, even in this case, something like docker-compose exec apache service apache2 status still wouldn't show "a service is running", but if you docker-compose exec apache ps -e you'd see the HTTP daemon as process 1 within the container. This is normal.
I managed to leave it in just one container, PHP has an extension called Supervisor and with it installed we were able to start two or more services inside the container.
The Dockerfile looked like this:
FROM httpd:2.4-alpine
RUN apk update && \
apk add \
php \
php-fpm \
php-zip \
composer \
supervisor
COPY . /usr/local/apache2/htdocs
COPY httpd.conf /usr/local/apache2/conf/httpd.conf
COPY supervisor /etc/supervisor
WORKDIR /usr/local/apache2/htdocs
CMD ["supervisord","-n", "-c", "/etc/supervisor/supervisord.conf"]
And I created two configuration files for Supervisor.
apache.conf
[program:apache]
command=httpd -DFOREGROUND
autostart=true
autorestart=true
priority=10
startretries=1
startsecs=1
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
fpm.conf
[program:php-fpm]
command = php-fpm8 --nodaemonize
autostart=true
autorestart=true
priority=5
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
With that the two services started and it is working perfectly!

Docker download code from git and run php internal server

I want to download a public github project and run a project file through internal php server, through docker.
This is my file so far:
FROM php:7.2-cli
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y git
RUN git clone https://github.com/mygit src
WORKDIR src
CMD ["php", "-S", "0.0.0.0:80", "-t", "/src/src/examples/image.php"]
The process does not show up in docker ps when I run:
docker build -t myimage .
docker run -d -p 8080:8080 myimage
Try with this Dockerfile:
FROM php:7.2-cli
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y git
RUN git clone https://github.com/douma/langtons-ant src
WORKDIR src
ENTRYPOINT ["php"]
CMD ["-S", "0.0.0.0:8080","/src/src/examples/image.php"]
Note I don't know php but checking your github project's readme I think you do not need the -t argument.
I also added ENTRYPOINT command to make your Dockerfile clearer. For differences check this.
The build and run commands should be the same as these you posted.
docker build -t myimage .
docker run -d -p 8080:8080 myimage

Building a Docker Container with Cetnos7 apache and php.

I'll preface this by saying I am very new to the docker world and despite reading documentation I am still a little confused about a few things.
I want to build a container with centos7 apache and php. I don't want to use an already existing image, want to build a custom container. I have the following folder structure
My rw/docker/webserver/Dockerfile:
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
RUN yum -y install httpd
RUN systemctl start httpd
RUN systemctl enable httpd
RUN yum update -y && yum install -y libpng-dev curl libcurl4-openssl-dev
RUN docker-php-ext-install pdo pdo_mysql gd curl
RUN a2enmod rewrite
MY docker-compose.yml
version: '2'
services:
webserver:
build: ./docker/webserver
ports:
- "80:80"
- "443:443"
volumes:
- /**PATH**/rw/services:/var/www/html
links:
- db
db:
image: mysql:5.7
ports:
- "3306:3306"
volumes:
- ./db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=****
- MYSQL_DATABASE=****
This fails when docker tries to start httpd with the error
ERROR: Service 'webserver' failed to build: The command '/bin/sh -c systemctl start httpd' returned a non-zero code: 1
Q1. Why is the install failing?
Q2. Is the the proper way to do this? Should my dockerfile for centos and apache+php be separate. If yes, how does that work?
Q1. I think systemctl may not be provided with CentOS docker image.
Indeed, docker services are not meant to be run as daemons, but in the foreground. Take a look at apache's original http-foreground shell script for a better understanding of the concept.
Q2. Not that's not the right way IMHO.
Running apache is the job of an entrypoint or command script.
So instead of RUN your-command-to-run-apache, it would rather be CMD your-command-to-run-apache.
Once again, Apache official repository can give you some clue about this.
To my eyes these kinds of Dockerfiles look too old as they try to map the external docker daemon inside the container. That's a workaround as a systemd daemon cannot be run separately in a container.
Instead I am using the docker-systemctl-replacement script. The docker systemctl.py can parse the normal *.service files to know how to start and stop services. You can register it as the CMD of an image in which case it will look for all the systemctl-enabled services - those will be started and stopped in the correct order.
There are even some testcases for the LAMP stack available, so it should work in your case quite smoothly. The systemctl.py script is compatible with the systemd systemctl as much as that one simply overwrite the /usr/bin/systemctl inside the image - and all the non-docker installation instructions will work for docker builds.

unable to run Apache/php from docker container

My requirement is using openface i need to train the dataset(images) and test each input image from webinterface (PHP) and all this activity should run from docker container.
I am able to achieve the above requirment on ubuntu machine. we are trying to install the complete setup(apache/php & openface) in docker. currently we are unable to invoke the html files from apache server using docker
The following the docker file used to import the project into docker and install apache/PHP. Please let me know if any changes need to be done in the dockerfile.
FROM ubuntu:16.04
RUN apt-get update && \
apt-get -y install sudo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo
ADD opencv-3.0.0 /
ADD openface_setup.sh /
RUN /openface_setup.sh
ADD openface_work /
RUN apt-get update && apt-get -y upgrade && DEBIAN_FRONTEND=noninteractive apt-get -y install \
apache2 php7.0 libapache2-mod-php7.0 curl lynx-cur
RUN a2enmod php7.0
RUN a2enmod rewrite
RUN sed -i "s/short_open_tag = Off/short_open_tag = On/" /etc/php/7.0/apache2/php.ini
RUN sed -i "s/error_reporting = .*$/error_reporting = E_ERROR | E_WARNING | E_PARSE/" /etc/php/7.0/apache2/php.ini
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
EXPOSE 8080
VOLUME /var/www/html # **my PHP/html files are located here. In the docker container the html/php files are not reflecting**
ADD apache-config.conf /etc/apache2/sites-enabled/000-default.conf
CMD /usr/sbin/apache2ctl -D FOREGROUND
Once the container is started i want the test.html(located in /var/www/html) to be running.
FYI :
command to created docker image
sudo docker build -t myname/apache-test .
command to start the docker container
docker run -p 8080:80 -d <imageid>
I'd suggest to use the official PHP image with a pre-installed Apache installation.
Your project might look like this:
.
├── Dockerfile
└── src
└── index.php
while your Dockerfile consists of this:
FROM php:7.1-apache
# now RUN here your commands to install openface etc.
and your index.php could look like this:
<?php phpinfo();
Then build the image:
docker build -t myapache .
docker run --rm -p 8080:80 -v $(pwd)/src:/var/www/html myapache
http://localhost:8080 shows the php-info page.
You can extend the image to your needs and it's much simpler than your approach. Hope this might help.
If you do not need to install anything else, you can directly use the php:7.1-apache image when creating a new container.
try typing docker ps to get all the processes running in containers.
Then just type docker run -it container-id
It will start the apache server and show the address where it hosted it unless you want to add a different one in /etc/docker/daemon.json (https://docs.docker.com/engine/userguide/networking/default_network/custom-docker0/)

Linking to a Docker memcached container

I have been experimenting with Docker for a few days now and have grown to like it. However, there are a few things that still elude me. Here is what I have thus far
Create a low footprint Ubuntu 14.04 image
//I got this from a post on this forum
#!/bin/bash
docker rm ubuntu-essential-multilayer 2>/dev/null
set -ve
docker build -t textlab/ubuntu-essential-multilayer - <<'EOF'
FROM ubuntu:14.04
# Make an exception for apt: it gets deselected, even though it probably shouldn't.
RUN dpkg --clear-selections && echo apt install |dpkg --set-selections && \
SUDO_FORCE_REMOVE=yes DEBIAN_FRONTEND=noninteractive apt-get --purge -y dselect-upgrade && \
dpkg-query -Wf '${db:Status-Abbrev}\t${binary:Package}\n' |grep '^.i' |awk -F'\t' '{print $2 " install"}' |dpkg --set-selections && \
rm -r /var/cache/apt /var/lib/apt/lists
EOF
TMP_FILE="`mktemp -t ubuntu-essential-XXXXXXX.tar.gz`"
docker run --rm -i textlab/ubuntu-essential-multilayer tar zpc --exclude=/etc/hostname \
--exclude=/etc/resolv.conf --exclude=/etc/hosts --one-file-system / >"$TMP_FILE"
docker rmi textlab/ubuntu-essential-multilayer
docker import - textlab/ubuntu-essential-nocmd <"$TMP_FILE"
docker build -t textlab/ubuntu-essential - <<'EOF'
FROM textlab/ubuntu-essential-nocmd
CMD ["/bin/bash"]
EOF
docker rmi textlab/ubuntu-essential-nocmd
rm -f "$TMP_FILE"
Create a Dockerfile for an Apache image
FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install apache2 && apt-get clean
RUN a2enmod ssl
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
EXPOSE 443
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
docker build -t droidos/apache .
Create a Dockerfile for PHP5
FROM droidos/apache
RUN apt-get update && apt-get -y --reinstall install php5 php5-redis php5-memcached php5-curl libssh2-php php5-mysqlnd php5-mcrypt && apt-get clean
RUN php5enmod mcrypt
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
EXPOSE 443
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
docker build -t droidos/php5 .
Create a Dockerfile for memcached and build the image
FROM textlab/ubuntu-essential
# Install packages
RUN DEBIAN_FRONTEND=noninteractive apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install memcached
# memcached public variable
EXPOSE 11211
CMD ["/usr/bin/memcached", "-u", "memcache", "-v"]
docker build -t droidos/memcached .
Fireup a docker container with memcached
docker run -d -P --name memcached droidos/memcached
Fireup a docker container with apache and link it to the memcached container created earlier
docker run -d --name apache --link memcached:memcached -v /var/droidos/site:/var/www/html -v /var/droidos/logs:/var/log/apache2 -p 8080:80 droidos/php5
Browse to example.com:8080
Everything seems ok
Create a memcached test script in /var/droidos/site
<?php
error_reporting(E_ALL);
header('Content-type:text/plain');
$mc = new Memcached();
$mc->addServer("localhost", 11211);
$flag = $mc->add('name','droidos');
echo ($flag)?'y':'n';
echo $mc->getResultCode();
?>
This script returns n47 implying that the memcached server is disabled.
Either my linking is incorrect or memcached has not been started or the memcached container port is not visible in the apache container. SSHing into the memcached container
docker exec -it <container-id> /bin/bash
and running
service memcached status
indicates that the service is not in fact running. So I start it
service memcached start
verify it has started and run the script above again. No joy - I still get an n47 reply rather than the y0 I would like to see. Clearly, I am missing a step somewhere here. I'd be most obliged to anyone who might be able to tell me what that might be.
I think it fails because you're trying to access memcached from the apache container connecting to the localhost of the apache container, while the memcached container is made accessible to the apache one on a different IP address.
This is the line I think is wrong:
$mc->addServer("localhost", 11211);
When you link containers, Docker adds a host entry for the source container to the /etc/hosts file (see the docs about linking).
Therefore you should be able to connect from the apache container to the memcached one using this PHP command:
$mc->addServer("memcached", 11211);
If it doesn't work, check that you can connect to the memcached service from the memcached container itself.

Categories