Docker基础使用

1. Docker核心概念速览

  • 镜像:一个只读的模板,包含了运行应用所需的所有内容(操作系统、库、代码、环境变量等)。可以把它看作是面向对象编程中的"类"。
  • 容器:镜像的一个运行实例。它是可读写的,包含了应用运行时的进程。可以看作是"对象"。
  • Dockerfile:一个文本文件,包含了构建Docker镜像所需的所有指令。这是容器化的"蓝图"。

2. 安装Docker

卸载旧版本

bash 复制代码
sudo apt-get remove docker docker-engine docker.io containerd runc
Docker安装方式【二选一】
1. 使用Docker存储库安装

更新 apt 包索引并安装相关软件包以允许 apt 通过 HTTPS 使用 docker 存储库:

复制代码
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

添加 Docker 的官方 GPG 密钥:

bash 复制代码
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

设置存储库:

bash 复制代码
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list > /dev/null
2. 使用阿里安装

因为官方下架了dockerhub的镜像,更换一个阿里的镜像源。

更新 apt 包索引并安装相关软件包以允许 apt 通过 HTTPS 下载安装:

bash 复制代码
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

添加阿里云的Docker GPG密钥

bash 复制代码
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

添加阿里云的Docker源

bash 复制代码
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装 Docker engine
bash 复制代码
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
验证安装完成
bash 复制代码
sudo docker -v
# 打印出版本号
Docker version 29.0.4, build 3247a5a

3. 配置 Docker 国内镜像源

用于解决国内访问 Docker Hub 网络问题。

  1. 创建或编辑 Docker 配置文件
    Docker 守护进程的配置文件通常位于 /etc/docker/daemon.json。如果这个文件不存在,就创建它。
bash 复制代码
sudo vim /etc/docker/daemon.json
  1. 添加镜像源配置
    将以下内容复制到 daemon.json 文件中。
json 复制代码
{
"registry-mirrors": [
     "https://docker.1ms.run",
     "https://docker.xuanyuan.me"  
]
}
  1. 重启 Docker 服务
    配置文件修改后,需要重启 Docker 来让配置生效。
bash 复制代码
sudo systemctl restart docker
  1. 验证配置
    可以通过 info 命令查看镜像源是否配置成功。
bash 复制代码
sudo docker info | grep -A 10 "Registry Mirrors"

如果看到刚刚配置的镜像源地址,就说明成功了。

4. 创建镜像

假设项目结构如下:

复制代码
/home/ubuntu/C_C++/demo/
├── demo.c
└── Dockerfile

demo.c 的内容:

c 复制代码
#include <stdio.h>
int main() {
    printf("Hello from a containerized C application!\n");
    return 0;
}
编写 Dockerfile

在 demo 目录下,创建一个名为 Dockerfile 的文件,内容如下:

dockerfile 复制代码
# Stage 1: Build Stage (构建阶段)
# 使用一个包含GCC编译器的官方镜像作为基础镜像
FROM gcc:9.4 AS builder
# 设置工作目录
WORKDIR /usr/src/app
# 复制当前目录下的所有文件到工作目录
COPY . .
# 编译C程序
# -o demo 指定输出文件名为 demo
RUN gcc -o demo demo.c
# Stage 2: Runtime Stage (运行阶段)
# 使用一个最小化的镜像作为最终运行环境
FROM debian:buster-slim
# 设置工作目录
WORKDIR /app
# 从构建阶段复制编译好的可执行文件到当前镜像
# --from=builder 指定从上一个名为 builder 的阶段复制
COPY --from=builder /usr/src/app/demo .
# 容器启动时执行的命令
CMD ["./demo"]

Dockerfile 指令解析

  • FROM <image>: 指定基础镜像。gcc:9.4 提供了编译环境,debian:buster-slim 是一个非常小的运行环境。

  • WORKDIR <dir>: 设置工作目录,后续的 COPY, RUN, CMD 都会在此目录下执行。

  • COPY <src> <dest>: 将文件从宿主机复制到镜像中。

  • RUN <command>: 在镜像构建过程中执行命令(比如编译)。

  • CMD ["executable", "param1", "param2"]: 指定容器启动时默认执行的命令。

多阶段构建

在 Dockerfile 中,每一个 FROM 指令不仅仅是引入一个基础镜像,它实际上是开启了一个全新的构建阶段。当 Dockerfile 执行完毕,Docker 只会把最后一个 FROM 阶段生成的内容打上标签,作为最终镜像。

第一阶段用大体积的编译镜像生成可执行文件,第二阶段只把最终的可执行文件复制到一个干净、小巧的运行镜像中。

构建镜像

在 demo 目录下,打开终端执行以下命令:

bash 复制代码
# -t demo-app 给我们的镜像打一个标签,便于识别
# . 表示构建上下文是当前目录
sudo docker build -t demo-app .
查看镜像

运行以下命令就能看到创建的镜像。

bash 复制代码
sudo docker images
运行容器
bash 复制代码
# --rm 容器退出后自动删除
sudo docker run --rm demo-app

输出:

bash 复制代码
Hello from a containerized C application!
查看所有容器(包括停止的)
bash 复制代码
sudo docker ps -a
删除所有停止的容器
bash 复制代码
sudo docker container prune
删除指定的镜像
bash 复制代码
sudo docker rmi <image_id_or_name>
删除所有未使用的镜像
bash 复制代码
sudo docker system prune -a

5. 分离开发环境和运行环境

  1. 开发环境 :一个包含所有开发工具(如 gcc, gdb, make 等)的容器,用于编码、编译、调试。
  2. 运行环境:一个精简的、只包含运行依赖的容器,用于部署和运行最终产品。

前文的 Dockerfile 有一个痛点:每次修改 demo.c 里的代码,都必须重新 docker build 一次。因为c-demo 里面根本没有开发工具,相当于精简版操作系统 + 程序,只能运行程序。

在开发阶段,不需要每次都 Build,可以创建一个 GCC 环境作为开发环境,并把宿主机的文件夹映射到容器里。实现在本地改代码,Docker 里编译程序,而且这个程序直接出现当前目录下。

创建开发容器
第一种情况:一键编译并运行

第一次运行会去 Docker Hub执行 docker pull gcc:9.4下载镜像。

bash 复制代码
# 第一部分:Docker 的配置
# 使用官方的 gcc 镜像启动一个开发容器
# -v $(pwd):/src  将宿主机的代码目录挂载到容器的 /src 目录
# -w /src   设置容器内的工作目录,启动后,直接进入
# gcc:9.4   指定gcc版本镜像
# 第二部分:容器内的指令
# gcc -o demo demo.c
# 第三部分:宿主机的指令
# && 如果前面的 Docker 命令成功执行(编译没报错),那么就执行后面的命令
sudo docker run -it --rm -v $(pwd):/src -w /src gcc:9.4 gcc -o demo demo.c && ./demo
第二种情况:在开发容器内工作

启动开发容器

bash 复制代码
# -it: i = interactive (保持STDIN开放), t = allocate a pseudo-TTY (分配一个伪终端)
# /bin/bash: 覆盖Dockerfile中的CMD,启动一个bash shell
sudo docker run -it --rm -v $(pwd):/src -w /src gcc:9.4 /bin/bash

在开发容器内工作

bash 复制代码
# 你会看到提示符,比如:
root@2f3a4b5c6d7e:/src# 

# 验证 gcc 是否存在
gcc --version

# 编译代码
gcc -o demo demo.c

# 运行它
./demo

6. 去掉sudo

在使用非root用户输docker命令需要sudo,在 Linux 中,可以把当前用户加入 docker 用户组,这样就不需要 sudo 了。

操作步骤(仅需做一次):

  1. 创建 docker 组(如果已存在则跳过):
bash 复制代码
sudo groupadd docker
  1. 把当前用户加入组:
bash 复制代码
sudo usermod -aG docker $USER
  1. 注销并重新登录,或者执行以下命令让组权限立即生效:
bash 复制代码
newgrp docker
相关推荐
2035去旅行7 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
陈希1237 小时前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
女神下凡8 小时前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
且从容.12 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道12 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
闲云自留地14 小时前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
且从容.15 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落16 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨16 小时前
WSL2的安装与使用
linux·wsl
微小的鱼17 小时前
Linux的渲染与显示系统链路
android·java·linux