I have the problem of my app in Heroku, my set up is Nginx, Docker and Php, and a simple Php script. after issuing release command in Heroku CLI and open the app, my app launches in browser but it crashes.
here is the log.
2020-05-30T15:46:38.733789+00:00 heroku[web.1]: State changed from crashed to starting
2020-05-30T15:46:51.620126+00:00 heroku[web.1]: Starting process with command `nginx -g daemon\ off\;`
2020-05-30T15:47:52.178537+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2020-05-30T15:47:52.210903+00:00 heroku[web.1]: Stopping process with SIGKILL
2020-05-30T15:47:52.317640+00:00 heroku[web.1]: Process exited with status 137
2020-05-30T15:47:52.373907+00:00 heroku[web.1]: State changed from starting to crashed
Dockerfile
FROM ubuntu:latest
RUN apt-get update \
&& apt-get install -y curl zip unzip \
php7.4 php7.4-fpm \
nginx
COPY ./webapp /var/www/myapp
WORKDIR /var/www/myapp
# ADD default.conf /etc/nginx/conf.d/default.conf
COPY default.conf.template /etc/nginx/conf.d/default.conf.template
COPY nginx.conf /etc/nginx/nginx.conf
# for ubuntu
RUN useradd -m myuser
USER myuser
CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'
UPDATE
After adding port as what suggested in the comment, now new error occurs
/bin/bash: envsubst: command not found
As mentioned in your Dockerfile for CMD, you are $PORT and you have to pass that environment variable in your Dockerfile or while running the container.
CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'
If you want to supply in Dockerfile,
FROM ubuntu:latest
ENV PORT=80 # Add this line
...
...
CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'
or If you want to override at runtime, pass it with docker run command
docker run -e PORT=8008 imageName
Related
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!
I am running a containerized web based application on AWS ECS fargate for a few months now. But due to few issues with AWS my team planned to take it multicloud with GCP. So when deploy my container image on GCP Cloud Run it gives me this errors
ERROR: [pool www] failed to write the ACL of the socket '/run/php-fpm/www.sock': Operation not permitted (1)"
ERROR: FPM initialization failed
Then i tried to change permission make of /run/php-fpm using
chmod 777 -R /run/php-fpm
It again shows me same error
After than i run the container locally and exec into the container to check the www.sock file, its permission was
srw-rw----+ root root www.sock
and the permission of /run/php-fpm was
drwxrwxrwx. root root php-fpm
After that i tried to change permissions with
chmod 777 -R /run/php-fpm/*
in the docker file but it gives me an error that file doesn't exists
I also tried using setfacl but when i exec into container and check it locally the permission off www.sock is not changed and give same error when deployed on cloud run
I don't want to move to azure so i need the solution for cloud run only. I am using port 80 to expose to docker file
Here is my dockerfile
FROM amazonlinux:2
# Environment variables
ENV PORT 80
# Install dependencies
RUN amazon-linux-extras install php7.2
RUN yum clean metadata && yum update -y && \
yum install -y \
curl \
httpd httpd-tools\
git \
openssh-server \
openssh-clients \
php-cli php-pdo php-fpm php-json \
php-bcmath \
php-cli \
php-common \
php-dba \
php-devel \
php-embedded \
php-enchant\
php-gd\
php-intl \
php-lda\
php-mbstrin\
php-mysqlnd \
php-odbc \
php-pd\
php-pear.noarch \
php-pgsql\
php-process \
php-pspel \
php-recode \
php-snmp \
php-soap \
php-xml \
php-xmlrpc \
php-mbstring \
unzip \
&& ln -s /usr/sbin/httpd /usr/sbin/apache2 \
&& curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer \
&& ln -s /usr/local/bin/composer /usr/bin/composer
COPY github_key .
COPY httpd.conf /etc/httpd/conf/httpd.conf
# Install app
RUN rm -rf /var/www/html/* && mkdir -p /var/www/html
# git clone command
#few sed commands
WORKDIR /var/www/html/
RUN composer require mpdf/mpdf && \
chmod 777 -R vendor/mpdf/mpdf/tmp
EXPOSE $PORT
ENTRYPOINT ["sh", "-c", "/usr/sbin/php-fpm && /usr/sbin/apache2 -DFOREGROUND"]
Well after alot of searching and hit n trail i got the solution.
Most of solutions online recommend set values in /etc/php-fpm.d/www.conf to
;listen.owner = nginx
;listen.group = nginx
listen.acl_users = apache, nginx
listen.acl_groups = apache, nginx
But this does NOT WORK
For perfect deployment on Cloud Run we have to comment listen.acl_users and listen.acl_groups
;listen.acl_users = apache, nginx
;listen.acl_groups = apahce, nginx
For that i am using sed command in Dockerfile
RUN sed -i 's/listen.acl_users/;listen.acl_users/g' /etc/php-fpm.d/www.conf
RUN sed -i 's/listen.acl_groups/;listen.acl_groups/g' /etc/php-fpm.d/www.conf
After that my app will perfectly deployed on Cloud Run but started giving error on AWS ECS Fargate. So, i end up making 2 different Dockerfiles for each service.
I'm trying to run php-fpm in gitpod.io. But when I run following command...
service php7.1-fpm start
...Gitpod console return a permission error, I can't use sudo in gitpod console.
What can i do to fix that issue.
Error:> mkdir: cannot create directory ‘/run/php’: Permission denied . That error are show in my gitpod console
My dockerfile :
FROM gitpod/workspace-full:latest
# optional: use a custom Nginx config.
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./docker-run.sh /
# optional: change document root folder. It's relative to your git working copy.
ENV NGINX_DOCROOT_IN_REPO="www"
USER root
RUN apt-get update \
&& apt-get -y install mysql-server mysql-client \
&& apt-get -y install php-fpm php-cli php-bz2 php-bcmath php-gmp php-imap php-shmop php-soap php-xmlrpc php-xsl php-ldap \
&& apt-get -y install php-amqp php-apcu php-imagick php-memcached php-mongodb php-oauth php-redis\
&& apt-get clean && rm -rf /var/cache/apt/* /var/lib/apt/lists/* /tmp/*
RUN mkdir /var/run/mysqld \
&& chown -R gitpod:gitpod /var/run/mysqld /usr/share/mysql /var/lib/mysql /var/log/mysql /etc/mysql
COPY ./my.cnf /etc/mysql/my.cnf
RUN mysqld --daemonize --skip-grant-tables \
&& sleep 3 \
&& ( mysql -uroot -e "USE mysql; UPDATE user SET authentication_string=PASSWORD(\"root\") WHERE user='root'; UPDATE user SET plugin=\"mysql_native_password\" WHERE user='root'; FLUSH PRIVILEGES;" ) \
&& mysqladmin -uroot -proot shutdown;
EXPOSE 80 443
Sorry for my english is verry bad.
I'm not familiar with php-fpm therefore I'm not able to test if my solution runs correctly. However, I'm able to start php-fpm in Gitpod when I change the paths in the php-fpm config files to locations the user gitpod is allowed to write to.
You'll find the configuration of php-fpm in /etc/php/7.2/fpm/ (you may have to change the version number if you use 7.1). I created a simple config file where the pid file, the socket file and the log file will be written to /tmp/, a location the user gitpod is allowed to write files to:
[global]
pid = /tmp/php7.2-fpm.pid
error_log = /tmp/php7.2-fpm.log
[www]
listen = /tmp/php7.2-fpm.sock
listen.owner = gitpod
listen.group = gitpod
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Now, you can start the php-fpm daemon like this:
/usr/sbin/php-fpm7.2 --fpm-config php-fpm.conf
After that, you can check that the daemon is running by ps -aux. There you'll find something like this:
gitpod 3342 0.0 0.0 234512 11524 ? Ss 14:34 0:00 php-fpm: master process (php-fpm.conf)
gitpod 3343 0.0 0.0 234644 5812 ? S 14:34 0:00 php-fpm: pool www
gitpod 3344 0.0 0.0 234644 5812 ? S 14:34 0:00 php-fpm: pool www
You can find a working example here.
I hope that works for you.
Cornelius
PS: If this answers your question please consider to write a comment to your reddit post with a link to this answer so that the reddit users know that the problem is solved already.
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.
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.