Deploy a Dockerized Laravel app using Apache on Heroku - laravel

I'm trying to deploy a Laravel 5.5 app using Docker on Heroku. I'm coming up against the problem where Heroku dynamically assigns the $PORT value though, and I can't figure out where to tell Apache to use $PORT instead of port 80. Has anyone else had success deploying an app using Apache in Docker to Heroku with the $PORT specification?
To be specific, this is the error I get tailing the Heroku logs:
2019-01-31T14:01:17.605297+00:00 app[web.1]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
which I understand to mean that the container is trying to listen on Port 80, but the host is using $PORT instead of 80.
Here's my Dockerfile:
FROM php:7.1.5-apache
#install all the system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
mcrypt \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
zip \
opcache
ENV PHPREDIS_VERSION 3.0.0
RUN mkdir -p /usr/src/php/ext/redis \
&& curl -L https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& echo 'redis' >> /usr/src/php-available-exts \
&& docker-php-ext-install redis
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to laravel /var/www/html/public folder
RUN sed -i -e "s/html/html\/public/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
COPY . $APP_HOME
# install all PHP dependencies
RUN composer install --no-interaction
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
And here's my Heroku Procfile:
web: vendor/bin/heroku-php-apache2 public/
And here's my heroku.yml:
build:
docker:
web: Dockerfile
Thanks!

Got it.
Using this SO post, I discovered I could insert a CMD statement at the end of my Dockerfile to sed replace the ports in my apache config files to the magical $PORT environment variable at run time.
New Dockerfile below:
#start with our base image (the foundation) - version 7.1.5
FROM php:7.1.5-apache
#install all the system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
mcrypt \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
zip \
opcache
ENV PHPREDIS_VERSION 3.0.0
RUN mkdir -p /usr/src/php/ext/redis \
&& curl -L https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& echo 'redis' >> /usr/src/php-available-exts \
&& docker-php-ext-install redis
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to laravel /var/www/html/public folder
RUN sed -i -e "s/html/html\/public/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
COPY . $APP_HOME
# install all PHP dependencies
RUN composer install --no-interaction
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
#update apache port at runtime for Heroku
ENTRYPOINT []
CMD sed -i "s/80/$PORT/g" /etc/apache2/sites-enabled/000-default.conf /etc/apache2/ports.conf && docker-php-entrypoint apache2-foreground

Related

Laradock - Service 'php-fpm' failed to build

Info:
OS: Ubuntu 16.04
Docker version: 20.10.6
Commit: 63fc1fd
Project versions:
Laravel 5.8.33
Vue 2.6.10
My Laravel docker environment stopped working today.
After several tries I finally deleted all images and tried to rebuild environemt.
I get the same error:
+ apt-get install -yqq apt-utils libzip-dev zip unzip
E: Unable to correct problems, you have held broken packages.
ERROR: Service 'php-fpm' failed to build: The command '/bin/sh -c set -xe; apt-get update -yqq && pecl channel-update pecl.php.net && apt-get install -yqq apt-utils libzip-dev zip unzip && docker-php-ext-configure zip --with-libzip && docker-php-ext-install zip && php -m | grep -q 'zip'' returned a non-zero code: 100
Here is the code of my php-fpm Docker file.
Any idea what is wrong?
in Dockerfile
you can add:
FROM composer AS composer
COPY . /app
RUN rm composer.lock && composer install
--optimize-autoloader
--no-interaction
--no-progress
--ignore-platform-reqs
RUN apk add --no-cache php
php7-common
php7-fpm
php7-pdo
php7-opcache
php7-zip \
did you add
RUN apk add --no-cache php
php7-common
php7-fpm \
try this
FROM composer AS composer
COPY . /app
RUN rm composer.lock && composer install \
--optimize-autoloader \
--no-interaction \
--no-progress \
--ignore-platform-reqs
RUN chmod 777 -R storage
FROM alpine:3.13
LABEL Maintainer="Diki Rahman <diki#sawala.tech>"
RUN apk add --no-cache php \
php7-common \
php7-fpm \
php7-pdo \
php7-opcache \
php7-zip \
php7-phar \
php7-iconv \
php7-cli \
php7-curl \
php7-openssl \
php7-mbstring \
php7-tokenizer \
php7-fileinfo \
php7-json \
php7-xml \
php7-xmlwriter \
php7-simplexml \
php7-dom \
php7-pdo_mysql \
php7-pdo_pgsql \
php7-pdo_sqlite \
php7-tokenizer \
php7-pecl-redis \
nginx supervisor curl
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY docker/php-fpm/fpm-pool.conf /etc/php7/php-fpm.d/www.conf
COPY docker/php/php.ini /etc/php7/conf.d/timezone.ini
COPY docker/supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x docker-entrypoint.sh
RUN mkdir -p /var/www/html
RUN mkdir -p /var/www/backend
RUN chown -R nginx.nginx /var/www/html && \
chown -R nginx.nginx /run && \
chown -R nginx.nginx /var/lib/nginx && \
chown -R nginx.nginx /var/log/nginx
WORKDIR /var/www/html
COPY --chown=nginx --from=composer /app /var/www/html
COPY --chown=nginx --from=composer /app /var/www/backend
EXPOSE 8080
ENTRYPOINT ["/docker-entrypoint.sh"]
HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping

Logs directory permission denied error when running Artisan commands

I have a setup of docker with laravel and apache alongside mysql, when trying to run artisan command in the terminal of vscode i get :
There is no existing directory at "/var/www/html/storage/logs" and its not buildable: Permission denied
Apache setup in docker compose:
laravel-app:
build:
context: ./docker/app
args:
uid: ${UID}
container_name: laravel-app
environment:
- APACHE_RUN_USER=#${UID}
- APACHE_RUN_GROUP=#${UID}
volumes:
- .:/var/www/html
ports:
- ${HOST_PORT}:80
networks:
backend:
aliases:
- laravel-app
Dockerfile of apache
FROM php:7.2-apache
RUN apt-get update
# 1. development packages
RUN apt-get install -y \
git \
zip \
curl \
sudo \
unzip \
libicu-dev \
libbz2-dev \
libpng-dev \
libjpeg-dev \
libmcrypt-dev \
libreadline-dev \
libfreetype6-dev \
g++
# 2. apache configs + document root
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# 3. mod_rewrite for URL rewrite and mod_headers for .htaccess extra headers like Access-Control-Allow-Origin-
RUN a2enmod rewrite headers
# 4. start with base php config, then add extensions
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN docker-php-ext-install \
bz2 \
intl \
iconv \
bcmath \
opcache \
calendar \
mbstring \
pdo_mysql \
zip
# 5. composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# 6. we need a user with the same UID/GID with host user
# so when we execute CLI commands, all the host file's ownership remains intact
# otherwise command from inside container will create root-owned files and directories
ARG uid
RUN useradd -G www-data,root -u $uid -d /home/devuser devuser
RUN mkdir -p /home/devuser/.composer && \
chown -R devuser:devuser /home/devuser
even though the directory exists, also the commands run successfully from within the container. Should i always run the commands related to laravel artisan from the container, or there is something wrong?
Go to your project folder and open terminal
then,
run this command
sudo chmod -R 775 storage

Excecute .sh file on start of Docker container and let container run

I have a docker container that serves a webserver. On every startup of the container, I want to excecute a little shell script. The script that has to be executed has only one statement.
/var/www/html/app/Console/cake schema update -y
To achieve this, I created a .sh file called schemaupdate.sh which I copy into the docker container using the dockerfile into the /etc/init.d folder. Furthermore I make it executable and register it to the startup.
COPY schemaupdate.sh /etc/init.d/schemaupdate.sh
chmod 755 /etc/init.d/schemaupdate.sh
update-rc.d schemaupdate.sh defaults
The file is successfully copied into the container. However, the script is not executed when the docker container starts. When I manually call the sh file, everything is running fine.
How can I achieve, that the file / statement is executed on each startup of a container? It is important, that the script is executed at the startup and the container (so the webserver) still continues to run! The script only makes a little update check and after the check the webserver keeps on going.
The container is a debian based container. Here is inital dockerfile.
#start with base Image from php
FROM php:7.3-apache
#install system dependencies and enable PHP modules
RUN apt-get update && apt-get install -y \
libicu-dev \
libpq-dev \
libmcrypt-dev \
mysql-client \
git \
zip \
unzip \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install \
intl \
mbstring \
pcntl \
pdo_mysql \
pdo_pgsql \
pgsql \
opcache
# zip \
# mcrypt \
#configure imap for mails
RUN apt-get update && \
apt-get install -y \
libc-client-dev libkrb5-dev && \
rm -r /var/lib/apt/lists/*
RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \
docker-php-ext-install -j$(nproc) imap
#install mcrypt
RUN apt-get update \
&& apt-get install -y libmcrypt-dev \
&& rm -rf /var/lib/apt/lists/* \
&& pecl install mcrypt-1.0.2 \
&& docker-php-ext-enable mcrypt
#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
#set our application folder as an environment variable
ENV APP_HOME /var/www/html
#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data
#change the web_root to cakephp /var/www/html/webroot folder
#RUN sed -i -e "s/html/html\/webroot/g" /etc/apache2/sites-enabled/000-default.conf
# enable apache module rewrite
RUN a2enmod rewrite
#copy source files and run composer
#COPY src/ /var/www/html
#COPY src/ $APP_HOME
# install all PHP dependencies
#RUN composer install --no-interaction
#SET Volume
VOLUME /var/www/html/
#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
#SET ENV VARIABLES
COPY schemaupdate.sh /etc/init.d/schemaupdate.sh
chmod 755 /etc/init.d/schemaupdate.sh
update-rc.d schemaupdate.sh defaults
EXPOSE 80
/etc/init.d/ isn't relevant. Containers aren't full blown operating systems with a heavyweight SysV init-style startup sequence. They run a single command, that's it.
You should either add the command as a RUN statement in the Dockerfile so its results are baked into the image, or you should have it called directly by the container's CMD or ENTRYPOINT directive.
I Finally used the Entrypoint. I deleted the COPY, chmod and update-rc. The Entrypoint looks like the following.
ENTRYPOINT [ "sh", "-c", "/var/www/html/app/Console/cake schema update -y && /var/www/html/app/Console/cake schema update -y && /usr/sbin/apachectl -D FOREGROUND"]
It first starts the update statment. After this is finished (so terminated), the apachectl is called to keep the webserver running.

Docker bash file will not load

I'm new to docker and I try to build a php-fpm container which should include sendmail as well
having the following configuration
# php-fpm
FROM php:7.2-fpm
RUN apt-get update && apt-get install -y sendmail sendmail-bin mailutils openssl git libcurl4-gnutls-dev libpng-dev libfreetype6-dev libjpeg62-turbo-dev zlib1g-dev libicu-dev g++ libxml2-dev libpq-dev \
# && git clone -b php7.2 https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis \
&& docker-php-ext-install pdo pdo_mysql pdo_pgsql pgsql intl curl json opcache xml zip mysqli mbstring \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& apt-get autoremove && apt-get autoclean \
&& rm -rf /var/lib/apt/lists/* \
RUN yes | pecl install xdebug \
# configure sendmail
COPY ./*.sh /usr/local/bin/
COPY ./php_mail.ini /usr/local/etc/php/conf.d/mail.ini
RUN chmod a+x /usr/local/bin/*.sh
ENTRYPOINT ["start_sendmail_mta.sh"]
RUN update-ca-certificates
ENV PHP_DATE_TIMEZONE="Europe/Berlin" \
PHP_LOG_ERRORS_MAX_LEN=1024 \
PHP_LOG_ERRORS="" \
PHP_MAX_EXECUTION_TIME=0 \
PHP_MAX_FILE_UPLOADS=20 \
PHP_MAX_INPUT_VARS=1000 \
PHP_MEMORY_LIMIT=128M \
PHP_POST_MAX_SIZE=8M \
#PHP_SENDMAIL_PATH="/usr/sbin/sendmail -t -i" \
PHP_SESSION_SAVE_HANDLER=files \
PHP_SESSION_SAVE_PATH="" \
PHP_UPLOAD_MAX_FILESIZE=2M \
PHP_XDEBUG_DEFAULT_ENABLE=0 \
PHP_XDEBUG_IDEKEY=''\
PHP_XDEBUG_PROFILER_ENABLE=0 \
PHP_XDEBUG_REMOTE_AUTOSTART=0 \
PHP_XDEBUG_REMOTE_CONNECT_BACK=0 \
PHP_XDEBUG_REMOTE_ENABLE=0 \
PHP_XDEBUG_REMOTE_HOST=0
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
CMD ["php-fpm"]
EXPOSE 9000
when I run docker-compose buildI get the following error
Service 'php-fpm' failed to build: The command '/bin/sh -c chmod a+x /usr/local/bin/*.sh' returned a non-zero code: 1
[![enter image description here][2]][2]
Why are the bash files not found in this case?
chmod: cannot access '/usr/local/bin/*.sh': No such file or directory
ERROR: Service 'php-fpm' failed to build: The command '/bin/sh -c chmod a+x /usr/local/bin/*.sh' returned a non-zero code: 1
if I run RUN ls -l /usr/local/bin I can not see any bash files
Just change copy ./*.sh to:
COPY sendmail.sh /usr/local/bin/
COPY ./php_mail.ini /usr/local/etc/php/conf.d/mail.ini
COPY start_sendmail_mta.sh /usr/local/bin
RUN chmod a+x /usr/local/bin/*.sh

ERR_EMPTY_RESPONSE with docker-compose of a Laravel app

I have a Laravel / VueJS app that I am trying to dockerize.
At the end of the Dockerfile, I have
CMD php artisan serve --host=0.0.0.0 --port=80
my docker-compose:
version: '3'
services:
app:
image: xoco/kendozone:local-1.0.1
ports:
- "8181:80"
When I run:
docker-compose up
I get:
Recreating local_app_1 ... done
Attaching to local_app_1
app_1 | [03-May-2018 18:20:21] NOTICE: fpm is running, pid 1
app_1 | [03-May-2018 18:20:21] NOTICE: ready to handle connections
that seems to be ok
But when I try to access it on
localhost:8181
I get a ERR_EMPTY_RESPONSE
Any idea how to fix it ?
EDIT: Add Dockerfile
FROM php:7.2-fpm
LABEL version="1.0.0"
ENV node_version 8.4.0
ENV npm_version 5.7.1
ENV NVM_DIR /.nvm
ENV APP_DIR="/var/www"
ENV APP_PORT="80"
ENV DOCKER_FOLDER="docker/local"
RUN echo "deb http://ftp.de.debian.org/debian stretch main " >> /etc/apt/sources.list \
&& apt-get update -y
RUN apt-get install -y openssl zip unzip git gcc make automake \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libmagickwand-dev vim --no-install-recommends
RUN apt-get purge --auto-remove -y g++ \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install pdo pdo_mysql mbstring zip -j$(nproc) iconv -j$(nproc) gd
WORKDIR $APP_DIR
COPY . $APP_DIR
RUN mkdir -p $APP_DIR/resources/assets/less/_main_full \
&& touch $APP_DIR/resources/assets/less/_main_full/main.less \
&& touch $APP_DIR/database/sqlite.db \
&& mv $DOCKER_FOLDER/.env.local .env \
&& chown -R www-data:www-data $APP_DIR
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-interaction
RUN mkdir -p $NVM_DIR && chown -R www-data:www-data $NVM_DIR
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash \
&& [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" \
&& nvm install ${node_version}
ENV NODE_PATH $NVM_DIR/v$node_version/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$node_version/bin:$PATH
RUN npm install --save-exact imagemin-pngquant#5.0.*
RUN npm install
RUN npm run production
RUN php artisan key:generate
RUN php artisan migrate --seed
CMD php artisan serve --host=0.0.0.0 --port=$APP_PORT

Resources