How do I make my container sync the files I make? (docker) - php

I'm making a web application using Laravel 7 but I want to develop it in docker, but when I am using my container, the container files are not synchronized with the ones that are shown in the text editor, how can I solve that?
The files that are not synchronized are, for example, the migrations or the composer.json, that is, when I install a package through composer, those changes are not reflected in the text editor
I've tried to put ./:/var/www/html in docker-compose.yml but I get an error when I run it. Warning: require(/var/www/html/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/artisan on line 18 Fatal error: require(): Failed opening required '/var/www/html/vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/html /artisan online 18
Next, I provide my dockerfile and my docker compose.
Dockerfile
FROM composer:1.10.22 as build_stage
LABEL maintainer="Me"
COPY . /src
ADD .env.example /src/.env
WORKDIR /src
RUN composer install --no-ansi --no-interaction --no-progress --no-scripts --optimize-autoloader --ignore-platform-reqs
RUN php artisan key:generate
FROM php:7-fpm-alpine
ENV \
BUILD_PACKAGES="build-base curl-dev linux-headers" \
SQLITE_PACKAGES="zlib-dev libxml2-dev libxslt-dev postgresql postgresql-dev sqlite sqlite-libs sqlite-dev nano php7-gd php7-mysqli php7-zlib php7-curl"
RUN apk update && apk add $BUILD_PACKAGES && apk add $SQLITE_PACKAGES
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN set -ex \
&& apk --no-cache add \
postgresql-dev
RUN docker-php-ext-install pdo pdo_pgsql
COPY --from=build_stage /src /var/www/html
RUN chmod -R 777 /var/www/html
EXPOSE 5000
COPY ./run.sh /tmp
RUN chmod +x /tmp/run.sh
ENTRYPOINT ["/tmp/run.sh"]
docker-compose.yml
version: "3.4"
networks:
project-net:
volumes:
project-datastore:
services:
postgres-db:
image: postgres:11-alpine
volumes:
- project-datastore:/var/lib/postgresql/data
networks:
- project-net
ports:
- "25432:5432"
environment:
POSTGRES_DB: db
POSTGRES_USER: user
POSTGRES_PASSWORD: password
project:
build:
context: ./
image: project:latest
volumes:
- ./app:/var/www/html/app
- ./public:/var/www/html/public
- ./routes:/var/www/html/routes
- ./resources:/var/www/html/resources
depends_on:
- postgres-db
networks:
- project-net
ports:
- "5000:5000"
environment:
DATABASE_URL: postgres://user:password#postgres-db:5432/db
run.sh
cp /usr/share/zoneinfo/America/Mexico_City /etc/localtime
php artisan serve --host=0.0.0.0 --port=5000

Related

Database migration fails in entrypoint.sh during docker-compose up

I am new to Docker and trying to dockerize the project I am working on, which is a simple Symfony API with a MySql database.
I want docker to execute the DB migration php bin/console doctrine:migrations:migrate when it builds the container, so I added an entrypoint to do so:
entrypoint.sh
#create or update db
php bin/console doctrine:migrations:migrate --no-interaction
# start apache
apache2-foreground
Then when I run docker-compose up -d everything works fine but database is not migrated. When I enter the container I can manually execute the doc:mig:mig command but how do I get this done automatically? Am I not understanding the usage of entrypoint properly?
Here is my docker-compose.yaml file (substituted sensitive data)
version: '3.7'
services:
api:
build: .
ports:
- 8000:80
links:
- db
volumes:
- C:/Repos/myProjectName/src:/var/www/myProjectName_api/src
db:
image: 'mysql:8.0'
container_name: mysql
environment:
MYSQL_USER: myUserName
MYSQL_PASSWORD: myPwd
MYSQL_ROOT_PASSWORD: myRootPwd
MYSQL_DATABASE: dev_myProjectName
volumes:
- ./mysql:/var/lib/mysql
command: ["--default-authentication-plugin=mysql_native_password"]
ports:
- "3307:3306"
and my Dockerfile
FROM php:8.1-apache
RUN a2enmod rewrite
RUN apt-get update \
&& apt-get install -y libzip-dev git wget nano --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN docker-php-ext-install pdo
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install zip
RUN wget https://getcomposer.org/download/2.4.2/composer.phar \
&& mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer
COPY docker/apache.conf /etc/apache2/sites-enabled/000-default.conf
COPY . /var/www/myProjectName_api
RUN chown -R www-data:www-data /var/www/myProjectName_api/var
# Allow Authorization header
RUN echo 'SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1' >> /etc/apache2/apache2.conf
COPY environments/.env.dev /var/www/myProjectName_api/.env.local
WORKDIR /var/www/myProjectName_api
COPY docker/entrypoint.sh /tmp
RUN chmod +x /tmp/entrypoint.sh
ENTRYPOINT /tmp/entrypoint.sh

Laravel Swoole Docker "There are no commands defined in the "swoole" namespace"

So, I want to configure the swoole laravel project. I run a Dockerfile and it successfully run. Then I want to run compose file this give me error
There are no commands defined in the "swoole" namespace.
This is my first experience with swoole. And I don't understand what is the problem.
How can solve this problem?
This is a Dockerfile
FROM php:8.1-fpm-alpine
# Install laravel requirement PHP package
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS libzip-dev sqlite-dev \
libpng-dev libxml2-dev oniguruma-dev libmcrypt-dev curl curl-dev libcurl postgresql-dev
RUN docker-php-ext-install -j$(nproc) gd bcmath zip pdo_mysql pdo_pgsql
RUN pecl install xdebug swoole && docker-php-ext-enable swoole
# Install composer
ENV COMPOSER_HOME /composer
ENV PATH ./vendor/bin:/composer/vendor/bin:$PATH
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN curl -s https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer
# Install PHP_CodeSniffer
WORKDIR /app
COPY ./ ./
USER root
RUN chown -R www-data /app/storage
RUN chmod -R ug+w /app/storage
RUN chmod 777 -R /app/storage
RUN chmod 777 -R /app/public
RUN composer install
RUN php artisan optimize
CMD php artisan swoole:http start
EXPOSE 1215
And this is a docker-compose.yaml file
version: "3.7"
services:
app:
build:
args:
user: www-data
uid: 1000
context: ./
dockerfile: Dockerfile
image: topspot-swoole-image
container_name: topspot-swoole-container
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- topspot-network
nginx:
image: nginx:alpine
container_name: topspot-nginx
restart: unless-stopped
ports:
- 80:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- topspot-network
networks:
topspot-network:
driver: bridge
Solved
I solved it. Firstly install the swoole and publish to a local project. Then run the container and the composer saw the Swoole packages.

From which Dockerfile should composer install be called from

I need to call composer install and unsure from which Dockerfile to call it from - Dockerfile-apache or Dockerfile-php-fpm?
Should I install composer in Dockerfile-apache (and PHP CLI?) and run it from there?
Running composer install from Dockerfile-php-fpm gives me this: Composer could not find a composer.json file in /var/www/html
Docker-php-fpm
# Do we target a specific version? ie. 7.4.25?
FROM php:7.4-fpm
# Need to add zip and other extensions
RUN buildDeps=" \
libonig-dev \
libzip-dev \
libxml2-dev \
" \
&& apt-get -y update \
&& apt-get install -y $buildDeps zip libicu-dev \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl mbstring json mysqli opcache pdo pdo_mysql xml \
&& apt-get purge -y --auto-remove $buildDeps \
&& rm -r /var/lib/apt/lists/*
# Copying of base conf files
COPY docker/php-fpm/conf/php-fpm.conf /usr/local/etc
COPY docker/php-fpm/conf/php.ini-development /usr/local/etc/php/php.ini
COPY docker/php-fpm/conf/www.conf /usr/local/etc/php-fpm.d
# Install Composer.
RUN curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/ \
&& ln -s /usr/local/bin/composer.phar /usr/local/bin/composer
EXPOSE 9000
Docker-apache:
FROM httpd:2.4
# Copy config files
COPY docker/apache/conf/httpd.conf /usr/local/apache2/conf
COPY docker/apache/conf/httpd-vhosts.conf /usr/local/apache2/conf/extra
# Do something about log rotate?
# Create vhost directory
WORKDIR /var/www/html
#Set our application folder as an environment variable
ENV APP_HOME /var/www/html
#copy files
COPY bin ${APP_HOME}/bin
COPY config ${APP_HOME}/config
COPY plugins ${APP_HOME}/plugins
COPY src ${APP_HOME}/src
COPY webroot ${APP_HOME}/webroot
COPY .htaccess ${APP_HOME}
COPY index.php ${APP_HOME}
COPY composer.json ${APP_HOME}
COPY composer.lock ${APP_HOME}
Edit #1
docker-compose.yml
version: "3.2"
services:
php-fpm:
container_name: php-fpm
build:
context: .
dockerfile: Dockerfile-php-fpm
networks:
- backend
ports:
- "9000:9000"
apache:
container_name: httpd
build:
context: .
dockerfile: Dockerfile-apache
depends_on:
- php
networks:
- frontend
- backend
ports:
- "80:80"
- "443:443"
networks:
frontend:
backend:
Edit #2
This docker-compose file enables the communication via a common volume. I just need to compile, build and copy the files in Apache at this point.
version: "3.9"
services:
php-fpm:
container_name: php-fpm
build:
context: .
dockerfile: Dockerfile-php-fpm
volumes:
- mydata:/var/www/html:rw
networks:
- backend
ports:
- "9000:9000"
apache:
container_name: httpd
build:
context: .
dockerfile: Dockerfile-apache
depends_on:
- php
volumes:
- mydata:/var/www/html:rw
networks:
- frontend
- backend
ports:
- "80:80"
- "443:443"
networks:
frontend:
backend:
volumes:
mydata:
I would go with neither of the above; instead, run composer install locally and copy the resulting vendor directory as part of your application.
Fetching dependencies is fundamentally part of building an application, not part of running it, so Composer shouldn't even be installed on a production host or container. If you were writing a C application which needed to be compiled with gcc, you would run that as an earlier step, and then copy the binary into the container; composer install can be treated the same way.
So for instance, you might have a build script (to run manually, or in a CI server like Jenkins, Github Actions, Azure DevOps, etc) that went through the following steps:
Clone the repo from a git repository
Check out the latest tag
Run composer install
Run a script to minify the client-side JS
Run docker-composer, copying the source code, minified JS, and vendor directory
The software inside the Docker container therefore only needs to be able to run the application, not build it.

docker entrypoint sh file restarting

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

GitLab CI/CD - vendor directory on nginx container

I try write CI/CD for symfony, but i have problem with vendor directory. App is copied right, but i don't have vendor. I tried various ways but nothing works. Locally, as instead of variables with the image name, I will give the image name, it all works fine.
My .gitlab-ci.yml
image: tiangolo/docker-with-compose
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
IMAGE_TAG: $CI_REGISTRY_IMAGE/demo:$CI_COMMIT_REF_NAME
IMAGE_PHP_PROD: $CI_REGISTRY_IMAGE/demo:$CI_COMMIT_SHA
IMAGE_NGINX_PROD: $CI_REGISTRY_IMAGE/demo-nginx:latest
VERSION: $CI_COMMIT_SHA
stages:
- build
- deploy
before_script:
- apk add --no-cache python3 python3-dev py3-pip libffi-dev openssl-dev gcc libc-dev make
- docker login -u $CI_USER -p $CI_PASSWORD registry.gitlab.com
# build:
# stage: build
# script:
# - docker build --pull -t $IMAGE_TAG deploy
# - docker push $IMAGE_TAG
production images:
stage: build
script:
- docker build . -f deploy/php/Dockerfile -t $IMAGE_PHP_PROD
- docker push $IMAGE_PHP_PROD
- docker build . -f deploy/Dockerfile-nginx-prod -t $IMAGE_NGINX_PROD
- docker push $IMAGE_NGINX_PROD
pull:
stage: deploy
tags:
- prod
script:
- docker pull $IMAGE_PHP_PROD
- docker pull $IMAGE_NGINX_PROD
production:
stage: deploy
tags:
- deploy
before_script:
script:
- docker-compose -f deploy/docker-compose.yml up -d
docker-compose.yml
version: '3'
services:
nginx:
container_name: sf_nginx
image: $IMAGE_NGINX_PROD
restart: on-failure
ports:
- '81:80'
depends_on:
- php
php:
container_name: sf_php
image: $IMAGE_PHP_PROD
restart: on-failure
user: 1000:1000
Dockerfile for php
FROM php:7.4-fpm
RUN docker-php-ext-install pdo_mysql
RUN pecl install apcu
RUN apt-get update && \
apt-get install -y \
libzip-dev
RUN docker-php-ext-install zip
RUN docker-php-ext-enable apcu
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php --filename=composer \
&& php -r "unlink('composer-setup.php');" \
&& mv composer /usr/local/bin/composer
WORKDIR /usr/src/app
COPY --chown=1000:1000 ./ /usr/src/app
RUN PATH=$PATH:/usr/src/apps/vendor/bin:bin
Dockerfile for nginx
FROM nginx
ADD ./ /usr/src/app
ADD ./deploy/nginx/default.conf /etc/nginx/conf.d/default.conf
In php container exist vendor directory. Docker-compose run, but my app not working:
Am I wrong or you are just installing composer without executing it?
After && mv composer /usr/local/bin/composer you should put && composer install --no-interaction!

Categories