docker-learn

从零开始安装docker engine

打开终端,依次运行以下命令:

1
2
## 删除原来安装的旧版本
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
1
2
3
4
5
6
7
8
9
10
11
12
13
## 设置docker的apt软件源
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
1
2
## 安装最新版的docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
1
2
## 拉取hello-world镜像
sudo docker run hello-world

如果镜像拉取失败,即是国内网络的问题,需要设置镜像源

  • cd /etc/docker/
  • 创建一个json文件:sudo touch daemon.json
  • 编辑文件:sudo vim daemon.json
  • 添加以下内容到文件,保存并退出:
1
2
3
4
5
6
7
8
9
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com"
]
}
  • 重新运行daemon和docker: sudo systemctl daemon-reload sudo systemctl restart docker

重新运行sudo docker run hello-world。从输出中可以看出docker的运行逻辑,主要分为以下几个部分:

  • The Docker client contacted the Docker daemon. docker 客户端即用户终端接受命令,比如docker run等,客户端将指令发送给daemon,即服务端
  • The Docker daemon pulled the “hello-world” image from the Docker Hub. docker的服务端即后端负责管理镜像和容器,本地没有hello-world,服务端即会从dockerhub上下载
  • The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading. docer服务端从拉取的镜像中创建了一个实例即容器,容器是一个隔离的环境,可以运行在本地。容器内部执行镜像定义的命令
  • The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal. 容器的输出由守护进程捕获,并通过客户端显示在你的终端上。

一个类比:

Docker 概念 现实类比
镜像(Image) 蛋糕模具
容器(Container) 用模具烤出的蛋糕
Docker Hub 模具商店(可下载模具)
守护进程 蛋糕师傅(执行操作)

Docker Engine、Docker Compose 和 Docker Desktop 的区别

Docker Desktop (GUI + 完整开发环境)
├── Docker Engine (核心运行时)
│ ├── Docker CLI
│ └── Docker Daemon
└── Docker Compose (多容器管理工具)

Docker Engine

核心功能:Docker 的核心运行时环境,包含:,Docker Daemon (dockerd):后台服务,管理容器生命周期,Docker CLI (docker):命令行接口与 Daemon 交互,containerd:容器运行时,实际运行容器,runc:低层容器运行时工具,特点:只提供基础容器功能,纯命令行操作,适合服务器/生产环境使用,需要手动管理网络、存储等

Docker Compose

核心功能:用于定义和运行多容器 Docker 应用的工具,使用 YAML 文件 (docker-compose.yml) 配置应用服务
特点:简化多容器应用管理,一键启动/停止整个应用栈,内置服务依赖管理,集成在 Docker Engine 中 (作为插件),主要用于开发/测试环境

安装docker compose

sudo apt-get install docker-compose-plugin

给docker 配置代理

有的时候国内镜像很慢,或者有的镜像没有,需要走代理访问dockerhub

注意:配置完之后运行以下命令之后,查看出现的代理的ip地址和端口是否正确:

  • sudo systemctl daemon-reload
  • sudo systemctl restart docker
  • docker info | grep -i proxy

配置daemon.json(优先使用这个)

如果docker运行的电脑和你的电脑处于同一个局域网下,而且你的电脑安装了clash可以访问外网,那么即可让docker通过你的代理访问外网,前提是必须打开你电脑上clash的局域网开关

1
2
3
4
5
6
{
"proxies": {
"http-proxy": "http://127.0.0.1:7890",
"https-proxy": "http://127.0.0.1:7890"
}
}

配置环境变量

  • /etc/systemd/system 目录下创建 docker.service.d 目录:sudo mkdir -p /etc/systemd/system/docker.service.d
  • vim /etc/systemd/system/docker.service.d/http-proxy.conf
  • [Service]
    Environment="HTTP_PROXY=http://172.22.11.200:7777"
    Environment="HTTPS_PROXY=http://172.22.11.200:7777"
    Environment="NO_PROXY=localhost,127.0.0.1"
    
    1
    2
    3
    - ```python
    sudo systemctl daemon-reload
    sudo systemctl restart docker

这样就可以使用docker pull从dockerhub拉取镜像了。

注意以上两种方法不能同时配置,不然容易混乱,每个版本的docker究竟优先使用哪个不确定。

使用docker compose运行容器

首先需要新建一个项目,命名为composetest。在composetest中新建一个app.py内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)

@app.route('/')
def hello():
count = get_hit_count()
return f'Hello World! I have been seen {count} times.\n'

上述代码简单来说就是用flask搭建web服务,使用redis构建后端服务。flask处理web请求,redis处理用户数据,构建了一个微服务框架。

新建一个compose.yaml:

1
2
3
4
5
6
7
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"

配置文件中定义了一个services,其中有两个服务,一个web服务,build:.表示用当前目录下的dockerfile来构建镜像,ports表示将宿主机的本地8000端口映射到容器内部的5000端口。则容器中运行的flask应用会监听5000端口,那么你在宿主机上可以访问:localhost:8000来访问这个服务。但是宿主机一般是远程服务器,如果你的电脑和远程服务器是在同一个局域网下,那么你可以直接在你的电脑中访问:服务器ip:8000来访问这个服务。同时你也可以在你的电脑中运行以下命令:
ssh -L 8888:localhost:8000 用户名@远程服务器IP来将本地的8888端口的访问都转发到远程服务器的8000端口,然后在本地访问:localhost:8888即可。

新建一个requirements.txt:

1
2
flask
redis

新建一个Dockerfile:

1
2
3
4
5
6
7
8
9
10
FROM python:3.10-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run", "--debug"]

之后即可运行docker compose up来运行容器,过程中如果有pull不下来的images,手动使用pull来拉取,好像compose不会自动访问设置好的代理。

docker compose和docker run的区别

docker run

是运行一个容器的基本命令,每次执行都需要在命令行指定所有参数,比如:

1
docker run -d -p 8080:8080 --name searxng searxng/searxng

运行镜像并监听容器的8080端口,将主机的8080端口映射到容器的8080端口,这样就可以通过访问主机的端口来访问容器内提供的服务

另外我们可以将容器的内的某个文件夹挂载到主机的文件夹下,比如:

1
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

这里将容器根目录下的.ollama文件夹挂载到了主机的ollama,这个ollama默认位于/var/lib/docker/下,这里ollama被成为卷(volume)存储在主机中,这样就算容器ollama被删除了,但是在容器的.ollama文件夹下下载的模型仍保存在/var/lib/docker/ollama中,这样当我们再次pull一个ollama镜像的时候,只需要重新将.ollama挂载到上述文件夹下即可。

使用了docker run之后,容器就被启动了,在后台运行。把容器看作一个操作系统,我们想访问容器的终端,直接进入容器内操作的话,就需要命令sudo docker exec -it ollama ollama run gemma3:12b,以下是解释:

1. sudo (可选,取决于环境):

  • sudo 命令允许你以超级用户 (root) 权限执行后续命令。
  • 在某些情况下,你可能需要 sudo 才能在 Docker 容器内执行命令,尤其是在容器用户没有足够的权限时。 如果你的 Docker 环境配置良好,你可能不需要 sudo

2. docker exec:

  • docker exec 是 Docker 提供的命令,用于在 已存在的 Docker 容器 中执行命令。 这与 docker run 不同,docker run 是用来创建并启动一个新的容器。
  • exec 允许你访问容器内部的环境,执行命令,就像你直接在容器内操作一样。

3. -it (选项):

  • -i (interactive): 保持 STDIN 打开,允许你向容器发送输入。 这对于交互式使用至关重要,因为你需要和运行的程序(模型)进行交互。
  • -t (tty): 分配一个伪终端。 这使得你可以在容器内看到控制台输出,并使用命令行界面。
  • 结合 -i-t 创建了一个交互式终端会话,允许你与容器内的程序进行交互。

4. ollama (容器名):

  • ollama 是你已经存在的 Docker 容器的名称。 这意味着你之前已经使用 docker run 命令创建并运行了一个名为 ollama 的 Docker 容器。 这个容器通常包含 Ollama 环境,用于管理和运行大型语言模型。 你可以使用 docker ps 命令查看正在运行的容器列表,确认容器名称是否正确。 如果你的 Ollama 容器不是叫 ollama
    你需要替换成正确的容器名称。

5. ollama run gemma3:12b (命令):

  • ollama run 是 Ollama 工具的命令,用于下载和运行大型语言模型。
  • gemma3:12b 是你要运行的模型名称。 gemma3 是模型的名称,12b 指的是模型的大小(120 亿参数)。 Ollama 会自动从 Ollama Hub 下载模型 (如果尚未下载)。

总结:

总而言之,这条命令的执行流程是:

  1. 查找名为 ollama 的已存在 Docker 容器。
  2. ollama 容器内部,执行 ollama run gemma3:12b 命令。 这会下载 Gemma 3.12B 模型(如果尚未下载),并启动模型。
  3. -it 选项使得你能够与运行的模型进行交互,例如输入提示词并接收模型的输出。

所以docker run的特点就是:

  • 一次只能启动一个容器
  • 所有配置通过命令行给出
  • 适合简单的单容器应用
  • 命令可能会很长而且复杂
  • 难以管理多个相关联的容器

docker compose

Docker Compose 是一个用于定义和运行多容器应用的工具,通过 YAML 文件来配置服务:

1
2
3
4
5
6
7
8
9
10
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
database:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: password

1.. docker compose 的特点:

  • 定义多容器应用: docker compose 专门用于定义和运行多容器的 Docker 应用。
  • 使用 YAML 文件: 它使用 docker-compose.yml (或者 docker-compose.yaml) 文件来描述应用的各个服务(每个服务通常对应一个容器),包括镜像、命令、端口映射、环境变量、依赖关系、网络配置等。
  • 简化多容器管理: 它简化了多容器应用的创建、启动、停止和管理。 你只需要一个命令 docker compose up 就能启动整个应用。
  • 依赖关系管理: docker-compose.yml 文件可以明确定义服务之间的依赖关系,Docker Compose 会按照正确的顺序启动服务。
  • 网络配置: 它可以自动创建和配置服务之间的网络,方便服务间的通信。
  • 可重复性: docker-compose.yml 文件可以作为应用的配置清单,方便在不同的环境中使用相同的配置。
  • 编排功能: docker compose 提供了一些编排功能,例如健康检查、自动重启等。
  • 可扩展性: 可以更容易地扩展应用,例如增加服务实例或修改网络配置。

docker 常用命令

1. 镜像 (Images)

  • docker pull <image_name>[:<tag>]: 从 Docker Hub 或其他注册中心下载镜像。
    • 例如:docker pull ubuntu:latest (拉取最新版本的 Ubuntu 镜像)
  • docker images: 列出本地仓库中的镜像。
  • docker rmi <image_id> [<image_id> ...]: 删除本地镜像。 需要指定镜像 ID 或名称 (如果唯一)。
    • docker rmi -f <image_id>: 强制删除镜像,即使它被其他镜像使用。
  • docker build -t <image_name>:<tag> <path_to_dockerfile>: 从 Dockerfile 构建镜像。
    • 例如: docker build -t my-app:1.0 . (在当前目录构建一个名为 my-app,标签为 1.0 的镜像)
  • docker tag <source_image>:<source_tag> <target_image>:<target_tag>: 给镜像添加别名 (用于更方便的推送和管理
    )。

2. 容器 (Containers)

  • docker run [OPTIONS] <image_name> [COMMAND] [ARG...]: 创建并运行容器。 这是 Docker 最常用的命令之一。
    • docker run -d <image_name>: 在后台运行容器 (detached mode)。
    • docker run -p <host_port>:<container_port> <image_name>: 将容器的端口映射到主机端口。
    • docker run -v <host_path>:<container_path> <image_name>: 将主机目录挂载到容器目录 (用于数据持久化)。
    • docker run --name <container_name> <image_name>: 给容器指定一个名称。
    • docker run -e <key>=<value> <image_name>: 设置环境变量
  • docker ps [OPTIONS]: 列出正在运行的容器。
    • docker ps -a: 列出所有容器 (包括已停止的)。
    • docker ps -q: 只显示容器 ID。
  • docker start <container_id_or_name>: 启动已停止的容器。
  • docker stop <container_id_or_name>: 停止正在运行的容器。
  • docker restart <container_id_or_name>: 重启容器。
  • docker kill <container_id_or_name>: 强制停止容器 (更激进的停止方式)。
  • docker rm <container_id_or_name> [container_id_or_name...]: 删除一个或多个容器。
    • docker rm -f <container_id_or_name>: 强制删除运行中的容器。
  • docker exec -it <container_id_or_name> <command>: 在正在运行的容器中执行命令。
    • 例如: docker exec -it my_container bash (在 my_container 容器中打开一个 bash shell)
  • docker top <container_id_or_name>: 查看容器内的进程信息。
  • docker logs <container_id_or_name>: 查看容器的日志。
    • docker logs -f <container_id_or_name>: 实时查看容器日志。
  • docker inspect <container_id_or_name>: 显示容器的详细信息 (JSON 格式)。

3. 网络 (Networks)

  • docker network ls: 列出 Docker 网络。
  • docker network create <network_name>: 创建一个 Docker 网络。
  • docker network connect <network_name> <container_id_or_name>: 将容器连接到 Docker 网络。
  • docker network disconnect <network_name> <container_id_or_name>: 将容器从 Docker 网络中分离。
  • docker network inspect <network_name>: 查看 Docker 网络的详细信息。

4. 卷 (Volumes)

  • docker volume ls: 列出 Docker 卷。
  • docker volume create <volume_name>: 创建 Docker 卷。
  • docker volume inspect <volume_name>: 查看 Docker 卷的详细信息。
  • docker volume rm <volume_name>: 删除 Docker 卷。

5. Docker Compose (用于多容器应用)

  • docker-compose up [OPTIONS]: 构建、创建和启动 Docker Compose 应用。
    • docker-compose up -d: 在后台运行应用。
  • docker-compose down [OPTIONS]: 停止并删除 Docker Compose 应用。
  • docker-compose ps: 列出 Docker Compose 应用的容器状态。
  • docker-compose logs: 查看 Docker Compose 应用的日志。
  • docker-compose build: 构建 Docker Compose 应用的镜像。
  • docker-compose exec <service_name> <command>: 在 Compose 服务中执行命令。

6. 其他常用命令

  • docker info: 显示 Docker 环境的信息。
  • docker version: 显示 Docker 的版本信息。
  • docker system df: 显示 Docker 的资源使用情况 (磁盘空间)。
  • docker system prune: 清理无用的 Docker 对象 (容器、镜像、卷、网络)。 这是一个非常有用的命令,可以释放磁盘空
    间。
    • docker system prune -a: 删除所有未被使用的镜像、容器、卷和网络。谨慎使用!

提示:

  • 可以使用 docker --help 查看所有可用命令的帮助信息。
  • 可以使用 docker <command> --help 查看特定命令的帮助信息。
  • docker 命令通常需要使用 sudo 在 Linux 系统上运行,但在 Docker Desktop 上可能不需要。

参考文献

一文讲透如何给Docker设置代理

Docker 设置代理的三种方法

docker官方文档