Docker practice - image production

Keywords: Linux Nginx PHP Docker supervisor

Environmental Science

Installation of docker, gitlab runner and runner binding with gitlab.com will not be covered in detail.

  • Gitlab, I use gitlab.com
  • Ubuntu runs gitlab runner and docker containers

Make Dockerfile

Contents of Dockerfile file

  1. The default user of RUN and COPY in this file is root
  2. USER nobody specifies that the operation command after is based on the nobody user
FROM alpine:latest

RUN apk --no-cache add \
    nginx \
    supervisor \
    curl \
    openssl \
    openssl-dev \
    php7 \
    php7-fpm \
    php7-redis \
    php7-pdo

WORKDIR /var/www/html
COPY . /var/www/html/
RUN cd /var/www/html/ && \
    mkdir -p /etc/supervisor/conf.d/ && \ 
    mv env_config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf && \
    chmod +x /etc/supervisor/conf.d/supervisord.conf && \
    mv env_config/nginx.conf /etc/nginx/nginx.conf && \
    mv env_config/fpm-pool.conf /etc/php7/php-fpm.d/www.conf && \
    mv env_config/php.ini /etc/php7/conf.d/zzz_custom.ini && \
    mv -f test_src/* /var/www/html/

USER nobody

EXPOSE 8080

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

. gitlab-ci.yml content

stages:
- build

build:
    stage: build
    script:
        - sudo docker build -t ahcometrue/php-nginx-redis:latest .
    tags:
        - pack

Because there are multiple projects, and the running environment is only the configuration difference, so we take ahcomerule / PHP nginx redis as the basic image, so there are some problems.

Permission information for this image:

// Process information
$ ps aux
PID   USER     TIME  COMMAND
1 nobody    0:00 {supervisord} /usr/bin/python2 /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
7 nobody    0:00 nginx: master process nginx -g daemon off;
8 nobody    0:00 {php-fpm7} php-fpm: master process (/etc/php7/php-fpm.conf)
9 nobody    0:00 nginx: worker process

//Current user
$ whoami
nobody

//Current user user ID group ID
$ id
uid=65534(nobody) gid=65534(nobody)

//nginx profile permissions
$ ls -al /etc/nginx/
...
-rw-r--r--    1 root     root          2295 Sep 20 03:32 nginx.conf
...

//PHP profile permissions
$ ls -al /etc/php7/
...
-rw-r--r--    1 root     root          5329 Aug 30 00:13 php-fpm.conf
-rw-r--r--    1 root     root         71982 Aug 30 00:13 php.ini
...

$ ls -al /etc/php7/conf.d/
-rw-r--r--    1 root     root            27 Sep 20 03:32 zzz_custom.ini
  1. Permission problem when overwriting nginx.conf, php.ini and other files again
  2. The permission problem of CMD execution when running container

Problems

First look at the contents of the Dockerfile file:

First version

FROM ahcometrue/php-nginx-redis:latest

ENV BASE_DIR /var/www/html

COPY . $BASE_DIR

RUN cd $BASE_DIR && \
    cp -f $BASE_DIR/.docker/nginx/nginx.conf /etc/nginx/nginx.conf && \
    cp -f $BASE_DIR/.docker/php/fpm-pool.conf /etc/php7/php-fpm.d/www.conf && \
    cp -f $BASE_DIR/.docker/php/php.ini /etc/php7/conf.d/zzz_custom.ini && \
    cp -f $BASE_DIR/.docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
    

At this time, the runner fails to execute, and does not have permission to change nginx.conf, zzz_custom.ini and other files.
The reason is that the basic image finally specifies the nobody user, and these files belong to the root user, so there is a second version based on this.

Second version

FROM ahcometrue/php-nginx-redis:latest

ENV BASE_DIR /var/www/html

COPY . $BASE_DIR

//The following operations use the root user
USER root

RUN cd $BASE_DIR && \
    cp -f $BASE_DIR/.docker/nginx/nginx.conf /etc/nginx/nginx.conf && \
    cp -f $BASE_DIR/.docker/php/fpm-pool.conf /etc/php7/php-fpm.d/www.conf && \
    cp -f $BASE_DIR/.docker/php/php.ini /etc/php7/conf.d/zzz_custom.ini && \
    cp -f $BASE_DIR/.docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf && \

At this time, the image is packed normally, and the container can run normally. However, the problem arises again.

$ ps aux
PID   USER     TIME  COMMAND
1 root    0:00 {supervisord} /usr/bin/python2 /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
7 root    0:00 nginx: master process nginx -g daemon off;
8 nobody    0:00 {php-fpm7} php-fpm: master process (/etc/php7/php-fpm.conf)
9 root    0:00 nginx: worker process
  1. Because PHP fpm7 specifies no body to run in the file, nginx and supervisor run as root (because the last user to switch in the dockerfile is root). At this time, some logs do not have permission to write
  2. The site file / var/www/html permission also causes the cache \ and storage / under the laravel framework to be written without permission by root.

Third version


FROM ahcometrue/php-nginx-redis:latest

ENV BASE_DIR /var/www/html

COPY --chown=nobody . $BASE_DIR

//The following operations use the root user
USER root

RUN cd $BASE_DIR && \
    cp -f $BASE_DIR/.docker/nginx/nginx.conf /etc/nginx/nginx.conf && \
    cp -f $BASE_DIR/.docker/php/fpm-pool.conf /etc/php7/php-fpm.d/www.conf && \
    cp -f $BASE_DIR/.docker/php/php.ini /etc/php7/conf.d/zzz_custom.ini && \
    cp -f $BASE_DIR/.docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf && \
    rm -rf .docker index.php test.html

// The following operations use the nobody user
USER nobody

//Setting nginx listening interface
EXPOSE 8080

//Using supervisor to start nginx & PHP
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
  1. Copy -- chown = nobody. $base? Dir solves the permissions of site files. It can write cache \ and storage under laravel framework normally/
  2. USER nobody switches users, which solves the problem that nginx and supervisor processes run as nobody

At this time, all the image permission problems are solved.

Log persistence permission

When the container is started, specifying the log to the host computer encounters that the log in the container cannot be written. At this time, you need to change the directory permission of the host computer.

docker run -d -p 8080:8080 -v /data/log/:/var/log/ --name laravel-api laravel-php-redis:v2.0

At this time, the data generated by the log / var/log / in the container is persisted to / data/log /. The ID of the current user is known inside the container, so the permission problem can be solved in this way

sudo chown -R 65534 /data/log

List of common commands

  • Delete after entering the container and exiting

sudo docker run -ti --rm laravel-php-redis sh

  • Enter the container and will not be deleted after exiting

sudo docker run -ti laravel-php-redis

  • Delete all containers that are running or are no longer running

docker stop $(docker ps -q) & docker rm $(docker ps -aq)

  • Start the specified port of the container and mount the host file
//Specify the port 80 of the host to map to the port 8080 in the container and specify the / data/log / directory of the host to persist the / var/log / file in the container
docker run -d  -p 80:8080 -v /data/log/:/var/log/ --name laravel-api laravel-php-redis:v2.0
  • Enter the running container

docker exec -it laravel-api sh

Posted by pckidcomplainer on Fri, 22 Nov 2019 02:17:38 -0800