一. 安装Docker
1.1 卸载旧版
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-selinux
1.2 配置Docker的yum库
首先要安装一个yum工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
安装成功后,执行命令,配置Docker的yum源(已更新为阿里云源):
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
更新yum,建立缓存
sudo yum makecache fast
注意!!! 如果报了这样的错表示无法访问外网: 请按照下面提示做 已加载插件:fastestmirror, langpacks Loading mirror speeds from cached hostfile Could not retrieve mirrorlist mirrorlist.centos.org/?release=7&… error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"
One of the configured repositories failed (未知), and yum doesn't have enough cached data to continue. At this point the only safe thing yum can do is fail. There are a few ways to work "fix" this:
1. Contact the upstream for the repository and get them to fix the problem. 2. Reconfigure the baseurl/etc. for the repository, to point to a working upstream. This is most often useful if you are using a newer distribution release than is supported by the repository (and the packages for the previous distribution release still work). 3. Run the command with the repository temporarily disabled yum --disablerepo=<repoid> ... 4. Disable the repository permanently, so yum won't use it by default. Yum will then just ignore the repository until you permanently enable it again or use --enablerepo for temporary usage: yum-config-manager --disable <repoid> or subscription-manager repos --disable=<repoid> 5. Configure the failing repository to be skipped, if it is unavailable. Note that yum will try to contact the repo. when it runs most commands, so will have to try and fail each time (and thus. yum will be be much slower). If it is a very temporary problem though, this is often a nice compromise: yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=trueCannot find a valid baseurl for repo: base/7/x86_64
# 备份yum源
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back
# 下载 yum 源
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 清理缓存
sudo yum clean all
# 生成新的缓存
sudo yum makecache
# 更新yum
sudo yum update
1.3 安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
1.4 启动和校验
# 启动Docker
systemctl start docker
# 停止Docker
systemctl stop docker
# 重启
systemctl restart docker
# 设置开机自启
systemctl enable docker
# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps
1.5 配置镜像加速
镜像地址可能会变更,如果失效可以百度找最新的docker镜像。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.1ms.run"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
二. MySQl部署
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
- docker run -d :创建并运行一个容器,-d则是让容器以后台进程运行
- --name mysql : 给容器起个名字叫mysql,你可以叫别的
- -p 3306:3306 : 设置端口映射。
- 容器是隔离环境,外界不可访问。但是可以将宿主机端口映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。
- 容器内端口往往是由容器内的进程决定,例如MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。
- 格式: -p 宿主机端口:容器内端口,示例中就是将宿主机的3306映射到容器内的3306端口
- -e TZ=Asia/Shanghai : 配置容器内进程运行时的一些参数
- 格式:-e KEY=VALUE,KEY和VALUE都由容器内进程决定
- 案例中,TZ=Asia/Shanghai是设置时区;MYSQL_ROOT_PASSWORD=123是设置MySQL默认密码
- mysql : 设置镜像名称,Docker会根据这个名字搜索并下载镜像
- 格式:REPOSITORY:TAG,例如mysql:8.0,其中REPOSITORY可以理解为镜像名,TAG是版本号
- 在未指定TAG的情况下,默认是最新版本,也就是mysql:latest
三. Docker基础
3.1 常见命令
其他docker命令见官网
接下来我们做一个拉取nginx镜像并创建运行容器来熟悉一下这些命令
# 拉取Nginx镜像
docker pull nginx
# 查看镜像
docker images
# 创建并允许Nginx容器
docker run -d --name nginx -p 80:80 nginx
# 查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 停止容器
docker stop nginx
# 查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
现在容器就只有mysql在运行了
# 查看容器详细信息
docker inspect nginx
# 进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p
# 删除容器
docker rm nginx
# 结果如下:
# Error response from daemon: cannot remove container "nginx": container is running: stop the container before removing or force remove
# 发现无法删除,因为容器运行中
# 方法一:停止nginx服务
docker stop nginx
# 方法二:强制删除容器
docker rm -f nginx
3.2 数据卷
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。 数据卷(Volume) 是Docker容器用来持久化存储和共享数据的一种机制。它独立于容器的生命周期而存在,即使容器被删除,数据卷中的数据也不会丢失。
数据卷的主要特点:
- 持久化:数据卷的生命周期独立于容器,容器删除,卷依然存在。
- 高性能:绕过容器文件系统,直接读写宿主机,I/O性能高。
- 可共享:多个容器可以同时挂载同一个数据卷,实现数据共享。
- 易于管理:可以使用Docker命令(docker volume)或直接操作宿主机文件来管理数据。
演示一下nginx的html目录挂载
# 首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
# 如果数据卷不存在则自动创建数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
# 然后查看数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect html
Mountpoint表示宿主机目录,容器目录是创建时的/usr/share/nginx/html
# 进入宿主机目录
cd /var/lib/docker/volumes/html/_data
# 里面有个html文件 vi查看
vi index.html
可以看到正好就是nginx容器的html文件
3.3 挂载本地目录或文件
数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
# 方法一:
docker run -v /宿主机/绝对路径:/容器内路径 [其他选项] 镜像名 [命令]
# 方法二:
docker run --mount type=bind,source=/宿主机路径,target=/容器路径 [选项] 镜像名
下面是一个示例
# 1.删除原来的MySQL容器
docker rm -f mysql
# 2.进入root目录
cd ~
# 3.创建目录
mkdir mysql
cd mysql
mkdir conf
mkdir data
mkdir init
cd ~
# 4.创建并运行新mysql容器,挂载本地目录
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
mysql
可以看到已经挂载成功了!!!
本地挂载也就是给容器外接个移动硬盘。
- 怕丢数据:就像电脑重装系统,文件会没。挂载后,数据存在外面的"硬盘"里,容器删了数据也在。
- 想改配置:不用重做整个系统镜像,直接在外面改配置文件,容器里立马生效。
- 开发方便:在外面写代码,容器里直接运行,省去反复打包的麻烦。
3.4 自定义镜像
步骤:
- 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
- 安装并配置JDK
- 拷贝jar包
- 配置启动脚本
Dockerfile 参考文档: docs.docker.com/reference/d…
示例:构建一个Java应用
文件Dockerfile的内容如下(用于构造jdk包):
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
执行命令,构造镜像
# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
测试创建并运行
docker run -d --name dd -p 8080:8080 docker-demo:1.0
docker ps
docker logs -f dd
3.5 网络
用docker inspect分别查看MySQL和nginx,可以看到它们的ip网络是不同的
虽然IP不同但是在容器中还是可以互相连接
但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。 所以我们需要自定义网络 参考文档:docs.docker.com/reference/c…
常见命令有:
# 创建一个网络
docker network create ojh
为MySQL和dd都添加’ojh‘网络
docker network connect ojh mysql
docker network connect ojh dd
docker exec -it dd bash
ping mysql
现在无需记住IP地址也可以实现容器互联了。
四. Docker项目部署
4.1 后端部署
打包项目 把hm-service中的Dockerfile文件和target中的hm-service.jar放到root目录中
docker build -t hmall .
docker images
因为dd项目占用了8080端口,所以要构建之前先把之前的dd容器删除 docker rm -f dd
# 创建容器
docker run -d --name hmall -p 8080:8080 --network ojh hmall
# 查看日志
docker logs -f hm
4.2 前端部署
前端代码nginx.conf中要注意你的后端名和前端所在的位置要做一个挂载
server {
listen 18080;
# 指定前端项目所在的位置
location / {
root /usr/share/nginx/html/hmall-portal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://hmall:8080;
}
}
server {
listen 18081;
# 指定前端项目所在的位置
location / {
root /usr/share/nginx/html/hmall-admin;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://hmall:8080;
}
}
- 把/root/nginx/nginx.conf挂载到/etc/nginx/nginx.conf
- 把/root/nginx/html挂载到/usr/share/nginx/html
docker run -d \
--name nginx \
-p 18080:18080 \
-p 18081:18081 \
-v /root/nginx/html:/usr/share/nginx/html \
-v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
--network ojh \
nginx
点击搜索也能返回数据
关机之后再启动不需要再创建容器 直接docker start ~命令启动容器就行了
4.3 DockerCompose基础
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。 Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。
docker compose 和docker run 对比
services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
- "./mysql/init:/docker-entrypoint-initdb.d"
networks:
- hm-net
hmall:
build:
context: .
dockerfile: Dockerfile
container_name: hmall
ports:
- "8080:8080"
networks:
- hm-net
depends_on:
- mysql
nginx:
image: nginx
container_name: nginx
ports:
- "18080:18080"
- "18081:18081"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/html:/usr/share/nginx/html"
depends_on:
- hmall
networks:
- hm-net
networks:
hm-net:
name: ojh
docker compose [OPTIONS] [COMMAND]基础用法
在创建之前先把原先不用的容器和网络删除
docker compose up -d
docker compose ps