Docker-compose is mounting volumes with 1001:1001 USER:GROUP - docker

On a remote VPS, I am mounting volumes thanks to this docker-compose :
version: '3.3'
services:
webapp:
build:
context: ./docker/webapp/
volumes:
- '${RELEASES_DIRECTORY}:/var/apps/site.org/releases'
- '${REPO_DIRECTORY}:/var/apps/site.org/repo'
- '${SHARED_DIRECTORY}:/var/apps/site.org/shared'
- './docker/webapp/over.php.ini:/usr/local/etc/php/conf.d/over.php.ini'
environment:
- APP_ENV=prod
- APP_DEBUG=0
- APP_DATABASE_URL=mysql://${MYSQL_USER}:${MYSQL_PASSWORD}#${MYSQL_HOST}/${MYSQL_DATABASE}
- MYSQL_SERVER_VERSION=${MYSQL_SERVER_VERSION}
- MAILER_DSN=sendgrid+api://${SENDGRID_API_KEY}#default
working_dir: /var/apps/site.org
command: php-fpm
Here is the relative Dockerfile:
FROM php:7.4-fpm-alpine
# OS DEPENDENCIES
RUN apk update
RUN apk add --no-cache bash git curl libmcrypt libmcrypt-dev openssh-client icu-dev
RUN apk add --no-cache libxml2-dev freetype-dev libpng-dev libjpeg-turbo-dev zip libzip-dev g++ make autoconf
RUN apk add --no-cache php7-mysqli
RUN docker-php-source extract
RUN docker-php-source delete
RUN docker-php-ext-install soap intl zip
RUN docker-php-ext-install opcache
RUN docker-php-ext-install mysqli pdo pdo_mysql
#Creation APP Directory
RUN mkdir -p /var/apps
RUN mkdir -p /var/apps/site
# COMPOSER INSTALLATION
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# EXORT COMPOSER GLOBAL PATH
RUN echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
RUN source ~/.bashrc
# INSTALL NODE & NPM
RUN apk add --update nodejs npm
RUN npm config set production
RUN export NODE_ENV=production
On my local machine, when I go inside the docker throung docker exec, every mapped directories are root:root but on my remote host (VPS), they are 1001:1001 and I donèt get where does it can come from ?
I tried to re-install docker and docker-compose but I have the same behaviour.
The VPS runs
Unbuntu 18.04
Docker version 19.03.8, build afacb8b7f0
docker-compose version 1.25.5, build 8a1c60f6

When you bind host files to a docker container (bind mounting), the file's permissions aren’t changed.
Your VPS probably has those files owned by a user whose uid is 1001, while the same files on your system are owned by root.

Related

Building a Dockerfile from inside Docker Compose

So I'm trying to follow these instructions:
https://github.com/open-forest/sendy
I'm using Portainer and trying to run a Sendy container (newsletter software). Instead of running a MySQL image with it, I'm just using my external managed database instead.
On my server I keep project data at: /var/docker/project-name. I use this structure for bind mounting if I need to bring data into the containers from the start.
So for this project in the project-name folder I have sendy-6.0.2.zip and this Dockerfile: (This file was provide via the instructions on the above link)
#
# Docker with Sendy Email Campaign Marketing
#
# Build:
# $ docker build -t sendy:latest --target sendy -f ./Dockerfile .
#
# Build w/ XDEBUG installed
# $ docker build -t sendy:debug-latest --target debug -f ./Dockerfile .
#
# Run:
# $ docker run --rm -d --env-file sendy.env sendy:latest
FROM php:7.4.8-apache as sendy
ARG SENDY_VER=6.0.2
ARG ARTIFACT_DIR=6.0.2
ENV SENDY_VERSION ${SENDY_VER}
RUN apt -qq update && apt -qq upgrade -y \
# Install unzip cron
&& apt -qq install -y unzip cron \
# Install php extension gettext
# Install php extension mysqli
&& docker-php-ext-install calendar gettext mysqli \
# Remove unused packages
&& apt autoremove -y
# Copy artifacts
COPY ./artifacts/${ARTIFACT_DIR}/ /tmp
# Install Sendy
RUN unzip /tmp/sendy-${SENDY_VER}.zip -d /tmp \
&& cp -r /tmp/includes/* /tmp/sendy/includes \
&& mkdir -p /tmp/sendy/uploads/csvs \
&& chmod -R 777 /tmp/sendy/uploads \
&& rm -rf /var/www/html \
&& mv /tmp/sendy /var/www/html \
&& chown -R www-data:www-data /var/www \
&& mv /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
&& rm -rf /tmp/* \
&& echo "\nServerName \${SENDY_FQDN}" > /etc/apache2/conf-available/serverName.conf \
# Ensure X-Powered-By is always removed regardless of php.ini or other settings.
&& printf "\n\n# Ensure X-Powered-By is always removed regardless of php.ini or other settings.\n\
Header always unset \"X-Powered-By\"\n\
Header unset \"X-Powered-By\"\n" >> /var/www/html/.htaccess \
&& printf "[PHP]\nerror_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED\n" > /usr/local/etc/php/conf.d/error_reporting.ini
# Apache config
RUN a2enconf serverName
# Apache modules
RUN a2enmod rewrite headers
# Copy hello-cron file to the cron.d directory
COPY cron /etc/cron.d/cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cron \
# Apply cron job
&& crontab /etc/cron.d/cron \
# Create the log file to be able to run tail
&& touch /var/log/cron.log
COPY artifacts/docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["apache2-foreground"]
#######################
# XDEBUG Installation
#######################
FROM sendy as debug
# Install xdebug extension
RUN pecl channel-update pecl.php.net \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& rm -rf /tmp/pear
Here is my Docker Compose file:
version: '3.7'
services:
project-sendy:
container_name: project-sendy
image: sendy:6.0.2
build:
dockerfile: var/docker/project-sendy/Dockerfile
restart: unless-stopped
networks:
- proxy
- default
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.project-secure.entrypoints=websecure"
- "traefik.http.routers.project-secure.rule=Host(`project.com`)"
environment:
SENDY_PROTOCOL: https
SENDY_FQDN: project.com
MYSQL_HOST: db-host-name-here
MYSQL_DATABASE: db-name-here
MYSQL_USER: db-user-name-here
MYSQL_PASSWORD: db-password-here
SENDY_DB_PORT: db-port-here
networks:
proxy:
external: true
When I try to deploy I get:
failed to deploy a stack: project-sendy Pulling project-sendy
Error could not find /data/compose/126/var/docker/project-sendy:
stat /data/compose/126/var/docker/project-sendy: no such file or directory
So here's what I've done.
I have the cron and artifacts folder on the same directory as the Dockerfile.
In the Dockerfile look for this line:
COPY artifacts/docker-entrypoint.sh /usr/local/bin/
Right below it put this line:
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
Otherwise you will get this error:
Starting Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/usr/local/bin/docker-entrypoint.sh": permission denied: unknown
Then build it with:
docker build -t sendy:6.0.2 .
Then your image will show up in portainer.
You can then remove the build section in your docker compose file and hit deploy. It now works for me.

docker-compose - cannot use bind mount in folder created when using BUILD

I have a docker-compose file which uses a Dockerfile to build the image. In this image (Dockerfile) I created the folder /workspace which I'd like to bind mount for persistence in my local filesystem.
After the docker-compose up, the folder is empty if I bind mount, but if I do not mount this folder everything works fine (and the folder exist with all the files I added).
This is my docker-compose.yml:
version: "3.9"
services:
web:
build: .
command: uwsgi --ini /workspace/confs/uwsgi.ini --logger file:/workspace/logs/uswgi.log --processes 1 --workers 1 --plugins-dir=/usr/lib/uwsgi/plugins/ --plugin=python
environment:
- DB_HOST=db
- DB_NAME=***
- DB_USER=***
- DB_PASS=***
depends_on:
- db
- redis
- memcached
volumes:
- ./workspace:/workspace
networks:
- asyncmail
- traefik
# db, redis and memcached are ommited here
# aditional labels for traefik is also ommited
This is my Dockerfile:
FROM ubuntu:trusty
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
SHELL ["/bin/bash", "-c"]
RUN mkdir /workspace
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y redis-server python3-pip git-core postgresql-client
RUN apt-get install -y libpq-dev python3-dev libffi-dev libtiff5-dev zlib1g-dev libjpeg8-dev libyaml-dev libpython3-dev openssh-client uwsgi-plugin-python3 libpcre3 libpcre3-dev uwsgi-plugin-python
ADD myapp /workspace/
WORKDIR /workspace/src/
RUN /bin/bash -c "pip3 install cffi \
&& pip3 install -r /workspace/src/requirements.txt \
&& ./manage.py collectstatic --noinput"
RUN ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
# CMD ["uwsgi", "--ini", "/workspace/confs/uwsgi.ini", "--logger", "file:/workspace/logs/uswgi.log"]
I know there is some items it could be optimized, but when I do a docker-compose up -d the folder ./workspace is created with only a folder inside called src. Inside the container the /workspace only have this empty folder too;
If I remove the volumes line in docker-compose, inside the container, the folder /workspace have all the sourcecode of my app.
What am I doing wrong that I can't bind mount the workspace folder?
PS: I know this image i'm using (ubuntu trusty) is old, but my old app only run with this version.
am I correct in assuming that the files you want to appear inside workspace are actually in a folder called "myapp" in your host machine
(it seems so from this line)
ADD myapp /workspace/
I think you meant to map that into your docker container, so under volumes
volumes:
- ./myapp:/workspace
volume maps work one way, that is the folder inside the container is replaced by the contents of the mapped folder on the host, not the other way around...
I ended up with adding to the container the sourcecode directory to fix this problem. #NiRR answer helped a lot.
The final Dockerfile was changes to not include sourcecode in the image:
FROM ubuntu:trusty
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ARG DEBIAN_FRONTEND=noninteractive
SHELL ["/bin/bash", "-c"]
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y python3-pip git-core postgresql-client
RUN apt-get install -y libpq-dev python3-dev libffi-dev libtiff5-dev zlib1g-dev libjpeg8-dev libyaml-dev libpython3-dev openssh-client uwsgi-plugin-python3 libpcre3 libpcre3-dev
WORKDIR /workspace/src
COPY myapp/src/requirements.txt .
RUN /bin/bash -c "pip3 install cffi \
&& pip3 install -r requirements.txt"
# To set timezone
RUN ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
And I changed the docker-compose to the following final version:
version: "3.9"
services:
web:
build: .
command: ./start.sh
environment:
- DB_HOST=db
- DB_NAME=***
- DB_USER=***
- DB_PASS=***
volumes:
- ./myapp:/workspace
Now in the container start all the sourcecode from myapp is copied to inside the container;
Everything is under GIT control
If the code changes, we can make a push/pull and docker-compose up -d to restart the container. The new version will already be there.

Docker Compose service volume not reflecting my host machine changes to the running container

I am not a really experienced user on Docker, and I am faced with a weird issue I cannot solve.
What I try to do, is to run three services using a docker-compose.yml. The three services are a MySQL Server, a PHP-FPM and an nGinx server.
So far, I have achieve to run the services, and I can do all the operation I want, like running the migration files inside the container, add fixtures data in the database, etc.
The only problem I have using the following configuration is that the changes I do on my host machine files, it is not reflected in the running containers.
If I stop the docker-compose, and restart it, then I can see my host machine changes, but I cannot see the changes while the containers are running.
In the following files, do you see any errors in my configuration? I have searched a lot, but unfortunately, I cannot find any solution.
My docker-compose.yml file looks like that:
version: "3.9"
services:
mysql:
image: mysql:8.0
volumes:
- ./docker/mysql/init:/docker-entrypoint-initdb.d
- .data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: api
php:
build:
context: .
env_file:
- .env
ports:
- "9000:9000"
volumes:
- ./:/srv/api
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./:/srv/api
- ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf
For the PHP the Dockerfile is the following:
# the different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
# https://docs.docker.com/compose/compose-file/#target
# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG PHP_VERSION=8.0.9
# "php" stage
FROM php:${PHP_VERSION}-fpm-alpine AS api_platform_php
# persistent / runtime deps
RUN apk add --no-cache \
acl \
fcgi \
file \
gettext \
git \
gnu-libiconv \
;
# install gnu-libiconv and set LD_PRELOAD env to make iconv work fully on Alpine image.
# see https://github.com/docker-library/php/issues/240#issuecomment-763112749
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so
ARG APCU_VERSION=5.1.19
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
icu-dev \
libzip-dev \
mysql-dev \
zlib-dev \
; \
\
docker-php-ext-configure zip; \
docker-php-ext-install pdo pdo_mysql; \
docker-php-ext-install -j$(nproc) \
intl \
zip \
; \
pecl install \
apcu-${APCU_VERSION} \
; \
pecl clear-cache; \
docker-php-ext-enable \
apcu \
opcache \
; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-cache --virtual .api-phpexts-rundeps $runDeps; \
\
apk del .build-deps
###> recipes ###
###< recipes ###
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
COPY docker/php/conf.d/api-platform.prod.ini $PHP_INI_DIR/conf.d/api-platform.ini
VOLUME /var/run/php
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV PATH="${PATH}:/root/.composer/vendor/bin"
WORKDIR /srv/api
# build for production
ARG APP_ENV=prod
# prevent the reinstallation of vendors at every changes in the source code
COPY composer.json composer.lock symfony.lock ./
RUN set -eux; \
composer install --prefer-dist --no-dev --no-scripts --no-progress; \
composer clear-cache
# copy only specifically what we need
COPY .env ./
ADD bin bin/
COPY config config/
COPY migrations migrations/
COPY public public/
COPY src src/
COPY templates templates/
COPY ./ ./
COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
RUN chmod +x /usr/local/bin/docker-healthcheck
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENV SYMFONY_PHPUNIT_VERSION=9
CMD ["php-fpm"]
WORKDIR /srv/api
EXPOSE 9000
and finally my local file system is like that:
/bin
/config
/docker
/mysql
/init
init-script.sql
/nginx
site.conf
/php
/conf.d
api-platform.dev.ini
api-platform.prod.ini
/php-fpm.d
zz-docker.conf
docker-entrypoint.sh
docker-healthcheck.sh
/migrations
/public
/bundles
[...]
index.php
[...]
/src
/Controller
/DataFixtures
/Entity
/EventSubscriber
/Exception
/OpenApi
/Repository
/Security
/Serializer
/Validation
Kernel.php
/templates
/tests
/var
/vendor
.env
[...]
docker-compose.yml
Dockerfile
[...]
It should have nothing to do with your Dockerfile.
Perhaps for some reason your mounts default to :delegated mode.
Try adding :consistent to your volume specification, as in:
- ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf:consistent
From the docs:
consistent: perfect consistency (host and container have an identical view of the mount at all times)
cached: the host’s view is authoritative (permit delays before updates on the host appear in the container)
delegated: the container’s view is authoritative (permit delays before updates on the container appear in the host)
EDIT:
Check out this (long) thread: https://github.com/docker/for-win/issues/5530 (it has started as a Windows issue, but Ubuntu users report the same issue in the thread).
It has a lot of things in common with your issue, including PHP and more than one container using the same host folder as a volume. It seems a bug related to very frequent file updates and the caching system. For some, adding :consistent worked, for some not. The bug report is now closed - it seems fixed, even tough I do not see a very obvious explanation at the end. I do recommend to make sure your Docker / docker-compose deployment is up to date.
I had similar issues on my Mac - and this turned out to be related to the option in Docker Desktop which was enabled to "Use gRPC FUSE for file sharing". Once I disabled this option I was able to add and edit files on the host and see the updates reflected in the container without having to stop and start the containers.

How to deploy dockerized laravel app with elastic beanstalk?

I'm new to Docker. Trying to deploy dockerized laravel app using elastic beanstalk. Current Docker files -
docker-compose.yml -
version: '3'
services:
#PHP Service
app:
build:
context: ./
dockerfile: Dockerfile
image: admin
container_name: admin-app
restart: unless-stopped
working_dir: /usr/share/nginx/app/
volumes:
- ./:/usr/share/nginx/app/
networks:
- app-network
nginx:
image: nginx:stable-alpine
container_name: admin-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./:/usr/share/nginx/app/
- ./nginx/conf.d/:/etc/nginx/conf.d
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
and Dockerfile
FROM php:7.4-fpm
ARG uid=1000
ARG user=sammy
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
libcurl4-openssl-dev pkg-config libssl-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
RUN pecl install mongodb && docker-php-ext-enable mongodb && \
pecl install xdebug && docker-php-ext-enable xdebug
RUN pecl config-set php_ini /etc/php.ini
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Add user for laravel application
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 existing application directory contents
COPY . /usr/share/nginx/app
WORKDIR /usr/share/nginx/app
RUN chown -R $user:$user .
USER $user
RUN chown -R $user:$user storage bootstrap/cache
RUN chmod -R 775 storage bootstrap/cache
RUN composer install
RUN php artisan cache:clear
RUN php artisan view:clear
RUN php artisan config:clear
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
It works fine at local machine when I run docker compose up -d only if I have already run composer install otherwise throws following error
It is ok for development purpose I have to run composer install once, but for production, I think it is not right way to manually do composer install every time new version is deployed. Doesn't the command RUN composer install at Dockerfile install the required dependencies? I can see progress bar of dependencies being installed but no vendor folder is generated if I ssh into container. Again it works fine if I ssh into instance and manually install dependencies.
I have deployed a nodejs app also successfully using elastic beanstalk. There the dependencies were installed properly using command RUN npm install at Dockerfile. I don't see any difference in the process. Do I have to include vendor folder also in the zip file?. Please suggest correct way to deploy.

Docker not pulling updated php version

I am trying to update php version on the Docker
This is how my Dockerfile looks like
FROM php:7.2-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
# 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 -d /home/ubuntu ubuntu
RUN mkdir -p /home/ubuntu/.composer && \
chown -R ubuntu:ubuntu /home/ubuntu
# Set working directory
WORKDIR /var/www
USER ubuntu
I have changed the php version to 7.3, and I tried to delete all docker containers and recreate it docker rm -vf $(docker ps -a -q). And then I built my docker containers using docker-compose build --nocache --pull.
docker-compose.yaml file looks like this:
version: "3.7"
services:
app:
build:
context: ./
dockerfile: ./docker/Dockerfile
image: myapp
container_name: myapp-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- myapp
But still the php version is stated as 7.2.
Any advice?
To remove all containers/images/networks/.. run:
docker system prune -a
Then try to build the image.
If that don't works: can you give the logs, where the wrong version will pulled?

Resources