Docker
腾讯云租一个服务器
镜像操作
docker search nginx # 搜索镜像
docker pull nginx # 下载最新nginx镜像
docker images # 列出所有镜像列表docker pull nginx:1.26.0
docker images
docker rmi nginx:latest # 删除镜像,或者images查看唯一id后删除
docker rmi ****** # 查看唯一id后删除启动容器
docker run --help
docker run nginx:1.26.0 # 如果没有镜像会自动下载
docker ps # 查看所有运行中的Docker容器
docker ps -a # 查看所有容器,包括停止了的
docker ps -aq # 查看所有容器<仅显示容器id>
docker start 592887 # 启动容器
docker stop 592 # 停止
docker restart 592 # 无论容器是运行还是停止都可以启动
docker stats # 查看容器的cpu,内存包括网络io
docker logs 592 # 查看容器日志
docker rm 592 # 删除容器,需要先删除
docker rm -f 592 # 强制删除容器
docker rm -f $(docker ps -aq) # 删除所有容器docker run详细解读
# 先来个无用示范,假设名字容器id是 ebd
docker run -d --name xxx nginx # 指定后台启动,指定容器名字
docker ps # 查看
# 端口映射 p -> port 让浏览器可以访问
# 先删除上面的 ebd 容器
docker rm -f ebd
# 正确方式
docker run -d --name xxx -p 80:80 nginx ##################### <主机端口>:<容器端口>
# 进入容器,容器名xxx可以替换为容器id的缩写
docker exec -it xxx /bin/bash
ls
# 退出容器
docker exit保存镜像
# 上一步创建的容器叫做xxx,使用镜像是nginx,现在commit
docker commit -m "update index.html" xxx newnamexxx:v1.0
docker images # 查看发现多了一个镜像叫做newnamexxx,版本v1.0
docker save -o newnamexxx:v1.0 # 镜像打包为tar
ls
# 加载tar包获取到镜像,之后可以run了
docker load -i newnamexxx.tar分享社区
docker login
# 账号:
# 密码:
docker tag # dockerhub为了区分这些镜像,需要用户名+镜像
docker tag newnamexxx:v1.0 liuzy/newnamexxx:v1.0 # 名字可改
docker images # 再查看一下,镜像有个相同id名字不同而已
docker push liuzy/newnamexxx:v1.0推送完成后可以添加镜像的说明书,Repository overview描述一下,比如启动命令,如何使用
存储:目录挂载
运行在自己的机器外面开辟一个目录(初始化为空,导致内部也为空)映射到内部目录,实时更改,确保容器重启后数据丢失
docker run -d -p 80:80 -v /app/nghtml:/usr/share/nginx/html --name app01 nginx
# 解释 <外部目录路径>:<容器内部目录路径>
cd /app/nghtml
ls
echo 22222 > index.html
ls
# 浏览器重新访问,显示22222
# 删除容器后,重新执行上面的run命令,还是能够访问显示22222
docker rm -f ba6 # ba6是上面运行的容器id
docker run -d -p 80:80 -v /app/nghtml:/usr/share/nginx/html --name app01 nginx
ps存储:卷映射
与目录挂载,初始化时候给个空目录不同,卷映射从容器内部复制文件到卷中
docker run -d -p 99:80 -v ngconf:/etc/nginx --name app03 nginx
# ↑ 卷 ngconf 的位置在 /var/lib/docker/volumes中
# 解释 <卷名>:<容器内部目录路径>
# 卷名开头没有斜杠 /
# 查看所有卷
cd ~
pwd
docker volume ls
docker volume create haha # 直接在外部创建卷
docker volume inspect ngconf # 打印卷信息
docker volume rm $(docker volume ls -q) # 删除所有卷网络:
- 自定义网络
ip a
docker run -d -p 88:80 --name app1 nginx
docker run -d -p 99:80 --name app2 nginx
docker inspect app1 # 查看ip地址
docker inspect app2 # 查看ip地址
docker exec -it app1 bash
curl http://172.17.03:80 # 上面<docker分配的唯一ip地址>:<容器端口>docker为每个容器分配唯一ip,使用容器ip+容器端口可以互相访问
ip由于各种原因可能发送变化
- 创建自定义网络,容器名就是稳定域名
docker network --help
docker network create mynet
docker network ls
# 先删除之前的示例容器
docker rm -f $(docker ps -aq) # 删除所有容器
# 创建容器到自定义网络
docker run -d -p 88:80 --name app1 --newwork mynet nginx
docker run -d -p 99:80 --name app2 --newwork mynet nginx
docker exec -it app1 bash
curl http://app2:80- Redis主从集群
同一个网络下两个redis容器,实现主从同步,读写分离,主机处理写,从机处理读
分别目录挂载确保数据不丢失
注意:下面 -v 中的挂载目录需要修改一下读写权限哈(chmod),用于持久化同步容器数据的
# 主机 \ 代表换行输入
docker run -d -p 6379:6379 \
-v /app/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=123456 \
-- newwork mynet --name redis01 \
bitnami/redis
# 从机,需要配置连接到的主机名和密码等信息
docker run -d -p 6380:6379 \
-v /app/rd2:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_MASTER_HOST=redis01 \
-e REDIS_MASTER_PORT_NUMBER=6379 \
-e REDIS_MASTER_PASSWORD=123456 \
-e REDIS_PASSWORD=123456
--network mynet --name redis02 \
bitnami/redisMySQL实践示例
# 配置文件和数据存储目录挂载,都是空
docker run -d -p 3306:3306 \
-v /app/myconf:/etc/mysql/conf.d \
-v /app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.37-debian
docker ps # 查看启动Docker Compose 批量管理容器
compose.yaml文件
name: myblog
services:
mysql:
container_name: mysql
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
network:
- blog
wordpress:
images: wordpress
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST: mysql
- WORDPRESS_DB_USER: root
- WORDPRESS_DB_PASSWORD: 123456
- WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always
network:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordpress:
networks:
blog:vim compose.yaml # 编辑 esc 退出 wq
ls
docker compose up --help
docker comopse down --help
docker compose -f compose.yaml up -d
docker compose up -d # 上线:首次启动
docker compose down # 下线
docker compose -f compose.yaml down --rmi all -v # 下线容器并删除所有的镜像和卷
docker compose start x1 x2 x3
docker compose stop x1 x3
docker compose scale x2=3下线后卷里面的数据不会消失,继续上线会恢复
Dockerfile 制作镜像
java -jar app.jar --server.port=8888 # 指定运行端口拷贝app.jar到服务器根目录
vim Dockerfile # 编写一个Dockerfile文件 输入 i 进行编辑 esc wq
ls
cat Dockerfile
docker build -f Dockerfile -t myjavaapp:v1.0 . # 最后的 . 指定了目录位置,对应Dockerfile文件路径Dockerfile文件
FROM openjdk:17 # 镜像 java 17
LABEL author=liuzy # 标签
COPY app.jar /app.jar # 复制到运行容器的路径,注意前面app.jar位置与下面的 . 有关
EXPOSE 8080 # 容器端口
ENTRYPOINT ["java","-jar","/app.jar"] # 容器固定启动命令镜像分层机制
TIP
Docker 镜像并非是一个完整的、不可分割的文件,而是由一系列的只读层(layer)堆叠而成。每一层都代表了镜像构建过程中的一个步骤,例如一次文件的添加、修改或删除操作。这些层按照顺序堆叠,形成一个统一的文件系统视图,最终构成了一个完整的镜像。
节省存储空间:不同的镜像可以共享相同的基础层。例如,多个基于 ubuntu:latest 的镜像都可以共享 ubuntu:latest 这个基础层,而不需要每个镜像都单独存储一份完整的基础镜像文件,大大节省了磁盘空间。
加速镜像构建:当对镜像进行修改或更新时,只需要重新构建发生变化的层,而不需要重新构建整个镜像。例如,如果只是修改了 Dockerfile 中的 COPY 指令,那么只需要重新构建该指令对应的层,其他层可以直接复用,从而显著缩短了镜像构建的时间。
加速镜像分发:在分发镜像时,只需要传输发生变化的层,而不需要传输整个镜像。这样可以减少网络传输的数据量,加快镜像的下载速度。