docker 学习笔记 - 快速上手
1、下载和安装
官网:https://docs.docker.com/get-started/get-docker/
# centos9 安装docker
# 配置 Linux 系统的 IP 转发功能
cat >> /etc/sysctl.conf <<-EOF
net.ipv4.ip_forward=1
EOF
# 重新加载 sysctl.conf
sysctl -p
# 通过yum包管理器安装三个软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里云 Docker 镜像仓库地址
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新 yum 缓存
yum makecache fast
# 安装 Docker 引擎
yum -y install docker-ce
# 启动 Docker 服务
service docker start
# 查看 Docker 版本信息
docker version
# 开机自启
sudo systemctl enable docker
配置国内镜像源(2025/4/10)
cat >> /etc/docker/daemon.json <<-EOF
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
EOF
systemctl daemon-reload
systemctl restart docker
基本概念
1、镜像(Image)
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。
镜像和容器 的关系,就像是面向对象程序设计中的类和实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
2、容器(Container)
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
3、仓库(Repository)
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。一个Docker Registry中可以包含多个仓库;每个仓库可以包含多个标签;每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
常用指令合集
配置非主用户也可以使用docker命令
# 查看是否有 docker 用户组
# 通常 Docker 安装后会自动创建一个名为 docker 的用户组。可以用下面命令查看:
cat /etc/group | grep docker
# 如果没有,可以手动创建
sudo groupadd docker
# 把 非 root 用户加入到 docker 组,-aG 表示 追加到组,而不是覆盖用户原有的组。
sudo usermod -aG docker huy(username)
# 使组更改立即生效
newgrp docker
修改容器内配置文件
在启动容器后想要修改容器内的配置文件,基本都是将配置文件先复制出容器,因为在里面是没有配置vi的。
docker cp <源路径> <目标路径>
# 从容器复制到主机:
docker cp <容器ID或名称>:<容器内路径> <主机路径>
# 从主机复制到容器:
docker cp <主机路径> <容器ID或名称>:<容器内路径>
# 修改配置以后重启指令
docker restart <容器ID或容器名称>
部分经常会变动的文件可以使用挂载
镜像
拉取镜像:docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
- 示例:
docker pull [docker.1ms.run/library/]tomcat:9 - []表示可选项,前面配置了国内镜像可以不用写
查看所有镜像 :docker images
docker images 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。
查看镜像细节 :docker inspect tomcat:9
移除镜像 : docker rmi tomcat:9
运行: docker run tomcat:9(容器命令里详解)
查看镜像、容器、数据卷所占用的空间:docker system df
tomcat:9 这里是 REPOSITORY,也可以是 IMAGE ID,(docker images 可见)
容器命令
运行容器指令: docker run -d -p 8000:8080 --name tomcat9 tomcat:9
-p 8000:8080:将容器的 8080 端口映射到宿主机的 8000 端口
-d 表示以 detached 模式(后台模式)运行容器
--name 为启动容器起别名
还可以添加如
-rm 表示容器退出后随之将其删除
-v 挂载
-e 参数用于设置环境变量(格式 -e VAR1=value1 -e VAR2=value2 ...)
--env-file (后接需要读取的文件 和 启动的容器)
--network (后接网络名称,适用于容器之间网络互通,docker network create -d bridge my-net 创建网络)
此时访问 ip地址:8000 即可看到 tomcat 404 的界面了,创建 index.html 使用下示例指令即可修改启动界面
mkdir ROOT
echo '<h1>Hello, Docker!</h1>' > /usr/local/tomcat/webapps/ROOT/index.html
docker run 在本地没有镜像的时候会远程先拉去一个镜像再启动镜像
支持启动时资源限定
--memory 500m 限定容器的内存资源 为 500MB
--network-bandwidth 1G 限定容器的网络带宽
查看启动容器:docker ps
-a :列出所有容器(包括正在运行的和已停止的容器),不加默认显示正在运行的容器
暂停容器:docker pause <容器名称或ID>
恢复容器的运行状态: docker unpause <容器名称或ID>
停止容器: docker stop <容器名称或ID>
重新启动容器:docker start <容器名称或ID>
进入容器: docker exec -it tomcat9 /bin/bash
-i:交互式模式。
-t:分配一个伪终端。
-/bin/bash:指定在容器中启动一个 Bash shell。
挂载和卷
在容器中管理数据(数据持久化)主要有两种方式:
- 数据卷(Volumes)
- 挂载主机目录 (Bind mounts)
数据卷 是一个可供一个或多个容器使用的特殊目录,被设计用来持久化数据的,它绕过 UnionFS,可以提供很多有用的特性:
- 数据卷 可以在容器之间共享和重用
- 对 数据卷 的修改会立马生效
- 对 数据卷 的更新,不会影响镜像
- 数据卷 默认会一直存在,即使容器被删除
创建一个数据卷:docker volume create my-vol
查看所有数据卷:docker volume ls
查看指定数据卷的信息:docker volume inspect my-vol
删除卷:docker volume rm my-vol
删除无主卷:docker volume prune
示例
mkdir /home/init.d
cat>/home/init.d/db.sql<<-'EOF'
USE Test;
CREATE TABLE IF NOT EXISTS User(
ID INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
EOF
docker run
--name mysql8
-v /home/init.d:/docker-entrypoint-initdb.d
-v my-vol:/var/lib/mysql
-e MYSQL_DATABASE=Test
-e MYSQL_ROOT_PASSWORD=root
-d mysql:8.0.22
docker-entrypoint-initdb.d 是 Docker 容器中一个特殊的目录,主要用于在容器启动时自动执行初始化脚本。
定制镜像
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
创建一个 dockerfile
FROM stretch
RUN set -x; buildDeps='gcc libc6-dev make wget' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps
FROM 就是指定 基础镜像
Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
以 scratch 为基础镜像的话,意味着不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:
- shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
- exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式。
常用指令:
- FROM:指定基础镜像。所有的 Dockerfile 必须以 FROM 开头,用来选择一个官方提供的镜像或者自定义的基础镜像。
- RUN:执行命令并创建新的镜像层。这些命令会在构建过程中被执行,并且会被记录为镜像的一部分。
- LABEL:为镜像添加元数据。例如,可以添加作者信息或版本号。
- ENV:设置环境变量。这些变量可以在后续的 RUN 指令中使用,也可以在容器运行时被访问。
- ADD 和 COPY:将文件从主机复制到镜像中。ADD 提供了额外的功能,比如支持远程 URL 和自动解压 tar 文件。
- VOLUME:创建挂载点,允许外部访问容器内的特定目录。
- USER:切换执行命令的用户。这对于提高安全性非常有用。
- WORKDIR:设置工作目录。类似于 Linux 的 cd 命令,它会改变当前的工作目录。
- ENTRYPOINT:配置容器启动时运行的命令。不同于 CMD,ENTRYPOINT 不会被后面的命令覆盖。
- CMD:提供默认的执行参数,当没有指定其他参数时,该命令会被执行。与 ENTRYPOINT 一起使用时,CMD 可以作为 ENTRYPOINT 的默认参数。
- EXPOSE:告知 Docker 容器在运行时监听的端口。这只是一个声明,不会自动打开端口。
# dockerfile
# 使用 OpenJDK 官方镜像作为基础镜像
FROM openjdk:17-jdk-slim
# 设置工作目录
WORKDIR /app
# 将本地的 jar 文件复制到容器的 /app 目录下
COPY target/your-app.jar /app/your-app.jar
# 暴露应用的端口,假设是 8080
EXPOSE 8080
# 启动 Spring Boot 应用
ENTRYPOINT ["java", "-jar", "your-app.jar"]
# docker-compose.yml
version: '3.8'
services:
springboot-app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/your_database
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=your_password
- SPRING_REDIS_HOST=redis
networks:
- app-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: your_password
MYSQL_DATABASE: your_database
ports:
- "3306:3306"
networks:
- app-network
redis:
image: redis:6.2
ports:
- "6379:6379"
networks:
- app-network
networks:
app-network:
driver: bridge
docker-compose 是一个用于定义和管理多个 Docker 容器的工具,它通过一个 docker-compose.yml 配置文件来描述应用中的各个服务、网络、卷等,从而简化了多容器的管理和部署。它的优势在于可以让你用一个命令来启动、停止、查看日志等操作所有的容器,方便处理复杂的应用部署。
- version:指定 Docker Compose 文件的版本,3.8 是一个较新的稳定版本。
- services:定义了多个服务,每个服务代表一个容器。每个服务都可以配置如下:
- build:指定当前目录下的 Dockerfile 用于构建镜像(可选)。如果镜像已经构建好,可以使用 image。
- image:指定要使用的 Docker 镜像。如果没有指定 build,可以直接指定镜像名。
- ports:映射容器的端口到宿主机的端口。
- environment:设置容器的环境变量,通常用于数据库连接配置等。
- depends_on:指定服务的依赖关系,确保依赖的服务(如数据库)先启动。
- networks:指定该服务所属的网络,用于容器间的通信。
networks:定义多个网络,容器可以根据需要连接到这些网络。这有助于确保服务之间的隔离性,或让多个服务共享网络。
网络
Docker 网络是 Docker 容器之间通信的基础。Docker 提供了多种网络类型,包括:
- bridge 网络:这是默认的网络类型,它使用 Docker 的虚拟网桥来实现容器之间的通信。每个容器都有一个独立的 IP 地址,并且可以通过容器的名称或 ID 来访问。
- host 网络:容器使用宿主机的网络栈,容器的网络配置与宿主机完全相同。这意味着容器可以直接访问宿主机的网络接口,并且可以直接使用宿主机的 IP 地址。
- overlay 网络:这是一种分布式网络,用于在多个 Docker 守护进程之间实现容器之间的通信。它使用虚拟交换机来实现容器之间的通信。
- macvlan 网络:这是一种基于 MAC 地址的网络,它允许容器使用宿主机的物理网络接口来实现容器之间的通信。
- none 网络:容器没有网络连接,容器的网络配置与宿主机完全相同。这意味着容器无法访问宿主机的网络接口,并且无法使用宿主机的 IP 地址。
创建网络:docker network create my-net
查看网络:docker network ls
删除网络:docker network rm my-net
查看网络详情:docker network inspect my-net
连接容器到网络:docker network connect my-net container-name
断开容器与网络的连接:docker network disconnect my-net container-name
删除容器时自动断开与网络的连接:docker run --network my-net --rm container-name
查看容器的网络连接:docker network inspect container-name
查看容器的网络连接:docker network inspect container-name

浙公网安备 33010602011771号