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
相关推荐
shizhan_cloud1 小时前
Shell 脚本的条件测试与比较
linux·运维
郝学胜-神的一滴1 小时前
Linux kill命令与kill函数:从信号原理到实战解析
linux·服务器·开发语言·c++·程序人生
A-刘晨阳1 小时前
【Linux】中如何修改jar包里的文件类及配置等内容
linux·运维·jar
我在人间贩卖青春1 小时前
shell脚本入门
linux·shell脚本
chenzhou__1 小时前
LinuxC语言并发程序笔记补充
linux·c语言·数据库·笔记·学习·进程
被遗忘的旋律.1 小时前
Linux驱动开发笔记(二十二)——多点电容触摸屏
linux·驱动开发·笔记
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
docker打tar包命令
运维·docker·容器
fy zs1 小时前
Linux线程互斥与同步
linux·c++
---学无止境---1 小时前
sys_ioperm 函数详解
linux