Docker 是一个用于开发、运输和运行应用程序的流行开源平台。它将应用程序及其依赖关系封装在容器中,以促进不同环境间的一致性。这种一致性有助于防止与依赖冲突和 “在我的机器上也能运行” 的差异有关的问题。
使用 Docker,您可以使用 Dockerfile 定义必要的依赖关系和扩展。这意味着您的应用程序在一个可重现的隔离环境中拥有所有必需的库和工具。
应用程序托管服务器为自定义 Dockerfile 提供动态支持,使您能够更好地控制应用程序的环境。有了 Dockerfile,你几乎可以使用任何语言,而不必局限于 Nixpacks 或 Buildpacks 所支持的语言。
本文将手把手教你如何在 Docker 中安装和使用 PHP 依赖项和扩展。
为什么使用 Docker 安装依赖项?
使用 Docker 安装依赖项有几个好处:
- 环境一致性 – Docker 允许您将应用程序、其依赖项和配置打包到一个容器中。这种方法可确保在不同的配置和系统(包括开发、测试和生产环境)中,应用程序的运行环境保持一致。
- 易于设置和解决依赖性问题 – Docker 可让你在任何支持应用程序的机器上设置应用程序的环境,只需指定其所需的所有依赖性和配置即可。因此,您可以避免兼容性问题和手动安装依赖项的麻烦。
- 版本控制和隔离 – Docker 容器封装了所有依赖项,包括容器内的特定版本。这意味着您可以对应用程序及其依赖项进行版本控制,从而提高可重复性并消除不同依赖项版本之间的冲突。
此外,Docker 容器还提供隔离功能,有助于消除在同一系统上运行的不同应用程序之间的依赖关系冲突。
在服务器上设置应用程序
以Kinsta为例,在服务器上设置您的应用程序非常简单。访问 MyKinsta 并按照注册流程操作。注册完成后,您就可以访问功能强大的托管控制面板和一整套旨在优化性能和安全性的功能。
Kinsta 的应用程序托管支持一系列编程语言,包括 PHP、Python、Node.js 和 Ruby。这种广泛的语言支持确保了与各种应用程序的兼容性,使您能够选择最适合您项目要求的语言。
例如,如果您正在使用 PHP 开发动态网络应用程序,Kinsta 的优化托管环境可确保您基于 PHP 的项目具有高性能和高可靠性。或者,如果您使用 Node.js 构建 RESTful API,或使用 Python 构建数据驱动型网络应用程序,Kinsta 将为您的应用程序提供必要的基础设施和支持。
要体验如何在 Kinsta 上使用 Dockerfile 部署应用程序,请使用此应用程序,这是一个使用 MariaDB 存储数据的基于 PHP 的基本身份验证系统。该应用还利用了一些作曲包,包括用于输入验证的 respect/validation 和用于密码散列的 ircmaxell/password-compat。
准备 Docker 环境
Dockerfile 是一个文本文件,其中包含构建所需镜像所需的所有命令,并按照必要的顺序排列。PHP 应用程序的基本 Dockerfile 是这样的:
FROM php:8.3-cli COPY . /usr/src/myapp WORKDIR /usr/src/myapp CMD [ "php", "./your-script.php" ]
此 Dockerfile 可创建一个容器环境,用于从命令行界面(CLI)运行 PHP 脚本。它首先使用带有 CLI 变体的官方 PHP 映像,确保容器中只包含 PHP 运行时。
然后,它将包含 Dockerfile 的本地目录内容复制到容器中的 /usr/src/myapp 目录。将工作目录设置为 /usr/src/myapp 后,它会使用 php
命令指定要执行的 PHP 脚本,即 your-script.php。
映像包含许多预编译的 PHP 扩展。因此,首先运行 php -m
命令检查是否安装了所需的扩展。
如果基本镜像中没有你需要的扩展,Docker 会提供以下辅助脚本,帮助你更轻松地安装其他扩展:
docker-php-ext-configure
docker-php-ext-install
docker-php-ext-enable
例如,本教程的演示程序使用 MySQLi 扩展与 MariaDB 数据库交互。该扩展默认未编译到映像中,因此请在 Dockerfile 中使用以下命令安装它:
RUN docker-php-ext-install mysqli
要为演示程序编写 Dockerfile,请在项目根文件夹中新建一个名为 Dockerfile 的文件。在文件中粘贴以下代码:
FROM php:8.3-apache # Install MySQL client, server, and other dependencies RUN apt-get update && \ apt-get install -y \ default-mysql-client \ default-mysql-server \ git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Install mysqli PHP extension for MySQL support RUN docker-php-ext-install mysqli
该代码指定了官方 PHP 镜像(特别是 8.3 版),并安装了 Apache 作为容器的基础映像。该镜像为使用 Apache 作为 Web 服务器运行 PHP 应用程序提供了预配置环境。
然后,它将安装演示应用程序所需的其他依赖项,包括 default-mysql-client
和 default-mysql-server
,它们将创建 MariaDB 数据库并与之交互。
最后,上面的代码段使用 docker-php-ext-install
安装了 mysqli
PHP 扩展,它允许演示程序在 MariaDB 数据库上建立连接并执行操作。
用 Docker 管理依赖关系
使用 Docker 管理 PHP 的依赖关系需要使用 Composer,这是一种流行的 PHP 依赖关系管理器。通过在 Docker 容器中安装 Composer,您可以简化安装、更新和管理 PHP 依赖项的过程,同时促进不同环境间的一致性和可重复性。
请按照以下步骤在演示应用程序中使用 Composer 进行依赖关系管理。将每个步骤中的代码添加到你的 Dockerfile 中。
- 使用以下命令在 Docker 镜像中安装 Composer:
# Install Composer COPY --from=composer/composer:latest-bin /composer /usr/bin/composer
该命令会将 Docker Hub 代码库中预制的 Composer 二进制文件复制到你的镜像中。
--from=composer/composer:latest-bin
指定了从中拷贝文件的源镜像。源镜像中的
/composer
路径包含要复制的文件,而你的 Docker 镜像的/usr/bin/composer
路径则是这些文件的目的地。 - 接下来,运行以下命令设置工作目录:
# Set working directory WORKDIR /var/www/html
- 将 composer.json 和 composer.lock 文件复制到镜像中。
# Copy composer.json and composer.lock COPY composer.json composer.lock ./
- 安装 composer.json 中列出的 Composer 依赖项。
# Install Composer dependencies RUN composer install --no-dev --optimize-autoloader
--no-dev
指示 Composer 跳过特定于开发的依赖项。--optimize-autoloader
(优化自动加载器)指示 Composer 优化自动加载器,以提高性能。
你可以根据需要修改 composer.json 文件,添加新的依赖项,更新版本限制,删除不再需要的依赖项,从而逐步更新和管理依赖项。
进行必要的修改后,在 Docker 容器中运行 composer install
或 composer update
,安装或更新相应的依赖项。
应用最终配置
在应用程序使用 Docker 之前,必须创建数据库和数据库用户、设置环境变量,并将项目文件复制到 Docker 镜像中。
为此,请按照以下步骤操作,并将每个代码段复制到 Docker 文件中。
- 设置 PHP 应用程序用来连接 MariaDB 数据库的环境变量。你可以用自己喜欢的凭证替换
DB_USER
、DB_PASSWORD
和DB_NAME
。# Set environment variables ENV DB_HOST=localhost \ DB_USER=kinsta_user \ DB_PASSWORD=your_password_here \ DB_NAME=kinsta_docker_auth \ # Path to the Unix socket file used for connecting to the MariaDB server. DB_SOCKET=/var/run/mysqld/mysqld.sock
- 将 PHP 应用程序文件复制到 Docker 镜像中:
# Copy PHP application files into the image COPY . .
- 将启动脚本复制到图像中:
# Copy the startup script COPY scripts/start.sh /usr/local/bin/start.sh
该脚本在容器启动时运行,负责启动数据库服务器、创建数据库、表和用户以及启动 Apache 服务器。稍后您将创建此脚本。
- 使用
chmod
命令使脚本可执行:# Make the script executable RUN chmod +x /usr/local/bin/start.sh
- 最后,使用下面的命令执行脚本:
# Execute the startup script CMD ["/usr/local/bin/start.sh"]
现在 Dockerfile 已经完成,可以创建前面讨论过的启动脚本了。
在项目根文件夹中新建一个名为 scripts/start.sh 的文件,并添加以下代码。确保使用在 Dockerfile 中定义的数据库凭据。
#!/bin/bash # Start MariaDB server service mariadb start # Wait for MariaDB to be fully initialized (retry up to 30 times, waiting 1 second between each attempt) attempt=0 while [ $attempt -lt 30 ]; do if mysqladmin ping &>/dev/null; then echo "MariaDB is up and running." break else echo "MariaDB is not yet available. Retrying..." attempt=$((attempt+1)) sleep 1 Fi done # If MariaDB failed to start within the specified attempts, exit with an error if [ $attempt -eq 30 ]; then echo "Error: MariaDB failed to start within the specified time." exit 1 fi # Set the database name, username, and password dbname="kinsta_docker_auth" dbuser="kinsta_user" dbpassword="your_password_here" # Create the database if it does not exist mysql -u root -e "CREATE DATABASE IF NOT EXISTS $dbname;" # Create a database user and assign privileges to the database mysql -u root -e "CREATE USER '$dbuser'@'localhost' IDENTIFIED BY '$dbpassword';" mysql -u root -e "GRANT ALL PRIVILEGES ON $dbname.* TO '$dbuser'@'localhost';" mysql -u root -e "FLUSH PRIVILEGES;" # Create users table if it does not exist mysql -u root -e "USE $dbname; CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(20) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL );" # Start Apache server apache2ctl -D FOREGROUND
这个 Bash 脚本会启动 MariaDB 服务器。然后,当服务器完全初始化后,它会创建一个数据库、一个具有适当权限的用户以及数据库中的一个表。最后,启动 Apache 服务器。
在服务器上部署
在将应用程序部署到 Kinsta 之前,您必须为 Apache 服务器配置一些配置。Kinsta 的应用程序托管服务开放了 80
和 443
端口,但如果您的应用程序暴露了任何端口,我们建议您使用 8080
端口。
默认情况下,Apache 服务器监听端口 80
上的连接,因此必须将其配置为监听端口 8080
上的连接。为此,请按照以下步骤操作:
- 在项目根文件夹中创建名为 apache-conf 的文件夹。
- 在新创建的文件夹中,创建名为 apache-config.conf 的文件。添加以下代码,配置 Apache 监听 8080 端口上的连接:
<VirtualHost *:8080> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
- 在 apache-conf 文件夹中新建一个名为 apache-ports.conf 的文件,并添加以下代码。
# Change the Listen directive to listen on port 8080 Listen 8080 # Keep the existing configuration for port 443 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
Listen 8080
指令指示 Apache 监听 8080 端口上的传入连接。 - 现在,你需要修改 Dockerfile,将此配置应用到 Apache 服务器。在 Dockerfile 中,在设置工作目录(
WORKDIR /var/www/html
)的命令之后添加这些命令。这些命令负责将自定义配置文件复制到相应的目录中。# Set up Apache virtual host COPY apache-conf/apache-config.conf /etc/apache2/sites-available/000-default.conf # Set up Apache ports COPY apache-conf/apache-ports.conf /etc/apache2/ports.conf
- 最后,在项目根文件夹中创建一个 .dockerignore 文件。该文件列出了不应复制到 Docker 镜像中的文件夹和文件。添加
vendor
以排除 vendor 文件夹。
完成所有配置后,就可以部署到 Kinsta 了。将项目文件上传到首选的 Git 提供商(Bitbucket、GitHub 或 GitLab),然后按照以下步骤操作。
- 在 MyKinsta 面板中,选择侧边栏上的 Applications,然后单击 Add application 按钮。
- 在 “Add application” 页面,选择 Git 仓库和分支,提供应用程序名称,选择数据中心位置,然后单击 “Continue“。
- 在 “Build environment” 页面,选择 “Use Dockerfile to set up container image“。提供 “Dockerfile “作为 Dockerfile path,并提供句号(”.”)作为 Context。单击 Continue。添加应用程序表单中的 “构建环境” 部分:
- 将所有内容保留在 “Set up your processes” 页面,然后单击 “Continue“。注意:重新启动或重新部署应用程序时,数据库将丢失数据。如果需要解决这个问题,请查看 Kinsta 的持久存储并在此页面上应用。本指南将不审查持久存储的设置。
- 在 “Summary ” 页面上确认付款详细信息,然后单击 “Deploy now“。
- 部署完成后,打开应用程序的域查看实时网站。下图为实时网站上的登录页面:注册一个账户,使用您的详细信息登录,然后检查您是否可以访问受保护的页面,以及是否一切正常。下图为登录后的应用程序主页:
监控和优化您的应用程序
一旦您的应用程序在服务器上启动并运行,监控和优化其性能至关重要。它能确保您的应用程序顺利运行并有效利用资源。
优化应用程序的性能对于提供快速响应的用户体验至关重要。
通过监控工具,帮助您跟踪各种性能指标,包括带宽、总构建时间、CPU 使用率、内存消耗、网络流量和响应时间。
如果遇到问题或意外的应用程序行为,您可以导航到服务器管理对应的日志部分。该部分详细概述了应用程序的性能和行为,包括错误和访问日志。
通过仔细查看这些日志,您可以深入了解可能导致问题的原因,如错误消息、堆栈跟踪或异常行为模式。这些信息可以帮助您诊断问题的根本原因,并采取适当措施加以解决。
此外,您还可以在 Docker 环境中利用性能优化技术,例如优化 Docker 映像以及实施应用架构和代码优化的最佳实践。
小结
无论底层基础架构如何,Docker 的轻量级和可移植容器都能轻松打包和部署包含所有所需依赖项的应用程序。通过将应用程序及其依赖项容器化,您可以在不同环境中提高一致性,简化设置流程,并获得更好的版本控制。
评论留言