Home > Enterprise >  When does Dockerfile executes, and why groupadd and usereadd not working
When does Dockerfile executes, and why groupadd and usereadd not working

Time:04-09

I have two questions:

  1. Dockerfile has two command, add group and user, both named www, but didn't create.
  2. How to stop the container created by docker-compose up -d.

I followed this article:
https://www.digitalocean.com/community/tutorials/how-to-set-up-laravel-nginx-and-mysql-with-docker-compose

git clone https://github.com/laravel/laravel.git mylaravel9

Edit docker-compose.yml and Dockerfile, then

docker-compose up -d

The browser "http://localhost" shows, but with an error, a log file with permission problem. This was solved, but not really solved.

docker-compose.yml

version: '3'
services:
  
  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: php:8.1.4-fpm
    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: laravel
      MYSQL_ROOT_PASSWORD: 123456
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
#Volumes
volumes:
  dbdata:
    driver: local

Dockerfile:

FROM php:8.1.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

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
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"]

The first question:

When first time do

docker-compose up -d

It pulls things, and run the commands in Dockerfile. There is a problem, which is also solved

failed to solve: executor failed running [/bin/sh -c docker-php-ext-install pdo_mysql mbstring zip exif pcntl]: exit code: 1

A post says the "mbstring" needs to be taken off. Ok, the Dockerfile really used. But there are two commands not working

# Add user for laravel application  
RUN groupadd -g 1000 www  
RUN useradd -u 1000 -ms /bin/bash -g www www  

Because

docker exec -it app bash  

and in the app container's shell

cd /var/www  
ls -l  

I saw the group and owner is number 1000, not www. Then

cat /etc/passwd  

The user and group of "www" doesn't exist! Why? I manually add the www group and user, and do chmod, the problem of log file permission is solved. But why www doesnt exist? The add commands are in the Dockerfile.

The second question
Exit the app shell, back to Ubuntu

docker ps

Shows three conatiners: php, nginx, mysql. But in docker interface(Windows 11), there is a container named by the folder mylaravel9.

docker stop mylaravel9

It says:

Error response from daemon: No such container: mylaravel9

So I can only stop the whole thing in the docker UI? If I want to use command, I have to stop the three containers? Is it?

CodePudding user response:

There are two significant problems in the setup you show.

volumes:
  - ./:/var/www

In the Dockerfile, you COPY --chown content to a different user, but then this volumes: mount hides everything the image setup does in the /var/www directory and replaces it with content from the host. Inside the container you'll see the host's numeric user ID and the possibly-unrelated code from the host. I'd recommend just deleting this line.

build: .
image: php:8.1.4-fpm

This combination tells Compose to build your application from its Dockerfile, then to label the result as the original php:8.1.4-fpm image. When you re-run docker-compose build it will start from the thing labeled as php:8.1.4-fpm, which means you're repeatedly reinstalling your application on top of itself.

Delete the image: line if you're not planning to push the built image to a registry (and if you are, use the name and tag for the built image, not the base image). docker pull php:8.1.4-fpm manually to make sure you have a "good" copy of this base image.

In the context of a Compose project, you don't usually need to use basic docker commands; there are docker-compose wrappers for most operations. If you want to update your application and restart its container it should be enough to

docker-compose build
docker-compose up -d

will will recreate the changed app container but leave the others alone. If you do need to stop an individual container for some reason ("stopped" is a somewhat unusual state) then docker-compose stop can do it.

  • Related