I need to have supervisor for my laravel queues. But supervisor starts from root user, and I want to start php from another user for safety. I could not find solution to start php in another way, like a standart user from image - www-data.
And I also have files with backend owner. I read that it's safer to have php files with one owner and start php-fpm with another
Question: is it normal to work in producation with www-data user for php-fpm or I have to have another user for it. Or maybe I can unite php-fpm with supervisor(and cron in future) in another way? And if I have to change user how to start php with another user?
Dockerfile
FROM php:8.1-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
git \
curl \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
libonig-dev \
libxml2-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
libpq-dev \
zlib1g-dev \
libzip-dev \
supervisor \
sudo
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN pecl install -o -f redis \
&& rm -rf /tmp/pear \
&& docker-php-ext-enable redis
# Install PHP extensions
RUN docker-php-ext-install intl pdo pdo_pgsql pgsql mbstring exif pcntl bcmath gd zip
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Add user for laravel application
RUN groupadd -g 1000 backend
RUN useradd -u 1000 -ms /bin/bash -g backend backend
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=backend:backend . /var/www
RUN ["chmod", "+x", "./my_wrapper_script.sh"]
RUN ["chown", "-R", "www-data:www-data", "./storage/framework"]
RUN ["chown", "-R", "www-data:www-data", "./storage/logs"]
COPY --chown=root:root docker-compose/app/supervisor.conf /etc/supervisor/conf.d/supervisord.conf
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ./my_wrapper_script.sh
Docker-compose
version: 3.7
services:
app:
build:
context: ./
dockerfile: Dockerfile
image: didido
container_name: didido-app
restart: unless-stopped
working_dir: /var/www/
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
volumes:
- ./:/var/www
networks:
- didido
db:
image: postgis/postgis:14-3.1
restart: always
container_name: didido-db
networks:
- didido
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- ../2. Init Database:/docker-entrypoint-initdb.d
- ./data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d didido"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
nginx:
image: nginx:1.17-alpine
container_name: didido-nginx
restart: unless-stopped
tty: true
ports:
- 80:80
depends_on:
- nodejs
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d
networks:
- didido
networks:
didido:
driver: bridge
my_wrapper_script.sh
#!/bin/bash
# Start the first process
php-fpm &
# Start the second process
supervisord &
# Wait for any process to exit
wait -n
# Exit with status of process that exited first
exit $?
Related
I'm trying to run a web project from a Docker container,
when I Dockerize the application on a macBook with an intel chip, everything runs fine and I can make a call to the Docker container. But when I run the same project, with the same setup on my M2 MacBook Air, the browser returns an empty response.
("this page isn't working" --> in Chrome)
This happens even though the containers appear to be running...
(Both containers are green lit up --> in Docker Desktop)
The container makes use of an Nginx service and a php service. The .yml file looks as below:
Docker-compose.yml
version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
image: php:8.0.6-fpm
container_name: Asset-Service
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: Asset-Service
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
#Nginx Service
webserver:
image: nginx:stable
container_name: Asset-Web-Server
restart: unless-stopped
tty: true
ports:
- "8087:80"
- "4487:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
My Dockerfile is the following, even though I don't think that this file causes the problem:
Dockerfile
FROM php:8.0.6-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
USER root
RUN apt-get update && apt-get install -y \
mariadb-client-10.3 \
libcurl4-openssl-dev \
pkg-config \
libssl-dev \
libpng-dev \
libzip-dev \
libonig-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
nano
RUN pecl uninstall mongodb
RUN pecl install mongodb
RUN echo "extension=mongodb.so" >> /usr/local/etc/php/conf.d/mongodb.ini
# Clear cache
## RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
#RUN docker-php-ext-enable mongodb
# Install composer
## RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -fg 1000 www
RUN id -u 1000 >/dev/null 2>&1 || useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
The container logs look normal and the ports in the inspect tab show 0.0.0.0:8087 and 0.0.0.0:4487.
Is this a recurring issue with the apple silicon version of Docker,
and is there anything I can do about it?
I have already tried to replicate the issue on an Intel macBook, but got the desired result instead of the empty response.
On my M2 I tried reinstalling Docker and rebuilding the containers but this didn't seem to fix anything...
Nevermind this issue.
This problem occurred when trying to build the containers from the Desktop folder.
I am testing docker with my php project. Everything is ok in testing but if I add ENTRYPOINT, docker is restarting.
Here is my docker compose file
version: "3.7"
services:
#Laravel App
app:
build:
args:
user: maruan
uid: 1000
context: ./docker/7.4
dockerfile: Dockerfile
# command: sh -c "start-container.sh"
image: laravel-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- app-network
#Nginx Service
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker/7.4/nginx/conf.d:/etc/nginx/conf.d/default.conf
networks:
- app-network
#Mysl Service
db:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
networks:
- app-network
networks:
app-network:
driver: bridge
Dockerfile
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
WORKDIR /var/www
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential mariadb-client libfreetype6-dev libjpeg-dev libpng-dev libwebp-dev zlib1g-dev libzip-dev gcc g++ make vim unzip git jpegoptim optipng pngquant gifsicle locales libonig-dev \
&& docker-php-ext-configure gd \
&& docker-php-ext-install gd \
&& apt-get install -y --no-install-recommends libgmp-dev \
&& docker-php-ext-install gmp \
&& docker-php-ext-install mysqli pdo_mysql zip \
&& docker-php-ext-enable opcache \
&& apt-get autoclean -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/pear/
COPY . /var/www
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
COPY start-container.sh /usr/local/bin/start-container.sh
RUN chmod +x /usr/local/bin/start-container.sh
ENTRYPOINT ["start-container.sh"]
start-container.sh file
#!/usr/bin/env bash
set -e
cd /var/www
php artisan optimize
php artisan view:cache
#composer install && composer dump-autoload
exec "$#"
I also print log for that docker image.
Configuration cached successfully!
Route cache cleared!
Routes cached successfully!
Files cached successfully!
Compiled views cleared!
Blade templates cached successfully!
I think my error is docker container is restarting after running start-container.sh file. When I google, some people use PHP artisan script with ENTRYPOINT sh file.
What should I do not to restart again and again with ENTRYPOINT sh file?
Your entrypoint script ends with the line exec "$#". This runs the image's CMD, and is generally a best practice. However, your image doesn't have a CMD, so that command just expands to a bare exec, which causes the main container process to exit.
An image built FROM php:fpm often won't have a CMD line since the base image's Dockerfile specifies CMD ["php-fpm"]; it is enough to COPY your application code into a derived image, and the base image's CMD knows how to run it. However, setting ENTRYPOINT in a derived image resets the CMD from the base image (see the note in the Dockerfile documentation discussing CMD and ENTRYPOINT together). This means you need to repeat the base image's CMD:
ENTRYPOINT ["start-container.sh"]
CMD ["php-fpm"] # duplicated from base image, because you reset ENTRYPOINT
I'm trying to set up a development environment on my local machine which consists of caddy + PHP.
docker-compose.yaml:
version: '3'
services:
app:
build:
context: .
container_name: app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
volumes:
- ./:/var/www
- ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
webserver:
image: caddy
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/srv
- ./docker/caddy/Caddyfile/:/etc/caddy/Caddyfile
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_USER: pingr
MYSQL_DB: pingr
MYSQL_PASSWORD: pingr
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
driver: local
Dockerfile for app service:
FROM php:7.4-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libzip-dev \
libicu-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl intl
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Caddyfile:
:80 {
root * /srv/public
php_fastcgi app:9000
file_server /uploads/*
encode gzip zstd
}
This results in "File not found" when I open http://localhost.
I'm 100% sure that the problem is because root in caddyfile and volumes in app and webserver serivces are different.
When I make them the same, looks like it works. Moreover, it even doesn't matter which path I choose, I can have /var/bar for example.
But then I don't understand how it works.
In caddy image they say that the working directory is /srv. So as I get it, this is where site files should be placed.
In the Caddyfile I specify that Caddy should look at /srb/public (because I use Laravel)..
In the php-fpm image, they say that the working directory is /var/www. Which means that.. I'm not sure what does it mean. If I don't use Docker, then in my local machine I'd have caddy + php, only caddy "knows" where the source .php files are located. In case the requests asks for a .php file Caddy proxies it to php. Maybe I don't need a volume here at all?
I want to access vsphere config info from powercli script to laravel. But I do not know how to make them work together in docker. Whatever I do, the error is similar to this - The command "'pwsh' '-v'" failed. Exit Code: 127(Command not found) Working directory: /var/www/public Output: ================ Error Output: ================ sh: 1: exec: pwsh: not found
As a last resort, I am here.
docker-compose.yml:
version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
image: vapp
container_name: app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
#Nginx Service
webserver:
image: nginx:alpine
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db:
image: mysql:5.7.22
container_name: db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: vapp
MYSQL_ROOT_PASSWORD: vapp
SERVICE_TAGS: dev
SERVICE_NAME: mysql
TZ: Asia/Kolkata
volumes:
- dbdata:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
- ./mysql:/var/lib/mysql-files/
networks:
- app-network
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpMyAdmin
restart: always
ports:
- "8080:80"
environment:
MYSQL_ROOT_PASSWORD: vapp
PMA_HOST: db
external_links:
- mariadb:mariadb
volumes:
- "./phpmyadmin/sessions:/sessions"
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
Dockerfile
FROM mcr.microsoft.com/powershell:latest
WORKDIR ./
FROM php:7.4-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libonig-dev \
locales \
libzip-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
RUN snap install powershell --classic
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl mysqli
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-enable mysqli
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Controller:
//$process = new Process(['ls', '-lsa']); #This works but next one do not
$process = new Process(['pwsh', '-v']);
$process->run();
// executes after the command finishes
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
I know how the Process() method works. Above code fails.
I need help on making powershell and laravel work together in docker.
Is there anything wrong with docker configuration or the controller code in accessing powershell.
You are using multistage build in Dockerfile. It can copy artifacts, but you don't copy anything. So pwsh app doesn't copy to PHP image (to the second stage).
You could remove first stage (FROM mcr.microsoft.com/powershell:latest) and install properly Powershell inside PHP image.
For example:
RUN apt-get update && apt-get install -y \
wget
RUN wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb && \
dpkg -i packages-microsoft-prod.deb
RUN apt-get update && apt-get install -y \
powershell
PHP image use Debian 10, so here is the instruction: https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7.1#debian-10
Check pwsh inside container first:
docker exec -it app bash
pwsh
Thanks to #konstantin-bogomolov
The reason was the incorrect docker file. Powershell was not properly installed in container.
For those who stop by, Working dockerfile is below.
FROM php:7.4-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libonig-dev \
locales \
libzip-dev \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
wget \
apt-utils
# Download the Microsoft repository GPG keys
RUN wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb
# Register the Microsoft repository GPG keys
RUN dpkg -i packages-microsoft-prod.deb
# Update the list of products
RUN apt-get update
# Install PowerShell
RUN apt-get install -y powershell
# Start PowerShell
RUN pwsh
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl mysqli
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-enable mysqli
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
I am trying to dockerise my laraver 5.5 application using docker-compose.
Here's my docker-compose.yml file definition:
version: '2.1'
services:
# The Database
database:
image: mysql:5.7
restart: always
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
environment:
- "MYSQL_DATABASE=myapp"
- "MYSQL_USER=myapp"
- "MYSQL_PASSWORD=123456"
- "MYSQL_ROOT_PASSWORD=secret"
ports:
- "33061:3306"
# The Application
app:
depends_on:
database:
condition: service_healthy
build:
context: ./
dockerfile: ./docker-compose/app.dockerfile
volumes:
- ./:/var/www/html
environment:
- "DB_CONNECTION=mysql"
- "DB_HOST=database"
- "DB_PORT=3306"
- "DB_DATABASE=myapp"
- "DB_USERNAME=myapp"
- "DB_PASSWORD=123456"
ports:
- "8080:80"
and this is my ./docker-compose/app.dockerfile:
# Base image
FROM php:7.1-apache
# Configure system
RUN apt-get update && apt-get install -y \
libmcrypt-dev \
mysql-client \
zlib1g-dev \
--no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-install mcrypt pdo_mysql
# Add php.ini and apache2.conf
COPY docker-compose/php.ini $PHP_INI_DIR/php.ini
COPY docker-compose/apache2.conf /etc/apache2/apache2.conf
# Configuring Apache
RUN rm -rf /etc/apache2/sites-available/* \
&& rm -rf /etc/apache2/sites-enabled/*
# Enable rewrite module
RUN a2enmod rewrite
# Download and install composer globally
RUN curl -s http://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer
# Add vendor binaries to PATH
ENV PATH=/var/www/html/vendor/bin:$PATH
I use the following command to start up my stack:
docker-compose -d --build via the Docker Quickstart Terminal on my Windows 10.
Everything builds fine and runs (I checked via docker-compose ps). When I visit the app url, I am getting forbidden error from apache, so I decided to login to the container using docker exec -it my_app_1 /bin/bash command and I went into /var/www/html directory and noticed that it's empty.
Doesn't volume mounting works in windows?