docker

Posted by zangxin on June 2, 2025

docker

说明

概观

截屏2025-06-02 20.19.52

镜像: 软件包

容器: 启动的一个软件

容器和虚拟机部署的区别

  • 截屏2025-06-02 20.20.26

  • 容器类似轻量级的VM 容器共享操作系统的内核

  • 容器相互隔离

  • 容器有自己的文件系统, cpu, 内存,进程空间等

  • 容器可以跨平台

常用命令(镜像)

# 以nginx举例

检索镜像

1
docker search nginx

#下载镜像

1
docker pull nginx

删除镜像

1
docker rmi

查看已经下载的镜像

1
docker images

启动应用

1
docker run 镜像名/id

特定版本的镜像

  • docker pull 下载的是latest版本的 要下载特定版本需要在dockerhub查看版本tag
    1
    
    docker pull nginx:1.26.0
    

    删除特定版本的docker rmi nginx:1.26.0 或者docker rmi 镜像id

常用命令(容器)

#查看运行的容器

1
docker ps 

#查看所有的容器

1
docker ps -a

#启动容器

1
 docker start 容器名

#停止

1
docker stop 容器id

#重启

1
docker restart 容器id

#删除容器(停止的)

1
docker rm 

一键删除(慎用)

#-a 所有容器, -q 只显示id dokcer rm -f $(docker ps -aq)

端口映射

# –name 容器名为myNginx666

-p 端口宿主机27182映射到myNginx666的80端口

-d 后台运行

1
docker run -d --name myNginx666 -p 27182:80 nginx

进入容器

docker exec -it ed9ccdba0d4f bash

修改nginx的index.html页面

1
echo "<h1>Hello,Docker</h1>" > /usr/share/nginx/html/index.html

在宿主机查看

1
curl localhost:27182

分享/使用容器镜像

#分享,打包自己的容器镜像

commit : Create a new image from a container’s change

-a:author , -m : commit message

1
docker commit -a "zangxin_test" -m "update index.html" myNginx666 zangxin_nginx:v1.0

把镜像保存一个文件 zangxinNginx.tar

1
 docker save -o zangxinNginx.tar zangxin_nginx:v1.0

加载文件

1
2
docker load -i zangxinNginx.tar
docker run -d --name mynginx -p 22222:80  zangxin_nginx:v1.0

访问: curl localhost:22222

分享镜像到DockerHub

  • #1.需要登录到dockerhub, zangxin51是用户名,zangxin51/zangxin_nginx是仓库名 #2.修改tag为自己的用户名/镜像名, 否则推不上去
    1
    
    docker tag zangxin_nginx:v1.0 zangxin51/zangxin_nginx:v1.0
    

    #推送镜像, 相当于在dockerhub创建了一个respository

    1
    
    docker push  zangxin51/zangxin_nginx:v1.0
    

    #3.创建latest分支, 别人拉的时候不用写版本好也可拉取

    1
    2
    
    docker tag zangxin51/zangxin_nginx:v1.0 zangxin51/zangxin_nginx:latest
    docker push zangxin51/zangxin_nginx:lates
    

目录挂载,以外文件为准

痛点

  • 1.在容器内部编写文件不方便 2.重启容器后,文件销毁

#宿主机~~/devtools/docker_mount/app/nginx_html映射到nginx容器的/usr/share/nginx/html目录下

#如果宿主机没有文件夹,会自动创建

1
docker run -d -p 15000:80 --name app01 
1
-v ~/devtools/docker_mount/app/nginx_html:/usr/share/nginx/html nginx:latest

配置了挂载后, 在容器内修改可以影响到外部文件, 在挂载文件修改也能影响到容器, 其实本质上就是一份文件

同步容器时间问题

  • -v /etc/localtime:/etc/localtime

卷映射(volumes) 以内部文件为准

痛点

  • 1.目录挂载可以无法再启动时使用nginx容器中默认配置文件, 挂载了目录导致原来/etc/nginx/nginx.conf文件消失了, 导致nginx启动不了

  • 卷映射可以把nginx中默认配置文件给映射到宿主机磁盘中

语法 -v ngconf:/etc/nginx

  • 与目录挂载的区别, 目录挂载是你指定目录的 而卷映射是docker统一管理

在linux上卷目录在放在

  • /var/lib/docker/volumes/

在mac上!!!

  • 执行
    1
    
    docker run --pid=host --privileged -it --rm justincormack/nsenter1
    

    然后再

    1
    
    cd /var/lib/docker/volumes/
    

命令

列出所有卷

1
docker volume ls

#创建卷

1
docker volume create ggstar

#查看卷的明细

1
docker volume inspect ggstar

删除docker容器并不会把卷也删除掉, 保证数据不会丢失

网络

在两个容器之间访问

  • 比较傻的方法

    • 通过外部端口映射来访问, 饶了一大圈,明明两个容器是邻居
      1
      
      curl 192.168.2.42:15000  
      

docker0默认网络

  • ifconfig

查看容器网络网关

1
docker instpect app01

截屏2025-06-02 20.23.04

容器网关默认是172.17.0.1

docker 为每个容器提供默认ip

  • 访问别的容器, 可以通过容器ip + 容器端口
    1
    
    curl http:172.17.0.3:80
    

缺点

  • 容器重启后ip变化

解决docker0的ip变化

  • dokcer0默认不支持主机域名

  • 创建自定义网络, 容器名就是稳定域名

自定义网络容器名,就是稳定域名

  • #创建网络
    1
    
    docker network create mynet
    

    #查看网络

    1
    
    docker network ls
    

    创建容器时加入网络

    1
    
    docker run -d -p 88:80 --name app1 --network mynet nginx:latest
    

    #在容器之间访问(进入到容器中,使用curl)

    1
    2
    
    curl http://app1
    curl http://app2
    

实例,搭建redis容器

通过配置环境变量

截屏2025-06-02 20.23.56

  • master(redis01)
1
2
3
4
docker run -d -p 6379:6379 -v ~/devtools/docker_mount/app/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=root \
--network mynet --name redis01 \
  • salve(redis02)
1
2
3
4
5
6
7
8
docker run -d -p 6380:6379 -v ~/devtools/docker_mount/app/rd2:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_PASSWORD=root \
-e REDIS_MASTER_HOST=redis01 \
-e REDIS_MASTER_PORT_NUMBER=6379 \
-e REDIS_MASTER_PASSWORD=root \
--network mynet --name redis02 \
bitnami/redis
  • 在master中写入数据, 查看slave中是否有数据 在anoter redis desktop这个可视化app中查看

环境变量

-e

最佳实践

是否需要端口访问

  • 端口映射

是否需要配置挂载

  • 卷挂载

是否需要数据挂载

  • 目录挂载

是否需要配置环境变量

安装mysql

1
2
3
4
5
docker run -d -p 3307:3306 \
-v ~/devtools/docker_mount/app/myconf:/etc/mysql/conf.d \
-v ~/devtools/docker_mount/app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name zangxin_mysql mysql:latest

docker compose

说明

  • docker pose用来批量管理容器

how to

  • 配置compose.yaml

命令

  • 上线
    1
    
    docker compose up -d
    

    下线

    1
    
    docker compose down
    
  • 启动
    1
    
    docker compose  start x1 x2 x3
    

    停止

    1
    
    docker compose stop x1 x3
    

    扩容,启动x2三个实例

    1
    
    docker compose scale x2=3
    

编写compose file

  • 文档

    • https://docs.docker.com/reference/compose-file/

安装一个wordpress blog

  • docker_compose.yaml

    • name: myblog services: ```bash mysql: container_name: myblog_mysql image: mysql:8.0 ports:
      • “3306:3306” environment:
      • MYSQL_ROOT_PASSWORD=root
      • MYSQL_DATABASE=wordpress volumes: 挂载
      • /Users/qingsongcai/devtools/docker_mount/myblog/mysql-data:/var/lib/mysql
      • /Users/qingsongcai/devtools/docker_mount/myblog/myconf:/etc/mysql/conf.d restart: always # 开机自启 networks:
      • myblog

    wordpress: image: wordpress ports: - “8080:80” environment: WORDPRESS_DB_HOST: myblog_mysql WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: root WORDPRESS_DB_NAME: wordpress volumes: - wordpress:/var/www/html restart: always networks: - myblog depends_on: #指定依service赖顺序, mysql先启动, 然后再启动这个 - mysql ```

volumes: #卷挂载要声明

1
  wordpress:

networks: #定义网络

1
  myblog:
  • docker compose -f docker_compose.yaml up -d

    • 启动 会判断是否修改过,只启动修改过的
  • docker compose -f docker_compose.yaml down

    • 停止, 并删除容器和网络, 但是不会删除volumes和挂载目录和镜像

● 增量更新

1
  ○ 修改 Docker Compose 文件。重新启动应用。只会触发修改项的重新启动。

● 数据不删

1
  默认就算down了容器,所有挂载的卷不会被移除。比较安全

Dockerfile

作用,制作镜像

文档

  • https://docs.docker.com/reference/dockerfile/

常用指令

截屏2025-06-02 20.25.27

文件名固定Dockerfile

  • FROM openjdk:17
1
LABEL author=zangxin

把当前目录下的app.jar放到容器的根目录下/

1
COPY app.jar /app.jar

#暴露端口

1
EXPOSE 8080

#执行 java -jar /app.jar

1
ENTRYPOINT ["java", "-jar","/app.jar"]

构建镜像

  • .点表示在当前目录构建

    1
    
    docker build -f Dockerfile -t myjavapp:v1.0 .
    

镜像分层机制

截屏2025-06-02 20.26.23

查看镜像层和读写层内存占用量

  • docker ps -s

安装常用中间件

https://www.yuque.com/leifengyang/sutong/au0lv3sv3eldsmn8

查看容器日志

1
docker logs names

docker RemoteAPI + idea集成工具使用

开启docker服务器守护进程绑定到2375接口

  • vim /usr/lib/systemd/system/docker.service

  • [Service] Type=notify

the default is not to use systemd for cgroups because the delegate issues still

exists and systemd currently does not support the cgroup feature set required

for containers run by docker

ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 –containerd=/run/containerd/containerd.sock

  • 在上面那个文件中[Service]的块中的ExecStart添加-H tcp://0.0.0.0:2375 使得远程可以连接,暴露端口

  • 先重启服务,两个都要执行
    1
    
    systemctl daemon-reload
    

    sudo systemctl restart docker.service

  • 还要注意关闭防火墙或者开放端口

  • 远程连接测试

    • 先在本机测试可以OK吗
      1
      
      docker -H tcp://127.0.0.1:2375 ps
      

      然后在其他机器测试可以OK吗

      1
      
       docker -H tcp://192.168.2.85:2375 ps
      
  • idea连接

    • services中选择docker 编辑配置 选择TCP socket engine api url填写为: tcp://192.168.2.85:2375