Docker 是一个开放平台,用于开发、移动、运行应用程序。它使应用程序可以封装在容器中,容器是轻量级的、可移植的、自给自足的环境,可以在任何支持 Docker 的机器上运行。
Docker 基础术语
在介绍 Docker 的使用之前,我们先了解几个基本概念:
- 镜像(Image):Docker 镜像是应用程序及其依赖的只读模板。镜像用于创建 Docker 容器的实例。
- 容器(Container):容器是镜像的运行实例。它是独立的,并包含其运行所需的一切(代码、运行时、系统工具等)。
- 仓库(Repository):仓库是集中存放镜像的位置,它可以是公共的或者私有的,最著名的是 Docker Hub。
- Dockerfile:一个文本文件,包含了一系列的命令,用于从给定的基础镜像构建新的镜像。
- Docker Compose:一个工具,允许你使用 YAML 文件定义多个容器的应用服务。
Docker 安装
安装 Docker 的第一步通常是从官方网站下载适合你操作系统的 Docker 安装包。Docker 针对 macOS、Windows 和各种 Linux 发行版提供了安装程序。
基本命令
一旦安装好 Docker,你可以通过命令行界面(CLI)开始使用以下的基本命令:
-
docker run:从指定的镜像中创建并启动一个新容器。
pythondocker run hello-world
-
docker ps:列出所有正在运行的容器。
pythondocker ps
-
docker ps -a:列出所有容器,包括未运行的。
pythondocker ps -a
-
docker stop:停止一个正在运行的容器。
pythondocker stop [容器ID或名称]
-
docker rm:删除一个容器。
pythondocker rm [容器ID或名称]
-
docker images:列出本地存储的所有镜像。
pythondocker images
-
docker rmi:删除一个镜像。
pythondocker rmi [镜像ID或名称]
-
docker pull:从仓库拉取指定的镜像。
pythondocker pull [镜像名称]
-
docker push:将本地的一个镜像推送到仓库。
pythondocker push [镜像名称]
-
docker build:基于 Dockerfile 构建一个新的镜像。
pythondocker build -t [镜像名称] [Dockerfile 的位置]
-
docker exec:在运行中的容器执行命令。
pythondocker exec [容器ID或名称] [命令]
-
docker logs:获取容器的日志输出。
pythondocker logs [容器ID或名称]
-
docker network:管理 Docker 的网络设置。
pythondocker network ls
-
docker volume:管理 Docker 的数据卷,用于持久化或共享容器数据。
pythondocker volume ls
使用 Dockerfile
Dockerfile
是一个文本文件,它包含了一系列的指令,用于自动化地构建 Docker 镜像。每个指令都会在镜像中创建一个新的层,指令通常包括添加文件、安装软件包、设置环境变量等。
Dockerfile 的基本结构和指令
FROM
:指定基础镜像。所有 Dockerfile 文件都必须从一个FROM
指令开始,除非它是一个特殊的scratch
基础镜像。RUN
:执行任意命令,它们会在镜像的当前层上运行,并将结果提交到新的层。CMD
:提供容器默认的执行命令。只能有一个CMD
指令,如果列出多个,只有最后一个会生效。LABEL
:为镜像添加元数据。EXPOSE
:声明容器运行时监听的端口。ENV
:设置环境变量。ADD
:将文件和目录添加到镜像中。可以从 URL 地址获取文件或解压本地的压缩文件。COPY
:用于从构建上下文复制文件和目录到镜像中。通常比ADD
更推荐。ENTRYPOINT
:配置容器启动时运行的命令,可以与CMD
配合使用来设置参数。VOLUME
:创建一个或多个挂载点路径,用于保存外部或其他容器的数据卷。USER
:指定运行容器时的用户名或 UID,后续的RUN
、CMD
和ENTRYPOINT
等指令都会使用该用户。WORKDIR
:为RUN
、CMD
、ENTRYPOINT
、COPY
和ADD
指令设置工作目录。ARG
:定义构建时的变量,可以在构建命令上使用--build-arg
参数来覆盖。
使用 Dockerfile 构建 Docker 镜像
构建 Docker 镜像的基本步骤涉及创建一个 Dockerfile
和使用 docker build
命令。
1. 创建一个 Dockerfile
以下是一个简单的 Dockerfile
示例,用于创建一个运行 Nginx Web 服务器的 Docker 镜像:
python
# Ubuntu 基础镜像
FROM ubuntu:latest
# 维护者信息
LABEL maintainer="name@example.com"
# 环境变量
ENV DEBIAN_FRONTEND noninteractive
# 安装 Nginx
RUN apt-get update && \
apt-get install -y nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 暴露端口 80
EXPOSE 80
# 设置工作目录
WORKDIR /var/www/html
# 复制网站内容
COPY ./src/ /var/www/html/
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
2. 使用 docker build 构建镜像
python
docker build -t my-nginx-image .
此命令会自动读取当前目录下的 Dockerfile
,构建一个新镜像,并将其标记为 my-nginx-image
。
-t
标志用于命名并可选地为新创建的镜像添加标签,格式为name:tag
。- 最后的
.
指定了 Dockerfile 的路径和构建上下文的位置,这里的.
表示当前目录。
完成构建过程后,你可以使用 docker images
查看已创建的镜像列表,并使用 docker run
启动一个基于新镜像的容器。
使用 Docker Compose
Docker Compose 允许你使用一个 YAML 文件定义多个容器的配置。这个文件常常被命名为 docker-compose.yml
。
一个基础的 docker-compose.yml
文件看起来可能像这样:
python
version: '3'
services:
web:
image: "nginx:alpine"
ports:
- "80:80"
db:
image: "postgres:latest"
environment:
POSTGRES_DB: exampledb
POSTGRES_USER: exampleuser
POSTGRES_PASSWORD: examplepass
在这个文件中,我们定义了两个服务:web
和 db
。web
服务使用了 nginx 的官方镜像,而 db
服务则使用了 PostgreSQL。
为了启动这些由 docker-compose.yml
文件定义的服务,运行:
python
docker-compose up
要停止这些服务,可以运行:
python
docker-compose down
示例
假设有一个python项目,涉及到mysql,redis,用nginx代理,使用docker-compose实现一键部署
dockerfile
# 基于Python官方镜像
FROM python:3.8
# 将工作目录设置为/app
WORKDIR /app
# 复制项目代码和依赖文件到容器内
COPY . /app
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 暴露端口
EXPOSE 5000
# 运行Python应用
CMD ["python", "your_app.py"]
nginx.conf
server {
listen 80;
location / {
proxy_pass http://your_python_service:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
docker-compose.yml
version: '3.8'
services:
your-python-service:
build: .
container_name: your-python-service
volumes:
- .:/app
ports:
- "5000:5000"
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- your-python-service
mysql:
image: mysql:5.7
container_name: mysql
environment:
MYSQL_DATABASE: 'mydb'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'rootpassword'
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:latest
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
volumes:
mysql-data:
redis-data:
总结
Docker 提供了一种标准化的方法来打包和运行应用程序,通过使用容器,它带来了便携性、微服务架构以及容易扩展和自动化部署的优势。上面介绍的命令和概念是 Docker 使用的基础,但 Docker 体系和工具集非常丰富,包括进阶的网络配置、数据卷、私有仓库和集群管理(如 Docker Swarm 和 Kubernetes)等内容,都是 Docker 更加强大的补充特性。