Docker+Jenkins 搭建多版本php環境

這幾天剛剛搭建了一個小項目的服務器,使用了docker +( jenkins,nginx,php-fpm,mysql,redis) 的組合,今天總結一下。

Docker 確實已經出來很久了,連k8s這種高端玩意兒也都很“普及”了,然而說實話,這纔是我第一次在生產環境中使用docker。

利用docker容器可以實現“真·多版本php”😎,多版本php適合一個服務器上同時有老項目和新項目的情況,甚至可以用不同版本來跑一個項目的不同部分​。。。​

 

宿主機:Ubuntu16.0.4

對只有一臺宿主機,說了是小項目就是小項目絕不騙人(主要什麼集羣啦什麼節點啦太高端咱也搞不了)。

 

安裝docker:

不多說,看這個:https://www.runoob.com/docker/ubuntu-docker-install.html

安裝nginx:

docker run -d --name nginx \

-v /var/www:/var/www \  #映射站點目錄,也可以把配置文件和日誌也映射出來

-p 80:80 \    #映射端口 本地端口:容器端口

nginx

 

安裝php:

這裏貼兩個php-fpm的Dockerfile,包含了常用的擴展

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 #php源碼包裏包含的擴展都可以用 docker-php-ext-install 命令直接安裝,這個還挺方便的。(但是這個並不能解決依賴問題,擴展如果依賴其他系統組件還是需要另外安裝的)

 

通過Dockerfile創建鏡像

docker build -t \

dubox/php-fpm7.4 \ #鏡像的 命名空間/名字

.     #Dockerfile所在目錄

從dubox/php-fpm7.4 創建php容器

docker run -d --name php-fpm74 -v /var/www:/var/www dubox/php-fpm7.4

#這裏因爲並不需要從宿主機外部訪問PHP,所以不需要映射9000端口;後面的mysql、Redis一樣的道理;

 

安裝mysql

docker run --name mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7

#這裏根據需要看是否映射3306端口

 

安裝Redis

docker run --name redis -d redis

 

安裝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 \ #這項很重要,它可以使你在Jenkins所在的容器中,像宿主機一樣操作其他容器

  jenkinsci/blueocean

訪問http://ip:8080 進行初始化jenkins ,選擇需要的插件。更多詳情可以參見:https://jenkins.io/zh/doc/book/installing/

 

容器間的網絡訪問

nginx容器 需要訪問 php容器 ,php容器需要訪問mysql和redis,容器間的網絡互聯可以通過:

1.使用容器ip //容器重啓ip可能會變化,不靠譜

2.使用--link參數指定容器的別名 //對新增加的容器就沒辦法了,不靠譜

3.創建一個橋接網絡:

# my-bridge 是網絡的名字可以自定義

docker network create -d bridge my-bridge


#將容器連接到網絡

docker network connect my-bridge nginx

docker network connect my-bridge php-fpm74


#查看網絡連接情況

docker network inspect my-bridge

這樣容器之間就可以通過容器名稱進行訪問,比如在nginx容器中可以直接 ping php-fpm74

 

容器有了,也可以互相訪問了,下來就該配置jenkins構建任務了

配置jenkins構建任務

創建一個自由風格的任務

點擊添加,添加github訪問私鑰

 

檢出到子目錄這個功能還挺有用的,而且支持jenkins環境變量(環境變量說明:http://ip:8080/env-vars.html/),這樣從github拉下來的代碼就會放在類似 /var/jenkins_home/workspace/job-name/job-name-123 的位置。

 

構建腳本說明:

BuildFolder=$JOB_NAME-$BUILD_NUMBER

Home="job-name"

cd $BuildFolder

rm -rf .git .gitignore

chown -R root:33 .    #修改項目文件的歸屬用戶和數組,33 是www-data用戶組的gid

chmod -R 750 .

chmod -R 770 runtime

cd ..

ln -sf /var/www/jenkinsBuild/$BuildFolder $Home   #創建軟鏈,即便jenkins容器中並沒有 /var/www/jenkinsBuild/$BuildFolder 目錄 軟鏈也是可以創建成功的;

docker cp -a ./$BuildFolder nginx:/var/www/jenkinsBuild/   #將項目文件夾拷貝到nginx容器中的相應目錄,因爲php容器也映射了/var/www目錄 所以php容器也可以訪問得到;這裏的 -a 參數很重要,它可以將文件的屬主和屬組(uid:gid)信息一同拷貝過去;

docker cp -a $Home nginx:/var/www/   #拷貝軟鏈

docker restart php-fpm74

docker exec -w /var/www/$Home/ php-fpm74 sh Start.sh   #可以在目標容器執行一些命令,-w 參數可以指定命令的工作目錄

這裏需要說一下docker映射目錄的文件權限問題:

多個容器可以映射同一個宿主機目錄,文件的權限以文件攜帶的uid:gid爲準,如:

/var/www/index.html 在php容器中的屬主是www-data 屬組也是www-data ,對應的uid和gid 都是 33,那麼,就有3種情況:

1.在宿主機或nginx容器中也存在 www-data:www-data 且uid:gid 也是 33:33 ,則該文件的屬主和屬組在這裏也是www-data;

2.在宿主機或nginx容器中不存在 www-data 但是有個叫someone的用戶的uid是33 ,那麼此文件的屬主就是someone;

3.在宿主機或nginx容器中不存在uid和gid 33,則文件沒有歸屬用戶,使用ls -l 查看時會直接顯示uid和gid;

所以,這裏要注意nginx和php容器中運行nginx和php-fpm的用戶和用戶組,它們的用戶名和組名可以不相同,但是一定要有相同的uid或gid,否則會出現文件訪問權限問題;如果同時跑多個版本的php也是同理;

而jenkins容器是用root用戶運行的,而且只起到“搬運工”的作用,所以jenkins容器中有沒有用戶和用戶組www-data以及uid:gid 33都不重要,只要在修改文件歸屬時指定你需要的uid:gid即可​;​

提供幾個可能用得到的命令:

useradd [username]    #新建用戶

groupadd [groupname]   #新建用戶組

usermod -G [groupname] [username]   #將用戶添加到用戶組

usermod -u NEW-UID username  #修改用戶的uid

groupmod -g NEW-GID groupname  #修改用戶組的gid

 

最後推銷一下自己的公衆號😂😂

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章