gitlab之ci脚本实现php项目自动发布
//在宿主机创建
1.laravel项目创建, 通过命令行 composer create-project --prefer-dist laravel/laravel project_name
$ composer create-project --prefer-dist laravel/laravel meta-known
//在gitlab-runner 容器里内
2.安装php8.3 ()
ubuntu22下(如果是root用户,就不用sudo):
添加php8.3官方源:
sudo apt update
sudo apt install -y software-properties-common ca-certificates lsb-release apt-transport-https
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
安装php8.3:
sudo apt install -y php8.3 php8.3-cli php8.3-mbstring php8.3-xml php8.3-zip php8.3-curl unzip
根据需求安装拓展:
sudo apt install -y php8.3-cli php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-bcmath php8.3-intl php8.3-gd php8.3-soap
3.php -v 查看版本
没有可以添加
sudo ln -s /usr/bin/php8.3 /usr/local/bin/php
再次执行
php -v
我这里安装完php,执行php -v 报:
PHP 8.3.17 (cli) (built: Feb 15 2025 09:08:37) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.17, Copyright (c) Zend Technologies
with Zend OPcache v8.3.17, Copyright (c), by Zend Technologies
说明已经做了软连接
查看php指向:
# which php
/usr/bin/php
查看具体指向:
ls -l $(which php)
lrwxrwxrwx 1 root root 21 Mar 12 15:20 /usr/bin/php -> /etc/alternatives/php
查看具体指向哪个版本:
ls -l /etc/alternatives/php
lrwxrwxrwx 1 root root 15 Mar 12 15:20 /etc/alternatives/php -> /usr/bin/php8.3
4.安装composer
下载 Composer 安装脚本:
curl -sS https://getcomposer.org/installer | php
将 Composer 安装到全局路径: 将下载的 Composer 可执行文件移动到 /usr/local/bin,这样你可以在任何地方通过 composer 命令使用它:
sudo mv composer.phar /usr/local/bin/composer
查看版本:
composer --version
Composer version 2.8.6 2025-02-25 13:03:50
PHP version 8.3.17 (/usr/bin/php8.3)
Run the "diagnose" command to get more detailed diagnostics output.
5.安装 rsync 工具,用于同步文件
apt-get install -y rsync
rsync --version
rsync version 3.1.3 protocol version 31
Copyright (C) 1996-2018 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, iconv, symtimes, prealloc
rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
6.宿主机上执行:
guoshipeng@tianyi510s:~/Documents/code/meta-known$ sudo mkdir -p /data/www/meta-known-backend-v1
这里因为安装gitlab-runner的时候,没有将 宿主机的 /data 挂载到容器的 /data 上,所以这里我就直接在容器里创建 mkdir -p /data/www/meta-known-backend-v1
默认有gitlab-runner用户和用户组:
root@8446a748968a:/# chown -R gitlab-runner:gitlab-runner /data
root@8446a748968a:/# chmod -R 775 /data
但是我还是想分配给 www-data:www-data
先查看www-data是否存在:
root@8446a748968a:/# getent passwd www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
root@8446a748968a:/#
root@8446a748968a:/#
root@8446a748968a:/# getent group www-data
www-data:x:33:
说明 www-data 用户和用户组都存在
或者直接:
root@8446a748968a:/# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
如果不存在,先创建用户组,再创建用户,加到用户组:
创建 www-data 组:
sudo groupadd www-data
创建 www-data 用户并加入 www-data 组:
sudo useradd -r -g www-data -s /usr/sbin/nologin www-data
解释 sudo useradd -r -g www-data -s /usr/sbin/nologin www-data:
useradd → 添加一个新用户
-r → 创建一个 系统用户(UID 小于 1000,一般用于守护进程)
-g www-data → 指定主组为 www-data
-s /usr/sbin/nologin → 让 www-data 用户无法直接登录系统
www-data → 这个是用户名
实际上可能需要sudo,但是gitlab-runner 容器默认没有装,所以需要手动安装:
root@8446a748968a:/# apt-get update && apt-get install -y sudo
查看:
root@8446a748968a:/# sudo --version
Sudo version 1.8.31
Configure options: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-exampledir=/usr/share/doc/sudo/examples --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p: --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-rundir=/run/sudo --libexecdir=/usr/lib --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --with-selinux --with-linux-audit --enable-tmpfiles.d=yes
Sudoers policy plugin version 1.8.31
Sudoers file grammar version 46
Sudoers path: /etc/sudoers
Authentication methods: 'pam'
...
...
gitlab-runner配置里面执行sudo,j结果需要密码,报:
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
在gitlab-runner容器里执行:
root@8446a748968a:/# sudo visudo
然后在末端添加如下内容(修改 sudoers,允许 gitlab-runner 无密码执行 sudo):
gitlab-runner ALL=(ALL) NOPASSWD: ALL
如下:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
gitlab-runner ALL=(ALL) NOPASSWD: ALL
保存退出
现在gitlab-ci.yml脚本里的:
script:
- sudo rsync -rL --delete --exclude={'.buildpath','.git','.gitignore'} ./* /data/www/meta-known-backend-v1/
- sudo chown -R www-data:www-data /data/www/meta-known-backend-v1/
可以成功执行了,默认通过 gitlab-runner 用户无密码执行.
分析 rsync 命令的行为:
sudo rsync -rL --delete --exclude={'.buildpath','.git','.gitignore'} ./* /data/www/meta-known-backend-v1/
1>覆盖已有文件:rsync 会将 ./*(CI 运行目录下的所有文件)同步到 /data/www/meta-known-backend-v1/,如果目标目录已经有相同的文件,rsync 会用新文件覆盖旧文件。
2>删除目标目录中不存在的文件:--delete 选项会删除 /data/www/meta-known-backend-v1/ 中在源目录(CI 目录)中不存在的文件,确保目标目录和源目录完全一致。
3>保留排除的文件:--exclude={'.buildpath','.git','.gitignore'} 这些文件不会被同步(不会被上传到目标目录)。
所以 /data/www/meta-known-backend-v1/ 的变化
1>新增的文件(在 CI 目录里但目标目录没有)会被添加到 /data/www/meta-known-backend-v1/。
2>已存在的文件会被覆盖为新版本。
3>目标目录中存在,但 CI 目录中已删除的文件,会被删除。
下面以laravel12项目为例子分析
1.通过命令行 composer create-project --prefer-dist laravel/laravel project_name
$ composer create-project --prefer-dist laravel/laravel meta-known
2.安装php8.3
ubuntu22下(如果是root用户,就不用sudo):
添加php8.3官方源:
sudo apt update
sudo apt install -y software-properties-common ca-certificates lsb-release apt-transport-https
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
安装php8.3:
sudo apt install -y php8.3 php8.3-cli php8.3-mbstring php8.3-xml php8.3-zip php8.3-curl unzip
根据需求安装拓展:
sudo apt install -y php8.3-cli php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-bcmath php8.3-intl php8.3-gd php8.3-soap
3.php -v 查看版本
没有可以添加
sudo ln -s /usr/bin/php8.3 /usr/local/bin/php
再次执行
php -v
我这里安装完php,执行php -v 报:
PHP 8.3.17 (cli) (built: Feb 15 2025 09:08:37) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.17, Copyright (c) Zend Technologies
with Zend OPcache v8.3.17, Copyright (c), by Zend Technologies
说明已经做了软连接
查看php指向:
# which php
/usr/bin/php
查看具体指向:
ls -l $(which php)
lrwxrwxrwx 1 root root 21 Mar 12 15:20 /usr/bin/php -> /etc/alternatives/php
查看具体指向哪个版本:
ls -l /etc/alternatives/php
lrwxrwxrwx 1 root root 15 Mar 12 15:20 /etc/alternatives/php -> /usr/bin/php8.3
4.安装composer
下载 Composer 安装脚本:
curl -sS https://getcomposer.org/installer | php
将 Composer 安装到全局路径: 将下载的 Composer 可执行文件移动到 /usr/local/bin,这样你可以在任何地方通过 composer 命令使用它:
sudo mv composer.phar /usr/local/bin/composer
查看版本:
composer --version
Composer version 2.8.6 2025-02-25 13:03:50
PHP version 8.3.17 (/usr/bin/php8.3)
Run the "diagnose" command to get more detailed diagnostics output.
5.安装 rsync 工具,用于同步文件
apt-get install -y rsync
rsync --version
rsync version 3.1.3 protocol version 31
Copyright (C) 1996-2018 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, iconv, symtimes, prealloc
rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
6.宿主机上执行:
guoshipeng@tianyi510s:~/Documents/code/meta-known$ sudo mkdir -p /data/www/meta-known-backend-v1
这里因为安装gitlab-runner的时候,没有将 宿主机的 /data 挂载到容器的 /data 上,所以这里我就直接在容器里创建 mkdir -p /data/www/meta-known-backend-v1
默认有gitlab-runner用户和用户组:
root@8446a748968a:/# chown -R gitlab-runner:gitlab-runner /data
root@8446a748968a:/# chmod -R 775 /data
但是我还是想分配给 www-data:www-data
先查看www-data是否存在:
root@8446a748968a:/# getent passwd www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
root@8446a748968a:/#
root@8446a748968a:/#
root@8446a748968a:/# getent group www-data
www-data:x:33:
说明 www-data 用户和用户组都存在
或者直接:
root@8446a748968a:/# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
如果不存在,先创建用户组,再创建用户,加到用户组:
创建 www-data 组:
sudo groupadd www-data
创建 www-data 用户并加入 www-data 组:
sudo useradd -r -g www-data -s /usr/sbin/nologin www-data
解释 sudo useradd -r -g www-data -s /usr/sbin/nologin www-data:
useradd → 添加一个新用户
-r → 创建一个 系统用户(UID 小于 1000,一般用于守护进程)
-g www-data → 指定主组为 www-data
-s /usr/sbin/nologin → 让 www-data 用户无法直接登录系统
www-data → 这个是用户名
实际上可能需要sudo,但是gitlab-runner 容器默认没有装,所以需要手动安装:
root@8446a748968a:/# apt-get update && apt-get install -y sudo
查看:
root@8446a748968a:/# sudo --version
Sudo version 1.8.31
Configure options: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-exampledir=/usr/share/doc/sudo/examples --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p: --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-rundir=/run/sudo --libexecdir=/usr/lib --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --with-selinux --with-linux-audit --enable-tmpfiles.d=yes
Sudoers policy plugin version 1.8.31
Sudoers file grammar version 46
Sudoers path: /etc/sudoers
Authentication methods: 'pam'
...
...
gitlab-runner配置里面执行sudo,j结果需要密码,报:
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
在gitlab-runner容器里执行:
root@8446a748968a:/# sudo visudo
然后在末端添加如下内容(修改 sudoers,允许 gitlab-runner 无密码执行 sudo):
gitlab-runner ALL=(ALL) NOPASSWD: ALL
如下:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
gitlab-runner ALL=(ALL) NOPASSWD: ALL
保存退出
现在gitlab-ci.yml脚本里的:
# update the dev env on gitlab
deploy:
stage: deploy
tags:
- tag1 # 使用 "tag1" 的 Runner
script:
- cat .env.example > /tmp/.env_backup || echo "No .env.example found, skipping"
- sudo rsync -rL --delete --exclude={'.buildpath','.git','.gitignore'} ./* /data/www/meta-known-backend-v1/
- if [ ! -f /data/www/meta-known-backend-v1/.env ]; then sudo cp /tmp/.env_backup /data/www/meta-known-backend-v1/.env; fi
- sudo cp ./.env.dev /data/www/meta-known-backend-v1/.env
- sudo rm -f /tmp/.env_backup
- sudo chown -R www-data:www-data /data/www/meta-known-backend-v1/
- cd /data/www/meta-known-backend-v1 && sudo -u www-data php artisan migrate --force
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
可以成功执行了,默认通过 gitlab-runner 用户无密码执行.
分析 rsync 命令的行为:
sudo rsync -rL --delete --exclude={'.buildpath','.git','.gitignore'} ./* /data/www/meta-known-backend-v1/
覆盖已有文件:rsync 会将 ./*(CI 运行目录下的所有文件)同步到 /data/www/meta-known-backend-v1/,如果目标目录已经有相同的文件,rsync 会用新文件覆盖旧文件。
删除目标目录中不存在的文件:--delete 选项会删除 /data/www/meta-known-backend-v1/ 中在源目录(CI 目录)中不存在的文件,确保目标目录和源目录完全一致。
保留排除的文件:--exclude={'.buildpath','.git','.gitignore'} 这些文件不会被同步(不会被上传到目标目录)。
所以 /data/www/meta-known-backend-v1/ 的变化
新增的文件(在 CI 目录里但目标目录没有)会被添加到 /data/www/meta-known-backend-v1/。
已存在的文件会被覆盖为新版本。
目标目录中存在,但 CI 目录中已删除的文件,会被删除。
7.在gitlab-runner 安装 mysql 客户端
apt-get update
apt-get install mysql-client -y
容器测试连接:
root@8446a748968a:/# mysql -h laravel-dev-v2-mysql -P 3306 -u laravel -proot_pwd
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2005 (HY000): Unknown MySQL server host 'laravel-dev-v2-mysql' (-2)
通过国宿主机连接:
root@8446a748968a:/# mysql -h 192.168.5.17 -P 3309 -u laravel -plaravel_pwd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.34 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
使用,报:
could not find driver (Connection: mysql, SQL: select exists (select 1 from information_schema.tables where table_schema = schema() and table_name = 'migrations' and table_type in ('BASE TABLE', 'SYSTEM VERSIONED')) as exists)
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:823
root@8446a748968a:/# sudo apt install -y php8.3-mysql
在次运行, ok了
上面的操作,实现的是gitlab-ci下项目的rsync操作,如果/data/www 和宿主机挂载,那么接下来可以直接使用宿主机运行这个项目,这个rsync相当于实时同步了代码,但是当时启动gitlab-runner的时候,没有将/data和宿主机挂载,导致这个部署方式不能使用,
接下来还是想基于docker部署laravel项目:
1.项目下创建Dockerfile
# 使用 PHP 8.3 + FPM
FROM php:8.3-fpm
# 安装必要的扩展
RUN apt-get update && apt-get install -y \
unzip libpng-dev libjpeg-dev libfreetype6-dev \
&& docker-php-ext-install pdo_mysql gd
# 安装 Nginx
RUN apt-get install -y nginx
# 设置工作目录
WORKDIR /var/www/html
# 复制 Laravel 代码
COPY . .
# 安装 Composer 依赖
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-dev --no-interaction --prefer-dist
# 配置 Nginx
COPY ./nginx/laravel.conf /etc/nginx/sites-available/default
# 赋予 storage 目录权限
RUN chmod -R 777 storage bootstrap/cache
# 启动 Nginx 和 PHP-FPM
CMD service nginx start && php-fpm
2.项目下创建 nginx/laravel.conf
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
3.构建和运行
# 构建 Docker 镜像
docker build -t laravel-app .
# 运行容器
docker run -d -p 8990:80 --name my-laravel-app laravel-app
此时,Nginx 将在容器的 80 端口运行,而 PHP 将通过 php-fpm 处理请求。你可以访问 http://localhost:8990 来查看 Laravel 项目。
但是报nginx 错误
然后到 my-laravel-app 容器里查看nginx错误日志:
2025/03/18 14:47:34 [crit] 22#22: *5 connect() to unix:/var/run/php/php8.3-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 172.17.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.3-fpm.sock:", host: "localhost:8990
发现 php8.3-fpm.sock 文件没有,但是 127.0.0.1:9000 端口有服务,于是修改
fastcgi_pass 127.0.0.1:9000;
然后重启nginx
# service nginx restart
Restarting nginx: nginx.
# service nginx status
nginx is running.
再次访问 http://localhost:8990 可以访问成功
终极版本
1.Dockerfile文件
# 使用 PHP 8.3 + FPM
FROM php:8.3-fpm
# 安装必要的扩展
RUN apt-get update && apt-get install -y \
unzip libpng-dev libjpeg-dev libfreetype6-dev vim \
&& docker-php-ext-install pdo_mysql gd
# 安装 Nginx
RUN apt-get install -y nginx
# 设置工作目录
WORKDIR /var/www/html
# 复制 Laravel 代码
COPY . .
# 复制 .env.dev 到 .env
RUN cp .env.dev .env
# 安装 Composer 依赖
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-dev --no-interaction --prefer-dist
# 生成 Laravel APP_KEY
RUN php artisan key:generate
# 配置 Nginx
COPY ./nginx/laravel.conf /etc/nginx/sites-available/default
# 赋予 storage 和 bootstrap/cache 目录权限
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 775 storage bootstrap/cache
# 创建启动脚本,这个方式其实和我之前的效果一样,并不需要在启动nginx或者php-fpm的时候切换到www-data,需要root
RUN echo '#!/bin/bash\nservice nginx start\nphp-fpm' > /start.sh \
&& chmod +x /start.sh
# 使用启动脚本
CMD ["/start.sh"]
2.gitlab-ci.yml文件
stages:
- build
- deploy
variables:
IMAGE_NAME: "meta-known-image" # 替换为你的镜像名称
CONTAINER_NAME: "meta-known-app"
DOCKER_REGISTRY: "localhost:5000" # 替换为你的 Docker 注册表(如果使用私有仓库)
before_script:
- echo "Logging into Docker Registry..."
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$DOCKER_REGISTRY" # 登录 Docker 仓库
build:
stage: build
tags:
- tag1 # 使用 "tag1" 的 Runner
script:
- IMAGE_TAG=$(date +%Y%m%d%H%M%S) # 生成时间戳作为 tag
- docker build --rm -t $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG .
- docker push $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
- docker tag $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG $DOCKER_REGISTRY/$IMAGE_NAME:latest
- docker push $DOCKER_REGISTRY/$IMAGE_NAME:latest # 推送镜像到 Docker 仓库
only:
- master # 仅在 master 分支执行才可以u
deploy:
stage: deploy
tags:
- tag1 # 使用 "tag1" 的 Runner
script:
- docker stop $CONTAINER_NAME || true # 停止旧容器(如果存在)
- docker rm $CONTAINER_NAME || true # 删除旧容器(如果存在)
- docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest # 拉取最新镜像
- docker run -d --name $CONTAINER_NAME -p 8990:80 --restart=always $DOCKER_REGISTRY/$IMAGE_NAME:latest # 运行容器
only:
- master # 部署仅在 master 分支执行
其它命令
# ps aux | grep php-fpm
bash: ps: command not found
安装ps:
apt install procps
再次查看 php-fpm:
# ps aux | grep php-fpm
root 1 0.0 0.0 2580 1536 ? Ss 14:41 0:00 /bin/sh -c service nginx start && php-fpm
root 25 0.0 0.1 82528 23168 ? Ss 14:41 0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www-data 33 0.0 0.1 91248 24404 ? S 14:41 0:00 php-fpm: pool www
www-data 34 0.0 0.1 91184 23432 ? S 14:41 0:00 php-fpm: pool www
root 342 0.0 0.0 3328 1664 pts/0 S+ 15:23 0:00 grep php-fpm
# netstat -tulnp | grep php-fpm
bash: netstat: command not found
安装netstat:
apt update && apt install -y net-tools
再次查看php-fpm 端口情况:
# netstat -tulnp | grep php-fpm
tcp6 0 0 :::9000 :::* LISTEN 25/php-fpm: master
php-fpm 监听在 :::9000,这表示它监听的是 IPv6(tcp6), 既然 php-fpm 监听在 9000 端口,可以修改你的 Nginx 配置,让它通过 127.0.0.1:9000 连接,而不是 Unix Socket。(前面的步骤就是这么解决问题的)
造成这个现象的俄原因是,之前的Dockerfile的最后CMD命令操作:
CMD service nginx start && php-fpm
会直接通过执行 php-fpm 启动PHP-FPM 进程,它会自动作为守护进程在容器内运行,等待处理 PHP 请求,而没有使用像 service 这样的服务管理工具。
如果在容器下再次执行,会报错:
# php-fpm
[18-Mar-2025 15:51:47] NOTICE: Failed implicitly binding to ::, retrying with 0.0.0.0
[18-Mar-2025 15:51:47] ERROR: unable to bind listening socket for address '9000': Address already in use (98)
[18-Mar-2025 15:51:47] ERROR: FPM initialization failed
默认配置:
PHP-FPM 默认会监听 9000 端口。这是 PHP-FPM 配置中的默认设置。
可以在 PHP-FPM 配置文件中调整监听方式,例如使用 Unix 套接字或 TCP 端口。常见的配置文件路径为 /etc/php/8.3/fpm/pool.d/www.conf
但是在容器下,/etc/php/8.3/ 目录不存在,于是想知道php8.3-fpm被安装到哪里了
# which php-fpm
/usr/local/sbin/php-fpm
root@e9c062a5ddf1:/etc/nginx/sites-available#
root@e9c062a5ddf1:/etc/nginx/sites-available# php -v
PHP 8.3.19 (cli) (built: Mar 17 2025 23:16:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.19, Copyright (c) Zend Technologies
# php -i | grep "Configuration File"
Configuration File (php.ini) Path => /usr/local/etc/php
Loaded Configuration File => (none)
发现php8.3-fpm的配置在(但是路径却没有php8.3-fpm)
# cd /usr/local/etc/php-fpm.d/
root@e9c062a5ddf1:/usr/local/etc/php-fpm.d# ls
docker.conf www.conf www.conf.default zz-docker.conf
查看默认开启的是监听9000端口:
root@e9c062a5ddf1:/usr/local/etc/php-fpm.d# vim www.conf
listen = 127.0.0.1:9000
而不是sock文件,难怪nginx不能使用sock文件了
还有个疑问,为什么一直不展示php8.3-fpm,而是php-fpm
# php -v
PHP 8.3.19 (cli) (built: Mar 17 2025 23:16:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.19, Copyright (c) Zend Technologies
root@e9c062a5ddf1:/usr/local/etc/php-fpm.d#
root@e9c062a5ddf1:/usr/local/etc/php-fpm.d#
root@e9c062a5ddf1:/usr/local/etc/php-fpm.d# php-fpm -v
PHP 8.3.19 (fpm-fcgi) (built: Mar 17 2025 23:16:48)
Copyright (c) The PHP Group
Zend Engine v4.3.19, Copyright (c) Zend Technologies
都表明,使用了php8.3-fpm
没有显式使用 php8.3-fpm,因为在 php:8.3-fpm 镜像中,php-fpm 命令默认指向 PHP 8.3 版本的 FPM 服务,所以直接执行 php-fpm 即可启动 PHP 8.3 的 FPM 进程。
