In recent days, we have just set up a small project server, which uses the combination of docker + (jenkins, nginx, PHP FPM, mysql, redis). Let's summarize today.
Docker has been out for a long time. Even the k8s high-end gadget is very "popular". To be honest, this is the first time I use docker in a production environment.
Using docker container, you can realize "true multi version php". Multi version php is suitable for the situation that there are old projects and new projects on a server at the same time, and you can even run different parts of a project with different versions...
Host: Ubuntu 16.0.4
For a host with only one host, if it's a small project, it's a small project, and we can't cheat people (what's the main cluster and what's the node, it's too high-end for us).
To install docker:
Not much. Look at this: https://www.runoob.com/docker/ubuntu-docker-install.html
To install nginx:
docker run -d --name nginx \ -v /var/www:/var/www \ #Map the site directory, as well as the configuration files and logs -p 80:80 \ #Mapping ports nginx
To install php:
Here are two dockerfiles of PHP FPM, including common extensions
FROM php:7.4-fpm RUN apt-get update && apt-get install -y \ libfreetype6-dev libjpeg62-turbo-dev libpng-dev \ curl libcurl4-openssl-dev RUN docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd RUN pecl install redis && docker-php-ext-enable redis RUN docker-php-ext-install bcmath pdo pdo_mysql mysqli curl
FROM php:7.3-fpm RUN apt-get update && apt-get install -y \ libfreetype6-dev libjpeg62-turbo-dev libpng-dev \ curl libcurl4-openssl-dev RUN docker-php-ext-configure gd \ --with-png-dir \ --with-jpeg-dir \ --with-freetype-dir \ && docker-php-ext-install -j$(nproc) gd RUN pecl install redis && docker-php-ext-enable redis RUN docker-php-ext-install bcmath pdo pdo_mysql mysqli curl #The extensions contained in the php source package can be installed directly with the command of docker php ext install, which is quite convenient. (however, this does not solve the dependency problem. If the extension depends on other system components, it needs to be installed separately.)
Create image through Dockerfile
docker build -t \ dubox/php-fpm7.4 \ #Namespace / name of the image . #Directory of Dockerfile
Create PHP container from dubox/php-fpm7.4
docker run -d --name php-fpm74 -v /var/www:/var/www dubox/php-fpm7.4 #Because you do not need to access PHP from the host, you do not need to map 9000 ports; mysql and Redis are the same;
Install mysql
docker run --name mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7 #It depends on whether 3306 port is mapped or not
Install Redis
docker run --name redis -d redis
Install Jenkins
docker run \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v /var/jenkins-data:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ #This is very important. It allows you to operate other containers like the host in Jenkins' container jenkinsci/blueocean
Visit http://ip:8080 to initialize jenkins and select the required plug-ins. More details can be found in: https://jenkins.io/zh/doc/book/installing/
Network access between containers
The nginx container needs to access the php container, and the php container needs to access mysql and redis. The network interconnection between containers can be achieved through:
1. Use container ip / / restarting the container ip may change, which is not reliable
2. Use the -- link parameter to specify the alias of the container / / there's no way for the newly added container. It's not reliable
3. Create a bridge network:
# My bridge is the name of the network, which can be customized docker network create -d bridge my-bridge #Connect the container to the network docker network connect my-bridage nginx docker network connect my-bridage php-fpm74 #View network connections docker network inspect my-bridage
In this way, containers can be accessed through their names. For example, in nginx containers, you can ping PHP fpm74 directly
Containers can also access each other. It's time to configure jenkins build task
Configure jenkins build task
Create a freestyle task
Click Add to add github access private key
The function of checking out subdirectories is also useful, and supports jenkins environment variables (environment variable description: http://ip:8080/env-vars.html/ )In this way, the code pulled from github will be placed in a location similar to / var / Jenkins? Home / workspace / job name / job name-123.
Build script description:
BuildFolder=$JOB_NAME-$BUILD_NUMBER Home="job-name" cd $BuildFolder rm -rf .git .gitignore chown -R root:33 . #Modify the home user and array of the project file, 33 is the gid of WWW data user group chmod -R 750 . chmod -R 770 runtime cd .. ln -sf /var/www/jenkinsBuild/$BuildFolder $Home #Create soft chain, even if there is no / var/www/jenkinsBuild/$BuildFolder directory soft chain in jenkins container, it can be created successfully; docker cp -a ./$BuildFolder nginx:/var/www/jenkinsBuild/ #Copy the project folder to the corresponding directory in the nginx container, because the php container also maps the / var/www directory, so the php container can also access it; the - a parameter here is very important, it can copy the file's owner and owner group (uid:gid) information together; docker cp -a $Home nginx:/var/www/ #Copy soft chain docker restart php-fpm74 docker exec -w /var/www/$Home/ php-fpm74 sh Start.sh #You can execute some commands in the target container. The - w parameter specifies the working directory of the command
Here we need to talk about the file permissions of the docker mapping directory:
Multiple containers can map to the same host directory. The permission of the file is subject to the uid:gid carried by the file, for example:
/The main owner of var/www/index.html in php container is www data group and WWW data. The corresponding uid and gid are 33. Then, there are three situations:
1. If www data: www data and uid:gid are also 33:33 in the host or nginx container, the owner and group of the file are also www data here;
2. There is no www data in the host or nginx container, but the uid of a user named someone is 33, so the owner of this file is someone;
3. If uid and gid 33 do not exist in the host or nginx container, the file does not belong to the user. When using ls-l to view, uid and gid will be displayed directly;
Therefore, we should pay attention to the users and user groups running nginx and php FPM in the nginx and php containers. Their user names and group names can be different, but they must have the same uid or gid, otherwise there will be file access problems; if you run multiple versions of php at the same time, it is the same;
The jenkins container is run by the root user and only serves as a "Porter". Therefore, it is not important whether there are users, user groups www data and uid:gid 33 in the jenkins container, as long as you specify the uid:gid you need when modifying the file ownership
Several possible commands are provided:
useradd [username] #New user groupadd [groupname] #New user group usermod -G [groupname] [username] #Add users to user groups usermod -u NEW-UID username #Modifying a user's uid groupmod -g NEW-GID groupname #Modify the gid of the user group
Finally, sell your public account