Docker入门
Docker可以用一行命令跨平台地运行应用,节省了构建、分享、运行的过程。
Docker的架构
docker-cli(Docker命令行接口)
- docker-cli 是与 Docker 引擎交互的命令行工具,通过它可以创建、管理容器、镜像、网络等。
- 常见命令包括
docker run
、docker ps
、docker stop
、docker build
等。 - docker-cli 通过 Docker API 和 Docker 引擎进行通信。
Docker Host
- Docker 主机是运行 Docker 引擎的服务器,它可以是物理机,也可以是虚拟机。
- 它包含 Docker 引擎和管理的容器资源。
- Docker 主机负责启动容器,管理容器生命周期、网络、存储等资源。
Docker 应用市场 / Docker Hub
- Docker Hub 是 Docker 的官方镜像仓库,用户可以从中获取各种官方和社区提供的镜像。
- 可以将自己创建的镜像上传至 Docker Hub,方便在其他主机上拉取和使用。
- 除了 Docker Hub,Docker 也支持私有仓库,允许企业在自己的网络环境中托管镜像。
镜像(Image)
- 镜像是一个只读的文件系统,它包含了运行某个应用所需的操作系统、依赖包、环境变量等。
- 镜像是容器的蓝图,每次启动容器时,Docker 会基于镜像创建一个容器。
- 镜像是分层的,Docker 镜像的层级结构使得镜像更高效、节省存储。
- 镜像可以通过 Dockerfile 定义,Dockerfile 是描述如何构建镜像的脚本。
容器(Container)
- 容器是基于镜像创建的实例,它是一个运行时环境,包含了应用程序所需的所有依赖、库文件及运行时环境。
- 容器是轻量级的,与虚拟机相比,它不需要运行一个完整的操作系统内核,而是与主机共享操作系统内核。
- 容器启动速度非常快,占用的资源较少。每个容器都是隔离的,它们不会干扰其他容器。
- 容器具有自己的文件系统、CPU、内存、进程空间,但与宿主机操作系统共享内核。
容器的特点
- 轻量:容器不需要完整的操作系统,它只包含应用及其依赖,相比虚拟机更加轻便。
- 快速:容器启动速度极快,几乎没有启动时间。虚拟机启动时需要加载操作系统,而容器只需要启动应用。
- 隔离性:容器通过操作系统层的虚拟化提供进程、网络、存储等资源的隔离。每个容器都有独立的进程空间,但都共享宿主机的操作系统内核。
- 跨平台:容器可以在任何支持 Docker 的平台上运行,从开发环境到生产环境都能保持一致。
- 高密度:同一台机器可以运行多个容器,容器相互隔离且资源占用较低,从而可以提高资源利用率。
容器与虚拟机的区别
- 资源开销:容器共享宿主机的操作系统内核,而虚拟机则需要运行独立的操作系统,因此容器更加轻量、启动更快。
- 隔离性:虚拟机的隔离性更强,因为每个虚拟机都运行独立的操作系统,而容器在内核层面进行隔离。
- 部署速度:容器的启动速度比虚拟机要快得多,因为它不需要加载操作系统,而是直接运行应用。
Docker安装
可以参照官方文档安装,也可以参照下面的内容安装。
在 Ubuntu 上安装
- 移除旧版本Docker
不同操作系统的操作略有差异,但是要卸载的软件包有:
docker.io
docker-compose
docker-compose-v2
docker-doc
podman-docker
- 安装 Docker 相关软件包,如我的系统为 Ubuntu:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
如果下载缓慢,可为 apt 配置国内镜像源,可参照 清华大学镜像源教程 来配置。
- 测试 Docker 是否安装成功:
$ docker -v
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Common Commands:
run Create and run a new container from an image
...
如果没有出现上述运行结果,可能是 Docker 进程未启动,执行:
systemctl start docker
systemctl status docker
可选的命令,如开机自启动、设置国内源:
# 设置国内源
systemctl enable docker --now
# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
下载镜像
下面以在 Docker 中从应用市场下载 Nginx 镜像,然后替换掉里面的默认页面,再将它发布到应用市场的几个步骤为例。
指令 | 代码 |
---|---|
检索 | docker search |
下载 | docker pull |
列表 | docker images |
删除 | docker rmi |
检索镜像:
docker search nginx
这一步我检索失败了,即使配置了国内镜像源,Docker在搜索镜像列表时,还是去docker.io搜索。
上图是老师的 docker search nginx
运行结果。可以看到,NAME 一列为 Docker 搜索到的镜像名称,一般以“作者名/容器名”命名,DESCRIPTION 为关于镜像的描述,STARS 为获取到的星星数,OFFICIAL 为是否为官方镜像,OK 的表示是官方发布的。
然后下载镜像:
$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
bc0965b23a04: Pull complete
650ee30bbe5e: Pull complete
8cc1569e58f5: Pull complete
362f35df001b: Pull complete
13e320bf29cd: Pull complete
7b50399908e1: Pull complete
57b64962dd94: Pull complete
Digest: sha256:fb197595ebe76b9c0c14ab68159fd3c08bd067ec62300583543f0ebda353b5be
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
检查已下载的镜像:
$ docker images # 或者 docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 66f8bdd3810c 3 weeks ago 192MB
Docker 镜像的名称一般为 镜像名:标签
,如上面的 nginx 就为 nginx:latest
,其中 latest 为最新版。我们一般下载的镜像都是最新版,如果我们要下载指定版本,就不要使用 docker search
命令下载了,而是前往 Docker Hub搜索 Nginx,网址为 https://hub.docker.com/_/nginx ,然后从 Overview 选项卡切换到 Tags 选项卡,就可以看到不同的 Nginx 版本了。点击对应版本右面命令的 Copy,就可以下载此版镜像了。
删除镜像,如使用 docker rmi nginx
删除最新版 Nginx 镜像。
启动容器
基础命令
下载镜像之后,我们就可以使用镜像创建容器。
指令 | 代码 |
---|---|
运行 | docker run |
查看 | docker ps |
停止 | docker stop |
启动 | docker start |
重启 | docker restart |
状态 | docker stats |
日志 | docker logs |
进入 | docker exec |
删除 | docker rm |
启动镜像:
docker images
# 显示所有镜像
docker run nginx
# 到这里控制台会阻塞
到第二个命令后,控制台会阻塞,关闭此控制台会令容器停止,我们可以另开一个终端执行其他命令。
查看运行中的容器:
另开一个终端后,执行 docker ps
。
将上一个终端中的阻塞停掉后,再使用 docker ps
就差看不到此容器了,此时可以使用 docker ps -a
查看所有容器,包含已停止的。
我在运行到这里时,关闭终端,容器仍然在运行,此时我们可以使用 docker stop 容器id
关闭此容器,也可以使用 docker start 容器id
再次启用此容器。
容器id 也可被替换为最后的 NAME,即容器名称,也可以使用 id 的前几个字符,即简写。
查看容器占用情况,使用 docker stats 容器id
。
查看容器日志:docker stats 12
。
启动容器后,可以看到 nginx 容器占用 80 端口,但此时在浏览器中是访问不到的。
docker run 的详细用法
运行到这里时,我们每次都启用新的容器,以展示 docker run
不同语法的效果,记得删除它们。
-d
参数,让容器后台运行,不阻塞控制台。
--name
参数,指定容器的名字,替代默认名字。
docker run -d --name mynginx nginx
输出的内容为容器的完整id。
由于容器是运行在容器化技术的,每个容器以及容器与宿主机之间是互相隔离的,从主机不能访问到容器中的 nginx。
使用 docker exec
,可以看到这个容器内也有属于它的文件系统。
它里面安装的 nginx 使用的是它的 80 端口,而不是主机的 80 端口。假如我们想实现访问主机的 88 端口,相当于访问容器的 80 端口,我们要加一个端口映射的操作,具体实现是加 -p 88:80
参数。
-p 外部端口:内部端口
用于指定端口映射。
docker run -d --name mynginx2 -p 88:80 nginx
此时执行 docker ps
,可以看到端口之间的关系。最新创建的容器中,使用了端口映射,由主机的 88 端口映射到容器的 80 端口,而其他的容器则没有使用端口映射,外部不能访问。
docker exec 的详细用法
docker exec
用于进入容器内部,向在执行宿主机打开终端那样,打开容器内部的终端。
语法:docker exec [参数] 容器名 命令
-it
参数代表以交互模式进入容器终端,如果不加此参数,则只执行一次命令。我们一般加上这个参数。
docker exec -it mynginx bash
-it
参数表示已交互模式进入,mynginx 为容器名,bash 代表进入终端(我们在宿主机进入终端就可以执行bash命令)。
在前面,我们说过要修改 nginx 的默认页面,它默认存放在此容器内部的 usr/share/nginx/html
中。阅读文档可以发现,它是可以通过 docker run
的参数指定的。
docker run --name my-custom-nginx-container -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
我们可以使用 vi 更新 nginx 的默认页面,但是为了保持容器的轻量级,容器是不包含这些默认软件的。我们可以使用下面的代码覆盖原有内容。
echo '<h1>Hello Docker!</h1>' > index.html
这样我们再访问浏览器时,就可以看到页面被成功更改了。
保存镜像
操作 | 代码 |
---|---|
提交 | docker commit |
保存 | docker save |
加载 | docker load |
提交镜像 语法:docker commit [选项] 容器名 [镜像名[:标签]]
docker commit -m "update index.html" mynginx mynginx:v1.0
将镜像保存为一个文件 语法:docker save [-o 文件名] 镜像 [更多镜像...]
docker save -o mynginx.tar mynginx:v1.0
从文件加载一个镜像 语法:docker load [-i 文件名]
docoer load -i mynginx.tar
目录挂载与卷映射
目录挂载
上面的例子展示了如何手动进入容器修改内置文件,但显然这样是极为不方便的。Docker 提供了目录挂载的方式,可以将宿主机的一个文件夹映射到 Docker 容器中的一个文件夹,编辑主机的文件就相当于编辑容器的文件。删除容器时,在宿主机中创建的文件夹也不会被删除,保护了数据。
语法:-v 宿主机路径:容器路径
,如 -v /app/nghtml:/usr/share/nginx/html
,在 docker run
时使用。
docker run -d -p 80:80 --name nginx -v ~/nghtml:/usr/share/nginx/html nginx
到这里时,可以看到文件系统内部出现了一个 nghtml 文件夹,只是内部什么文件都没有,所以访问浏览器时也会出现 403 状态。我们创建一个 index.html 并向内部写入内容,nginx 就返回正常页面了。同时在宿主机中修改文件,还是进入容器内部修改文件,两者同步,是完全等价的。
卷映射
容器中的 nginx 配置文件路径为 /etc/nginx/nginx.conf
。由于目录挂载在宿主机创建的文件夹默认为空,如果我们将配置文件所在的文件夹映射到宿主机,会导致配置文件缺失,使 nginx 无法启动。此时我们就需要将容器中的目录映射到主机,成为卷映射。
语法:-v 卷名:容器路径
。卷名和上面的宿主机路径不同的是,卷名内部不包含路径分隔符号。
docker run -d -p 80:80 --name nginx -v ngconf:/etc/nginx nginx
卷的位置为 /var/lib/docker/volumes/卷名
,如上面的卷所在的路径就是 /var/lib/docker/volumes/ngconf
。
自定义网络
如何自定义网络
由于容器之间的隔离性,不同容器之间无法访问,而宿主机和容器之间可以访问。
这里解释一下,如我在容器1中存储了一个可以下载的资源,并将其暴露在公网中,正常状态下,能访问互联网的所有客户端都可以下载此资源,即容器2也能获得此资源。不过按照这种方式,容器2是先到互联网中寻找资源,并在容器1中找到该资源,通俗地来说,这个网络的流向是先出去再进去,这样的方式就很奇怪。
Docker 提供了一个机制,就是默认的网络,它在 Docker 刚安装时就有了。
执行 ip a
命令,可以看到所有的网卡。
图中的 docker0 就是这个网卡,它的 ip 是 127.17.0.1。
运行 docker inspect nginx
可以查看容器 nginx 的细节。
Networks 就是 nginx 容器的一个配置,可以从图中看到,它配有网关、自己的 ip 地址等。
我们创建两个容器,每个容器各自使用一个 nginx 进程,同时将它们映射到宿主机的不同端口中。
docker run -d -p 88:80 --name nginx01 nginx
docker run -d -p 99:80 --name nginx02 nginx
docker ps
然后进入 nginx01 容器中,使用 curl 访问 nginx02 容器的 80 端口。
为什么是 80 端口不是 99 端口呢,因为我们要直接访问 nginx02 ,因此要使用的应是它的 ip 和端口。80 端口是容器的端口,而 99 是主机的端口。
接下来我们查看容器 nginx01 的ip,然后进入容器 nginx02 访问它。
docker inspect nginx01
然后,进入容器 nginx02,访问 nginx01。
$ docker exec -it nginx02 bash
root@nginx02$ curl http://172.17.0.2:80
Docker 为每个容器分配唯一 ip,使用 容器ip+容器端口
可以互相访问。但如果容器被删除、更改,ip 很容易改变。Docker0 默认不支持主机域名,而我们可以自己创建一个主机域名,相当于局域网内的 DNS。
使用 docker network
相关命令来操作网络资源。
首先我们来创建一个自定义网络,代码是 docker network create mynet
。执行后,可使用 docker network ls
查看所有已创建的网络。
接下来,我们重新创建这两个容器。不同的是,这两个容器都是用了自定义网络 mynet
。
docker run -d -p 88:80 --name nginx01 --network mynet nginx
docker run -d -p 99:80 --name nginx02 --network mynet nginx
docker ps
再查看一下两个容器的细节。
docker container inspect nginx01
可以看到,容器 nginx01 加入到了 mynet 网络中。这时候进入 nginx02,就可以通过容器名称直接访问 nginx01,而不需要再输入 ip。
$ docker exec -it mynginx02 bash
---
$ curl http://mynginx01:88 # 直接使用容器名
实际应用 - Redis 主从同步集群
**目的:**设计一个主 Redis 和一个从 Redis,将所有外部与集群之间的更新,都通过主 Redis 实现,而从 Redis 会自动同步至主 Redis,实现读写分离。
为实现这个目的,我们使用两个 Redis 容器,第一个使用 6379 端口,并映射到主机的 6379 端口,然后将 bitnami/redis/data
目录映射到 /app/rd1
上,以便于操作数据。第二个使用 6379 端口,并映射到主机的 6380 端口,然后将 bitnami/redis/data
目录映射到 /app/rd2
上。
除此之外,我们需要设置两个变量,主 Redis 的如下:
REDIS_REPLICATION_MODE=master
REDIS_PASSWORD=123456
第一个是设置主从之间的复制模式,以主机为准,第二个变量给主 Redis 设置个密码。
从机设置:
REDIS_REPLICATION_MODE=slave
REDIS_MASTER_HOST=redis01
REDIS_MASTER_PORT_NUMBER=6379
REDIS_MASTER_PASSWORD=123456
REDIS_PASSWORD=123456
这里使用到的镜像也不是官方镜像,因为使用官方的镜像实现主从同步集群还需要修改配置文件,比较麻烦,这里我们使用一个民间大神已经封装好的镜像。我们在 Docker Hub 中搜 bitnami redis
,进入镜像说明,可以看到我们不需要修改配置文件,而是输入环境变量即可实现配置修改的操作。
现在我们启动这两个容器。
$ docker run -d -p 6379:6379 -v ~/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=123456 --network mynet --name redis01 bitnami/redis
$ docker run -d -p 6380:6379 -v ~/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/redis
在容器创建时,容器没有启动成功,查看日志发现如下报错:Can't open or create append-only dir appendonlydir: Permission denied
。我们手动创建这两个映射目录,并修改它们的权限。
$ mkdir ~/rd1 ~/rd2
mkdir: 无法创建目录 "/home/qi1/rd1": 文件已存在
mkdir: 无法创建目录 "/home/qi1/rd2": 文件已存在
$ sudo chmod -R 777 ~/rd1 ~/rd2
$ docker restart redis01 redis02
$ docker ps
然后使用 Redis 客户端尝试链接主 Redis 和 从 Redis。
我们接下来测试主从同步功能,我们为主机更新一条数据。
GET key
SET key value
GET key
执行成功后,我们应该可以看到主机和从机数据已被更新。
Docker Compose
介绍
Docker Compose 是 Docker 提供的一个工具,用于定义和运行多容器 Docker 应用。通过 Docker Compose,可以使用一个 YAML 文件(docker-compose.yml
)来定义多个容器的配置,并通过单一命令启动所有容器。Docker Compose 使得管理和编排多个 Docker 容器变得更简单,特别适合开发环境和微服务架构的应用。
在一个有 docker compose 文件的目录,可以执行以下命令。
指令 | 代码 |
---|---|
上线 | docker compose up -d |
下线 | docker compose down |
启动部分容器 | docker compose start x1 x2 ... |
停止部分容器 | docker compose stop x1 x2 ... |
扩容 | docker compose scale x2=x3 |
我们以启动一个 WordPress 系统为例,如果使用命令的方式启动,需要输入下面的代码。
#创建网络
docker network create blog
#启动mysql
docker run -d -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-v mysql-data:/var/lib/mysql \
-v /app/myconf:/etc/mysql/conf.d \
--restart always --name mysql \
--network blog \
mysql:8.0
#启动wordpress
docker run -d -p 8080:80 \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=123456 \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress:/var/www/html \
--restart always --name wordpress-app \
--network blog \
wordpress:latest
接下来,我们手写一个 docker compose 文件,实现和上面一样的功能,并且可以便捷地管理和本项目相关的容器。
语法
前面已经介绍过了,docker compose 文件是 YAML 格式的,它的最顶层可以是以下元素:
符号 | 意义 |
---|---|
services | 服务 |
networks | 网络 |
volumes | 卷 |
configs | 配置 |
secrets | 密钥 |
其中,前三项用的最多,后两项基本不用。
示例:
version: '3.8' # 设置 Docker Compose 的版本为 3.8
services:
wordpress:
image: wordpress:latest # 使用官方的最新版本的 WordPress 镜像
container_name: wordpress # 设置容器名称为 wordpress
restart: always # 设置容器始终重启,除非手动停止
ports:
- "8080:80" # 将本地的 8080 端口映射到容器的 80 端口,访问 WordPress 网站
environment: # 设置容器的环境变量
WORDPRESS_DB_HOST: db:3306 # 设置 WordPress 数据库主机为 db 服务,端口为 3306
WORDPRESS_DB_NAME: wordpress # 设置数据库名称为 wordpress
WORDPRESS_DB_USER: root # 设置 WordPress 数据库的用户名为 root
WORDPRESS_DB_PASSWORD: example # 设置 WordPress 数据库的密码为 example
volumes:
- wordpress_data:/var/www/html # 将名为 wordpress_data 的卷挂载到容器的 /var/www/html 目录,用于保存 WordPress 数据
networks:
- wordpress_network # 将容器连接到名为 wordpress_network 的网络
depends_on:
db: # 设置依赖关系,确保 db 服务处于健康状态才启动 wordpress 服务
condition: service_healthy # 仅在 db 服务健康时启动 wordpress
db:
image: mysql:8.0 # 使用 MySQL 8.0 官方镜像
container_name: mysql # 设置容器名称为 mysql
restart: always # 设置容器始终重启,除非手动停止
environment: # 设置 MySQL 容器的环境变量
MYSQL_ROOT_PASSWORD: example # 设置 MySQL root 用户的密码为 example
MYSQL_DATABASE: wordpress # 设置创建的数据库名称为 wordpress
MYSQL_INITDB_SKIP_TZINFO: 1 # 跳过时区信息的初始化
command:
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # 设置 MySQL 字符集为 utf8mb4,适应更广泛的字符编码
volumes:
- db_data:/var/lib/mysql # 将名为 db_data 的卷挂载到容器的 /var/lib/mysql 目录,用于持久化数据库数据
networks:
- wordpress_network # 将容器连接到名为 wordpress_network 的网络
healthcheck: # 配置健康检查,确保 MySQL 服务正常运行
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] # 使用 mysqladmin 命令检查数据库是否可用
interval: 10s # 每 10 秒检查一次
retries: 5 # 如果连续 5 次失败,则认为健康检查失败
start_period: 30s # 在容器启动后等待 30 秒开始健康检查
timeout: 10s # 每次健康检查的超时时间为 10 秒
volumes:
wordpress_data: # 定义一个名为 wordpress_data 的卷
db_data: # 定义一个名为 db_data 的卷
networks:
wordpress_network: # 定义一个名为 wordpress_network 的网络
driver: bridge # 使用 bridge 驱动程序,默认的网络模式
docker-compose -f compose.yaml up -d
当 compose.yaml 文件内容发生改变时,再次运行 docker-compose -f compose.yaml up -d
即可,Docker 会自动检测配置文件什么被改变了。
如果要关闭和这个项目有关的容器,可以使用 docker-compose down -f compose.yaml down
,但为了安全起见,Docker 不会移除已创建的卷、网络等资源。
Dockerfile
Dockerfile 是一种文本文件,包含了一组指令,用于自动化构建 Docker 镜像的过程。它定义了从基础镜像开始,如何安装应用程序、配置环境、复制文件、暴露端口以及设置容器的启动命令等。常见的指令有 FROM(指定基础镜像)、RUN(执行命令)、COPY(复制文件到容器)、EXPOSE(暴露端口)等。通过 Dockerfile,用户可以通过一个简单的命令 docker build 创建出一个定制化的 Docker 镜像,实现环境的一致性、自动化部署以及便于分发。
下表,列举了常用的 Dockerfile 指令。
指令 | 作用 |
---|---|
FORM | 指定镜像基础环境 |
RUN | 运行自定义命令 |
CMD | 容器启动命令或参数 |
LABEL | 自定义标签 |
EXPOSE | 指定暴露端口 |
ENV | 环境变量 |
ADD | 添加文件到镜像 |
COPY | 复制文件到镜像 |
ENTRYPOINT | 容器固定启动命令 |
VOLUME | 数据卷 |
USER | 指定用户和用户组 |
WORKDIR | 指定默认工作目录 |
ARG | 指定工作目录 |
这里使用 Python 的 Flask 框架,使用一个简单的代码做一个可以访问的页面。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
if __name__ == '__main__':
# 将 host 设置为 0.0.0.0,让应用可以被外部访问
app.run(host='0.0.0.0', port=9000)
# 指定镜像
FROM python:3.13.1
# 如果下载缓慢或失败 可以使用国内镜像
# FROM hub.littlediary.cn/library/python:3.13.1
# 指定标签,内容自定义
LABEL author=qi1
# 安装依赖
RUN ["pip", "install", "flask"]
# 将宿主机的文件复制到容器中
COPY main.py /main.py
# 暴露端口
EXPOSE 9000
# 程序入口,可以理解为启动应用的命令
ENTRYPOINT python -m main
# 也可以写成 ENTRYPOINT ["python", "-m", "main"]
将上述命令复制到和 main.py 同级目录的 Dockerfile 中,然后运行 docker build -f Dockerfile -t myapp:v1.0 .
。
其中,-t
为 --tag
,指定镜像名称,.
为构建上下文,即当前目录。
查看容器列表:
docker images
docker run -d -p 9000:9000 --name myapp myapp:v1.0
其他命令
批量操作
批量删除所有容器 docker rm $(docker ps -aq)
重新构建容器
有时 Docker Compose 会遇到缓存问题,特别是在镜像更新或修改配置时。你可以尝试清除缓存并重新构建容器。
首先,停止并删除当前容器和网络:
docker-compose down
然后重新构建并启动:
docker-compose up --build
这样可以强制 Docker Compose 重新创建所有容器,而不是使用旧的容器配置。
清除卷数据
如果容器卷的数据或配置发生了损坏,可能会导致配置读取错误。你可以尝试删除卷数据并重新启动。
docker-compose down -v
docker-compose up --build
移除所有容器、容器、卷
docker rm -f $(docker ps -aq)
docker volume rm $(docker volume ls -q)
docker network rm $(docker network ls -q)
分享社区
指令 | 代码 |
---|---|
登录 | docker login |
命名 | docker tag |
推送 | docker push |