Docker on Ubuntu:安装、配置和入门

Docker on Ubuntu:安装、配置和入门

Docker 已经成为现代软件开发和部署中不可或缺的工具。它提供了一种轻量级、可移植且一致的方式来打包、分发和运行应用程序。本文将详细介绍如何在 Ubuntu 系统上安装、配置 Docker,并提供一些入门级的示例,帮助您快速上手 Docker。

1. Docker 简介

在深入安装和配置之前,让我们先简要了解一下 Docker 的核心概念。

1.1 什么是 Docker?

Docker 是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 App),更重要的是容器性能开销极低。

1.2 Docker 的核心组件

  • Docker 客户端 (Docker Client): 用户与 Docker 交互的主要方式。您可以通过 Docker 客户端发送命令到 Docker 守护进程。
  • Docker 守护进程 (Docker Daemon): 运行在宿主机上的后台服务,负责构建、运行和管理 Docker 容器。
  • Docker 镜像 (Docker Image): 一个只读模板,用于创建 Docker 容器。镜像包含了运行应用程序所需的所有内容:代码、运行时、系统工具、系统库和设置。
  • Docker 容器 (Docker Container): 镜像的可运行实例。容器是隔离的、轻量级的,并且包含运行应用程序所需的一切。
  • Docker 仓库 (Docker Registry): 用于存储和分发 Docker 镜像的集中位置。Docker Hub 是一个公共的 Docker 仓库,您也可以创建自己的私有仓库。
  • Dockerfile: 一个文本文件,其中包含一系列用于自动构建 Docker 镜像的指令。

1.3 Docker 的优势

  • 轻量级: 容器共享宿主机的内核,不需要额外的操作系统,因此比虚拟机更轻量级、更快速。
  • 可移植性: 一次构建,随处运行。Docker 容器可以在任何支持 Docker 的平台上运行,无需修改。
  • 一致性: 容器提供了一致的运行环境,消除了“在我机器上可以运行”的问题。
  • 隔离性: 容器之间相互隔离,互不影响,提高了安全性。
  • 可扩展性: 可以轻松地创建、复制和销毁容器,实现快速扩展。
  • 版本控制: 可以对镜像进行版本控制,方便回滚和管理。

2. 在 Ubuntu 上安装 Docker

在 Ubuntu 上安装 Docker 有多种方法,我们将介绍两种最常用的方法:使用 APT 仓库安装和使用便捷脚本安装。

2.1 使用 APT 仓库安装 (推荐)

这是官方推荐的安装方法,可以确保您安装的是最新版本的 Docker。

2.1.1 设置仓库

  1. 更新 apt 包索引:

    bash
    sudo apt-get update

  2. 安装必要的软件包,允许 apt 通过 HTTPS 使用仓库:

    bash
    sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

  3. 添加 Docker 的官方 GPG 密钥:

    bash
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

  4. 设置稳定版仓库:

    bash
    echo \
    "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    如果您想使用测试版或 nightly 版,可以将 stable 替换为 testnightly

2.1.2 安装 Docker Engine

  1. 再次更新 apt 包索引:

    bash
    sudo apt-get update

  2. 安装最新版本的 Docker Engine、containerd 和 Docker Compose:

    bash
    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

    如果您想安装特定版本的 Docker Engine,请先列出可用版本:
    bash
    apt-cache madison docker-ce

    然后使用第二列中的版本字符串安装,例如:
    sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io docker-compose-plugin

  3. 验证 Docker Engine 是否安装成功:

    bash
    sudo docker run hello-world

    此命令会下载一个测试镜像并在容器中运行。如果一切正常,您将看到一条消息,表明 Docker 已正确安装并正在运行。

2.2 使用便捷脚本安装 (适用于测试和开发环境)

Docker 提供了一个便捷脚本,可以快速安装 Docker。这种方法不建议在生产环境中使用,因为它可能不会安装最新版本的 Docker,并且可能存在安全风险。

  1. 下载并运行脚本:

    bash
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh

  2. 验证安装:
    bash
    sudo docker run hello-world

3. Docker 基本配置

3.1 非 root 用户使用 Docker

默认情况下,Docker 命令需要 root 权限才能运行。为了避免每次都输入 sudo,您可以将您的用户添加到 docker 用户组。

  1. 创建 docker 用户组 (如果不存在):

    bash
    sudo groupadd docker

  2. 将您的用户添加到 docker 用户组:

    bash
    sudo usermod -aG docker $USER

  3. 注销并重新登录 或使用以下命令使更改生效:
    bash
    newgrp docker

  4. 验证您是否可以在没有 sudo 的情况下运行 Docker 命令:

    bash
    docker run hello-world

3.2 配置 Docker 开机自启

为了确保 Docker 在系统启动时自动运行,您需要启用 Docker 服务。

bash
sudo systemctl enable docker

您还可以使用以下命令检查 Docker 服务的状态:

bash
sudo systemctl status docker

3.3 配置 Docker 镜像加速器 (可选)

由于国内访问 Docker Hub 速度较慢,您可以配置 Docker 镜像加速器来加快镜像下载速度。常用的镜像加速器有:

  • Docker 官方中国区加速器
  • 阿里云加速器
  • 网易云加速器
  • DaoCloud 加速器

这里以阿里云加速器为例进行配置。您需要先注册一个阿里云账号,然后在容器服务中找到镜像加速器,获取您的专属加速器地址。

  1. 创建或修改 /etc/docker/daemon.json 文件:

    bash
    sudo nano /etc/docker/daemon.json

  2. 添加以下内容 (将 your-mirror-address 替换为您的加速器地址):

    json
    {
    "registry-mirrors": ["your-mirror-address"]
    }

    如果您有多个加速器地址,可以使用逗号分隔。

  3. 重启 Docker 服务:

    bash
    sudo systemctl restart docker

4. Docker 入门

现在,您已经成功安装并配置了 Docker,让我们来学习一些基本的 Docker 命令和操作。

4.1 常用 Docker 命令

  • docker version: 查看 Docker 版本信息。
  • docker info: 查看 Docker 系统信息,包括镜像和容器数量等。
  • docker search: 搜索 Docker Hub 上的镜像。
  • docker pull: 从 Docker Hub 或私有仓库拉取镜像。
  • docker images: 列出本地镜像。
  • docker run: 创建并运行一个容器。
  • docker ps: 列出正在运行的容器。
  • docker ps -a: 列出所有容器 (包括已停止的)。
  • docker start: 启动一个已停止的容器。
  • docker stop: 停止一个正在运行的容器。
  • docker restart: 重启一个容器。
  • docker rm: 删除一个容器。
  • docker rmi: 删除一个镜像。
  • docker exec: 在正在运行的容器中执行命令。
  • docker logs: 查看容器的日志。
  • docker build: 使用 Dockerfile 构建镜像。
  • docker-compose up: 使用 Docker Compose 启动多个容器应用。
  • docker-compose down: 停止并移除 Docker Compose 启动的容器。

4.2 运行第一个容器

让我们以运行一个 Nginx Web 服务器为例,来体验 Docker 的强大功能。

  1. 拉取 Nginx 镜像:

    bash
    docker pull nginx:latest

    nginx是镜像名称,latest 是标签(tag),表示最新版本。如果不指定标签,默认拉取 latest 标签。

  2. 运行 Nginx 容器:

    bash
    docker run -d -p 8080:80 nginx

    • -d: 后台运行容器。
    • -p 8080:80: 将容器的 80 端口映射到宿主机的 8080 端口。这样您就可以通过访问宿主机的 8080 端口来访问 Nginx 服务器了。
    • nginx: 使用的镜像名称。
  3. 在浏览器中访问 http://localhost:8080,您将看到 Nginx 的欢迎页面。

  4. 查看正在运行的容器:

    bash
    docker ps

    您将看到类似以下的输出:

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    xxxxxxxxxxxx nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp romantic_leavitt

  5. 停止容器:

    bash
    docker stop <CONTAINER ID>

    <CONTAINER ID> 替换为您在上一步中看到的容器 ID。

4.3 使用 Dockerfile 构建自定义镜像

Dockerfile 是一个文本文件,其中包含一系列用于自动构建 Docker 镜像的指令。通过 Dockerfile,您可以定义应用程序的运行环境、依赖关系和启动命令等。

  1. 创建一个名为 Dockerfile 的文件 (没有后缀名):

    nano Dockerfile

  2. Dockerfile 中添加以下内容:

    ```dockerfile

    使用 Node.js 16 作为基础镜像

    FROM node:16

    设置工作目录

    WORKDIR /app

    将 package.json 和 package-lock.json 复制到工作目录

    COPY package*.json ./

    安装依赖

    RUN npm install

    将应用程序代码复制到工作目录

    COPY . .

    暴露端口

    EXPOSE 3000

    启动应用程序

    CMD [ "npm", "start" ]
    ```

    这是一个简单的 Node.js 应用程序的 Dockerfile 示例。它执行以下操作:

    • FROM: 指定基础镜像。
    • WORKDIR: 设置容器内的工作目录。
    • COPY: 将文件从宿主机复制到容器。
    • RUN: 在容器内执行命令。
    • EXPOSE: 声明容器监听的端口。
    • CMD: 指定容器启动时执行的命令。
  3. 创建一个简单的 Node.js 应用程序 (例如 app.js):
    ```javascript
    const http = require('http');

    const hostname = '0.0.0.0';
    const port = 3000;
    
    const server = http.createServer((req, res) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/plain');
      res.end('Hello, Docker!\n');
    });
    
    server.listen(port, hostname, () => {
      console.log(`Server running at http://${hostname}:${port}/`);
    });
    

    4. **创建一个 `package.json`的文件**json
    {
    "name": "docker-node-app",
    "version": "1.0.0",
    "description": "A simple Node.js app for Docker demo",
    "main": "app.js",
    "scripts": {
    "start": "node app.js"
    },
    "dependencies": {}
    }
    ```

  4. 构建镜像:

    bash
    docker build -t my-node-app .

    • -t my-node-app: 为镜像指定一个名称和标签 (my-node-app:latest)。
    • .: 指定 Dockerfile 所在的目录 (当前目录)。
  5. 运行容器:

    bash
    docker run -d -p 3000:3000 my-node-app

  6. 在浏览器中访问 http://localhost:3000,您将看到 "Hello, Docker!"。

4.4 使用 Docker Compose 管理多容器应用

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件,您可以配置应用程序的服务、网络和卷等。

  1. 创建一个名为 docker-compose.yml 的文件:

    yaml
    version: "3.9"
    services:
    web:
    build: .
    ports:
    - "3000:3000"
    depends_on:
    - db
    db:
    image: "postgres:13"
    environment:
    POSTGRES_PASSWORD: mysecretpassword
    volumes:
    - db_data:/var/lib/postgresql/data
    volumes:
    db_data:

    这是一个简单的Web应用和PostgreSQL数据库的Compose示例,它将执行以下操作:
    * version: 指定 Compose 文件版本。
    * services: 定义应用程序的服务。
    * web: Web 服务。
    * build: 指定 Dockerfile 所在的目录。
    * ports: 端口映射。
    * depends_on: 说明web服务依赖于db服务,db服务会先启动。
    * db: 数据库服务。
    * image: 使用的镜像。
    * environment: 设置环境变量。
    * volumes: 数据卷挂载。
    * volumes:定义数据卷。

  2. 启动应用程序:

    bash
    docker-compose up -d

    • -d: 后台运行。
  3. 停止应用程序:

    bash
    docker-compose down

5. 总结

本文详细介绍了在 Ubuntu 上安装、配置和入门 Docker 的过程。您学习了 Docker 的核心概念、安装方法、基本配置以及常用命令。通过运行 Nginx 容器、构建自定义镜像和使用 Docker Compose 管理多容器应用的示例,您已经对 Docker 有了初步的了解。

Docker 是一个强大而灵活的工具,可以极大地简化应用程序的开发、部署和管理。希望本文能帮助您快速上手 Docker,并在您的项目中使用它。

要深入学习 Docker,建议您参考 Docker 官方文档,并尝试更多的实践项目。祝您在 Docker 的世界中探索愉快!

THE END