前言
在当今复杂多变的软件开发与部署环境中,如何高效管理应用及其依赖,成为开发者们面临的一大挑战。你是否正为应用在不同环境中出现的兼容性问题而烦恼?是否渴望找到一种简便、快捷且可靠的方式来部署和运行项目?今天,我们将通过这篇文章,为你打开一扇新世界的大门,一文说清 docker 及 docker compose 的应用和部署,让你轻松应对这些难题,大幅提升开发与运维的效率。
假设现在服务器上需要部署三个项目,项目ABC,他们的web服务都是nginx,但是PHP版本不同,mysql数据库的版本也不相同,在传统模式下,尽管PHP可以多版本互存,但是数据库的多版本互存,相对来说就困难一些,在这种情况下,docker就是一种很好的解决方案。
docker主要由镜像和容器两部分组成,镜像可以理解成是一个模板,那么容器就是根据镜像,创建的不同的可执行的实例,那么这些实例之间是相互独立的。
一、Docker 的安装
1.1 安装 docker
安装过程中,可能因网络问题导致中断。若出现这种情况,重新执行安装命令即可继续。安装成功后,可查看对应的版本,若能显示版本信息,便证明安装已完成。
# 安装 Docker 所需的依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加 Docker 的 yum 源
yum-config-manager --add-repo https://mirrors.cloud.tencent.com/docker-ce/linux/centos/docker-ce.repo
# yum 安装 Docker
yum install -y docker-ce docker-ce-cli containerd.io
# 查看 Docker 版本
docker version
1.2 启动 docker
启动docker,并将其设置为开机自启动,随后查看运行状态。当状态显示为active (running)
时,表明docker正在运行。
# 执行以下命令启动 Docker
systemctl start docker
# 然后将 Docker 设置为开机启动
systemctl enable docker
# 查看 Docker 运行状态
service docker status
# 可能返回以下内容,看到 active (running) 表示正在运行中
Redirecting to /bin/systemctl status docker.service
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2023-12-22 10:00:56 CST; 11s ago
Docs: https://docs.docker.com
1.3 配置 docker 镜像加速
由于docker的镜像服务器位于海外,国内访问速度相对较慢。为提升访问效率,可将镜像源设置为国内的加速镜像,此处以腾讯云的镜像加速服务为例。配置完成后,需重启相关服务以使设置生效。
方法一:
# 创建Docker配置目录
mkdir -p /etc/docker
#配置Docker镜像加速源
vim /etc/docker/daemon.json
#输入以下内容后保存退出
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
#重启守护进程并重启Docker
systemctl daemon-reload && systemctl restart docker
方法二:
sudo su -
cat >> /etc/docker/daemon.json <<- EOF
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
systemctl daemon-reload && systemctl restart docker
1.4 体验 docker
完成上述设置后,即可着手体验docker的基本功能。借助简单的命令,便能轻松完成镜像的拉取与容器的创建。在此,我们以拉取nginx镜像并创建容器为例。容器创建成功后,随即可以运行。此时,通过服务器的IP地址,即可访问nginx的默认页面,这表明nginx已成功部署。
#拉取最新的nginx镜像
docker pull nginx
#运行容器
docker run -d --name nginx -p 80:80 nginx
#查看容器
docker ps -a
#显示结果
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc5b9ffeb31d nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp nginx
二、Docker 的镜像与容器
Docker镜像本质上是一种只读模板,它包含了运行应用程序所需的一切,如代码、运行时环境、库文件等。
Docker容器则是基于镜像创建的运行实例。一个镜像能够创建多个相互独立的容器,这些容器在各自的隔离环境中运行,彼此之间互不干扰。
镜像与容器是docker的核心概念。在前面的操作中,我们拉取的nginx镜像就是一个只读模板,而基于该镜像创建的nginx容器,则是一个可以独立运行的实例。
三、Docker 容器的独立性
项目 | web服务 | php版本 | mysql版本 |
---|---|---|---|
项目A | nginx | php7.4 | mysql5.7 |
项目B | nginx | php8.0 | mysql8.0 |
项目C | nginx | php7.4 | mysql8.0 |
鉴于docker的独立性优势,在面对如上述表格所示的复杂部署环境时,我们可以通过拉取不同的镜像,如不同版本的nginx、PHP以及mysql数据库镜像,分别创建对应的容器。每个容器都能在各自独立的环境中运行,从而轻松满足不同项目对于软件版本的多样化需求。
四、操作示例
4.1 部署思路
本示例的部署思路为:分别拉取nginx、php7.4、php8.0、mysql5.7、mysql8.0镜像,进而创建不同的容器,搭建两套不同的LNMP环境:
- LNMP_a:由nginx + php7.4 + mysql5.7组合而成。
- LNMP_b:由nginx + php8.0 + mysql8.0组合而成。
4.2 拉取镜像
为演示搭建两套不同的LNMP环境,先构建第一套环境(nginx+PHP 7.4+mysql 5.7)。首要步骤是将所需镜像全部拉取下来,随后查看当前已拉取到本地的所有镜像。
# 拉取镜像
docker pull nginx
docker pull php:7.4-fpm
docker pull php:8.0-fpm
docker pull mysql:5.7
docker pull mysql:8.0
# 查看镜像
docker images
4.3 部署LNMP_a
依据LNMP_a(nginx + php7.4 + mysql5.7)的环境要求,按以下命令依次执行,将顺序创建数据库、PHP以及nginx的容器,并完成相关配置。
# 建立lnma_a项目的各功能目录
mkdir -p ~/lnmp_a/{www,nginx,mysql}
# 建立网络
docker network create network_a
# mysql容器
docker run -d --name mysql57_a \
-p 33061:3306 \
-v ~/lnmp_a/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root_password \
--network network_a \
mysql:5.7
# php容器
docker run -d --name php74_a \
-v ~/lnmp_a/www:/var/www/html \
--network network_a \
php:7.4-fpm
# nginx conf配置文件
vim ~/lnmp_a/nginx/default.conf
########## 将下方内容复制至配置文件内 ##########
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass php74_a:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
########## 将上方内容复制至配置文件内 ##########
# nginx容器
docker run -d --name nginx_a \
-p 8081:80 \
-v ~/lnmp_a/www:/var/www/html \
-v ~/lnmp_a/nginx/default.conf:/etc/nginx/conf.d/default.conf \
--network network_a \
nginx:latest
4.3.1 镜像容器说明
执行docker ps -a
命令查看容器。其中,第一个nginx容器是前期体验时创建的;而后续名称中带有下划线“_a”的三个容器,则是为创建第一个项目(LNMP_a)所生成。这三个容器的数据相互独立,并且此nginx容器与最初体验时创建的nginx容器彼此互不干扰。
4.3.2 测试文件说明
为检验容器能否正常工作,创建一个静态文件和一个动态PHP文件进行测试。
访问静态文件时,页面显示“hello lnmp_a”,表明静态文件可正常解析。
访问PHP文件时,呈现phpinfo信息,显示当前PHP的相关信息,说明PHP动态解析功能也已实现。
# 建立网站静态文件
vim ~/lnmp_a/www/index.html
# 内容
hello lnmp_a
# 建立网站php文件
vim ~/lnmp_a/www/index.php
# 内容
<?php
phpinfo();
4.3.3 数据库测试说明
同时对数据库进行测试,新建一个数据库,检查数据库能否正常创建,以及对应文件夹中是否显示新建的数据库文件。
# 创建数据库
docker exec -it mysql57_a mysql -uroot -proot_password
CREATE DATABASE IF NOT EXISTS docker_mysql57_db;
SHOW DATABASES;
exit;
# 查看数据库文件
ls ~/lnmp_a/mysql/
4.4 部署LNMP_b
构建LNMP_b环境(nginx + php8.0 + mysql8.0),执行如下命令:
# 建立lnma_b项目的各功能目录
mkdir -p ~/lnmp_b/{www,nginx,mysql}
# 建立网络
docker network create network_b
# mysql容器
docker run -d --name mysql80_b \
-p 33062:3306 \
-v ~/lnmp_b/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root_password \
--network network_b \
mysql:8.0
# php容器
docker run -d --name php80_b \
-v ~/lnmp_b/www:/var/www/html \
--network network_b \
php:8.0-fpm
# nginx conf配置文件
vim ~/lnmp_b/nginx/default.conf
########## 将下方内容复制至配置文件内 ##########
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass php80_b:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
########## 将上方内容复制至配置文件内 ##########
# nginx容器
docker run -d --name nginx_b \
-p 8082:80 \
-v ~/lnmp_b/www:/var/www/html \
-v ~/lnmp_b/nginx/default.conf:/etc/nginx/conf.d/default.conf \
--network network_b \
nginx:latest
# 建立网站静态文件
vim ~/lnmp_b/www/index.html
# 内容
hello lnmp_b
# 建立网站php文件
vim ~/lnmp_b/www/index.php
# 内容
<?php
phpinfo();
# 创建数据库
docker exec -it mysql80_b mysql -uroot -proot_password
CREATE DATABASE IF NOT EXISTS docker_mysql80_db;
SHOW DATABASES;
exit;
# 查看数据库文件
ls ~/lnmp_b/mysql/
4.4.1 创建过程及测试说明
采用与LNMP_a相同的方式,构建第二个项目(LNMP_b)所需的各类环境容器,并对其进行静态文件、PHP动态文件的访问测试,以及数据库测试。
4.4.2 镜像与容器说明
通过命令查看当前服务器上已创建好的容器,可发现容器主要分为3组:
- 第一组仅有一个nginx容器,是最初体验时创建的。
- 第二组容器名称带有下划线“_a”,属于第一个项目(LNMP_a)的3个容器。
- 第三组容器名称带有下划线“_b”,属于第二个项目(LNMP_b)的3个容器。
这些容器相互独立、互不干扰。使用8081端口可访问第一个项目页面,使用8082端口可访问第二个项目页面。借助这种方式,在同一服务器上能够创建多个相互隔离的容器环境。
4.5 主要命令功能说明
4.5.1 创建功能模块目录
第一个命令用于创建各功能模块的目录:
www
目录存放程序和网页文件。nginx
目录存放 Nginx 配置文件。mysql
目录存放数据库文件。
命令使用 mkdir -p
递归创建目录,确保即使父目录不存在,也能顺利生成。
# 创建 lnmp_b 项目的目录结构
mkdir -p ~/lnmp_b/{www,nginx,mysql}
4.5.2 创建网络
为了让容器之间可以相互通信,需要先创建一个 Docker 网络。这样,处于同一网络的容器可以自动发现彼此,便于后续服务协同工作。
# 创建 Docker 网络
docker network create network_b
4.5.3 启动数据库容器
下面的命令用于启动 MySQL 容器,其中:
-d
让容器在后台运行,不影响终端操作。--name
指定容器名称,方便管理。-p
将主机的33062
端口映射到容器的3306
端口,供外部访问数据库。-v
挂载本机~/lnmp_b/mysql
目录到容器内,实现数据持久化,避免容器删除后数据丢失。-e
设定root
用户的初始密码。
# 启动 MySQL 容器
docker run -d --name mysql80_b \
-p 33062:3306 \
-v ~/lnmp_b/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root_password \
--network network_b \
mysql:8.0
4.5.4 启动 PHP 容器
PHP 容器用于处理动态网页,其关键参数:
-v
挂载~/lnmp_b/www
目录到/var/www/html
,让 PHP 代码能够在容器内运行。--network
让 PHP 容器加入network_b
网络,与其他容器互通。
# 启动 PHP 容器
docker run -d --name php80_b \
-v ~/lnmp_b/www:/var/www/html \
--network network_b \
php:8.0-fpm
4.5.5 配置 Nginx
接下来,需要创建 Nginx 配置文件,让其能正确解析 PHP 请求。
# 创建并编辑 Nginx 配置文件
vim ~/lnmp_b/nginx/default.conf
然后将以下内容粘贴到 default.conf
文件中:
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass php80_b:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
4.5.6 启动 Nginx 容器
最后,运行 Nginx 容器,使其能够解析网页并将 PHP 请求转发给 PHP 容器。
-p
将主机8082
端口映射到容器的80
端口,供外部访问网站。-v
绑定~/lnmp_b/www
目录,使网页文件可被访问。-v
挂载 Nginx 配置文件,确保容器内使用我们定义的规则。
# 启动 Nginx 容器
docker run -d --name nginx_b \
-p 8082:80 \
-v ~/lnmp_b/www:/var/www/html \
-v ~/lnmp_b/nginx/default.conf:/etc/nginx/conf.d/default.conf \
--network network_b \
nginx:latest
4.5.7 创建静态和动态测试文件
为了验证环境是否配置成功,可以创建简单的 HTML 和 PHP 文件:
# 创建静态 HTML 页面
vim ~/lnmp_b/www/index.html
内容如下:
hello lnmp_b
然后,创建 PHP 测试文件:
# 创建 PHP 测试文件
vim ~/lnmp_b/www/index.php
内容如下:
<?php
phpinfo();
4.5.8 验证数据库是否可用
进入 MySQL 容器,创建测试数据库,并查看是否成功:
# 连接数据库容器
docker exec -it mysql80_b mysql -uroot -proot_password
然后执行:
CREATE DATABASE IF NOT EXISTS docker_mysql80_db;
SHOW DATABASES;
exit;
还可以在主机上检查数据库文件是否创建成功:
ls ~/lnmp_b/mysql/
五、Docker Compose
采用上述方法,的确能够创建多个相互独立、互不干扰的容器,以此搭建不同项目,使其使用不同的运行环境。然而,该方法存在显著弊端,命令执行过程繁杂,所需配置众多,这不仅给后期维护带来极大困难,在进行环境迁移时也极为不便。
面对这类情况,通常会采用另一种解决方案——docker compose。它能有效简化容器的管理与部署流程,极大提升工作效率。
5.1 安装Docker Compose
依照文档中的指定命令逐步进行安装操作。安装完毕后,可通过查看版本号信息来确认安装是否成功。若能获取正确的版本信息,即表明安装过程顺利完成。
# 安装编译 Python 包所需的基础工具和 bcrypt 的依赖:
sudo yum install -y gcc openssl-devel bzip2-devel libffi-devel python3-devel make
# 升级 pip 和 setuptools
sudo pip3 install --upgrade pip setuptools wheel
# 安装 docker-compose
sudo pip3 install docker-compose
# 查看版本
docker-compose --version
5.2 建立目录及核心配置文件
# 建立 lnmp_c 项目的各功能目录
mkdir -p ~/lnmp_c/{www,nginx,mysql}
# 建立 docker-compose.yml 文件
vim ~/lnmp_c/docker-compose.yml
5.3 编写docker-compose.yml
docker-compose.yml是整个配置体系中的核心文件。借助该文件,可将多个存在关联关系的容器统一定义在一处,从而避免手动输入冗长且复杂的命令。它能有效确保开发、测试以及生产环境的一致性,自动处理容器之间的依赖关系,实现整个应用的快速启动与销毁,极大地提升了项目部署与管理的便捷性。
version: "3"
services:
nginx:
image: nginx
container_name: nginx_c
restart: always
ports:
- 8083:80
- 4433:443
volumes:
- ~/lnmp_c/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ~/lnmp_c/www:/var/www/html
php:
image: php:7.4-fpm
container_name: php74_c
restart: always
volumes:
- ~/lnmp_c/www:/var/www/html
mysql:
image: mysql:8.0
container_name: mysql80_c
restart: always
ports:
- 33063:3306
volumes:
- ~/lnmp_c/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=lnmp_c
- MYSQL_USER=lnmp_c_user
- MYSQL_PASSWORD=lnmp_c_password
5.4 编写nginx conf配置
# nginx conf 配置文件
vim ~/lnmp_c/nginx/default.conf
########## 将下方内容复制至配置文件内 ##########
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass php74_c:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
########## 将上方内容复制至配置文件内 ##########
5.5 启动服务
依据预先编写好的docker-compose.yml配置文件,执行特定命令,即可自动创建相关容器,快速搭建起完整的运行环境。
# 进入目录
cd lnmp_c
# 启动容器
docker-compose up -d
# 建立网站静态文件
vim ~/lnmp_c/www/index.html
# 内容
hello lnmp_c
# 建立网站 php 文件
vim ~/lnmp_c/www/index.php
# 内容
<?php
phpinfo();
# 查看数据库文件
ls ~/lnmp_c/mysql/
5.6 建立静态及动态测试文件
创建静态的html文件与动态的PHP文件,以此检验已创建好的容器是否能够正常解析这两类文件,进而验证整个环境的功能性。
5.7 查看数据库文件
由于在配置文件中已预先创建了一个数据库,通过相关命令在文件系统中进行查看,能够确切地找到对应的数据库文件,这进一步证明了数据库的创建操作准确无误。
5.8 docker-compose.yml文件介绍
此部分主要对配置文件中的三个核心组成部分进行详细说明。在阅读和编写该文件时,需重点关注类似于-v、-p、-e这类参数的设置,它们分别对应端口映射、文件映射以及环境变量的配置,这些参数的正确设置对于整个容器环境的正常运行至关重要。
5.9 docker-compose的启动与重启
通过docker compose方式创建的容器,在重启操作方面具备极高的便捷性。重启操作主要可分为相对路径重启和绝对路径重启两种方式。
方法一:相对路径写法
# 停止并删除所有由 Compose 管理的容器
docker-compose down
# 启动容器
docker-compose up -d
方法二:绝对路径写法
# 停止并删除所有由 Compose 管理的容器
docker-compose -f ~/lnmp_c/docker-compose.yml down
# 启动容器
docker-compose -f ~/lnmp_c/docker-compose.yml up -d
六、迁移测试
6.1 迁移说明
在服务器迁移场景中,操作极为简便。仅需将当前服务器上项目lnmp_c的目录完整复制到目标服务器。随后,在目标服务器上进入指定目录,重新执行docker-compose up -d
命令,系统便能一键自动拉取并创建项目lnmp_c所需的全部容器。由于整个项目目录被一同打包迁移,网站文件与数据库数据得以完整保留,确保迁移后项目的正常运行不受影响。
6.2 迁移前数据库准备
为全面且精准地测试数据迁移的完整性,在迁移操作前,需通过终端对项目c的数据库进行如下准备工作:创建特定的表,并添加一些数据记录。后续可通过对比迁移前后的数据,来验证迁移效果。
docker exec -it mysql80_c mysql -uroot -proot_password
SHOW DATABASES;
use lnmp_c;
CREATE TABLE `test` (
`id` int(11) NOT NULL,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `test` (`id`, `title`) VALUES
(1, 'title'),
(2, 'test');
ALTER TABLE `test`
ADD PRIMARY KEY (`id`);
ALTER TABLE `test`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
SELECT * FROM `test`;
exit;
6.3 迁移过程说明
本次迁移测试选用一台全新的测试服务器。通过执行相关命令,可清晰看到项目c的文件已成功复制至该服务器,且此时服务器上尚未安装任何相关镜像与容器。当执行启动docker compose文件的命令后,服务器即刻自动开始拉取项目所需的镜像,并依照配置自动创建对应的容器。
容器创建完成后,通过在浏览器中输入“IP地址加端口”的方式,能够顺利访问项目的静态页面与动态页面。同时,借助终端进入数据库容器,经检查发现,此前创建的数据库表以及添加的数据记录均完整无缺地保留了下来。由此可见,通过这种基于Docker compose的迁移方式,能够确保新旧服务器在程序运行、数据库状态以及整体环境等方面完全一致,有力保障了项目迁移的高效性与稳定性。
总结
本期教程至此已全部结束。通过对Docker两种使用方法的对比分析,不难发现Docker compose在实际应用中展现出了更高的灵活性与便捷性。因此,在日常工作及项目部署中,强烈推荐使用Docker compose的方式来构建和管理Docker容器环境,以提升工作效率,优化项目部署流程。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。
文章由技术书栈整理,本文链接:https://study.disign.me/article/202511/14.docker-and-docker-compose-application-deployment.md
发布时间: 2025-03-13