docker 基础教程

安装 Docker 可以通过官方脚本一键完成,执行以下两条命令即可:

bash 复制代码
curl -fsSL https://get.docker.com -o install-docker.sh
sudo sh install-docker.sh

下载好之后如果 pull 镜像失败,可以进入 /etc/docker/daemon.json 配置镜像源。

完成之后:sudo systemctl restart docker重启生效

(作者用的是 Ubuntu,其它不同版本系统可能会有差异,有需要可以 AI search 一下)

镜像相关命令

查看镜像:docker images

输出字段说明:

  • REPOSITORY:镜像的名称
  • TAG :镜像的标签(如 latest)
  • IMAGE ID:镜像的唯一 ID
  • CREATED:镜像创建时间
  • SIZE:镜像的大小

搜索镜像:docker search 镜像名

拉取镜像:docker pull <image_name>:<tag>

tag 就是类似于版本,如果不指定 tag 就会默认拉取带有 latest 的镜像,一般来说一个镜像会有多个版本。

删除镜像:docker rmi IMAGE ID/REPOSITORY

注:镜像 id 或名字均可,而且镜像不能有容器实例。

镜像和容器的关系:镜像是一个文件,文件实例化运行后产生容器。如果想删除容器需要使用 docker rm 容器名/id。

容器相关指令

指令 说明
docker ps 查看正在运行的容器
docker ps -a 查看所有容器(包括已停止的)
docker run 镜像名 基于镜像新建并运行容器
docker run -d 镜像名 后台运行容器(detached 模式)
docker run -it 镜像名 /bin/bash 交互式运行容器并进入 bash
docker start 容器ID或名字 启动一个已停止的容器
docker stop 容器ID或名字 停止一个正在运行的容器
docker restart 容器ID或名字 重启容器
docker exec -it 容器ID或名字 bash 在容器中启动一个新进程(进入容器)
docker attach 容器ID或名字 连接到正在运行的容器(会跟随主进程)
docker logs 容器ID或名字 查看容器的日志输出
docker rm 容器ID或名字 删除容器(必须先停止才能删)
docker rm -f 容器ID或名字 强制删除容器(无论是否在运行)
docker rename 旧名字 新名字 给容器重命名

docker run 常用参数

  • docker run -d:后台运行,不占用终端
  • docker run --name abc:给容器命名为 abc
  • docker run 镜像:如果没有 pull 这个镜像,会自动拉取然后创建容器运行一个
  • docker run -p 33061:33062:把宿主机的 33061 端口映射到容器的 33062,访问宿主机 33061 会端口转发到容器内指定端口
  • docker run -v 宿主机路径:虚拟机路径:挂载卷,用于配置数据、日志、数据持久化
  • docker run -e/--env Name=Value:设置环境变量
  • docker run -it:运行的时候进入容器的终端
  • docker run --rm:容器停止就删掉容器
  • docker run --restart always:只要容器停止就重启(还有 unless-stopped 代替 always,类似,但是手动停止不会重启)

创建容器

创建容器:docker create 参数 镜像

创建容器但是不会运行,需要手动运行。

启停与查看

启停容器:docker stop/start

查看容器详情:docker inspect 容器id/name,可以查看容器运行时候的参数配置等。

进入容器

进入到 docker 容器的内部(简单理解为每一个容器都是单独的操作系统):

bash 复制代码
docker exec -it 容器id/name /bin/bash

直接执行一条命令不进入容器:

bash 复制代码
docker exec 容器名或ID ls /

Docker 镜像构建

下面以一个简单的 Gin 服务器为例,演示如何把 Go 项目构建成 Docker 镜像。

准备示例代码

这是一个简单的 Gin 服务器:

go 复制代码
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/api/hello", func(c *gin.Context) {
	c.JSON(200, gin.H{"message": "hello"})
})

r.GET("/api/status", func(c *gin.Context) {
	c.JSON(200, gin.H{"status": "ok"})
})

r.GET("/api/info", func(c *gin.Context) {
	c.JSON(200, gin.H{"service": "gin-demo", "version": "1.0.0"})
})

r.Run(":9988")
}

编写 Dockerfile

需要编写 Dockerfile 文件,然后通过 docker build -t name . 构建成镜像。下面是对应的 Dockerfile:

dockerfile 复制代码
FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
COPY main.go ./
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o server main.go
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 9988
CMD ["./server"]

这是一个典型的双层构建,主要是为了节省存储空间。

Dockerfile 指令说明

  • FROM:指定系统基础,这里使用的是 golang:1.25-alpine。这个可以在 Docker Hub 上面搜索,或者直接问 AI。
  • WORKDIR:切换到指定目录。
  • COPY:把指定文件拷贝进去。
  • RUN:执行命令。
  • EXPOSE:声明端口,写不写都行。
  • CMD:指定命令,只能写一次。

查看与推送镜像

构建好的镜像直接 docker images 就可以看到。

推送到远程 Docker Hub:先登录 docker login,根据指引登录之后执行 docker push 用户名/镜像:version。

这里需要注意,构建镜像的时候最好以 dockerhub用户名/镜像名 格式命名,后续推送直接推送即可。如果只有镜像名,推送之前需要打 tag:docker tag gin-test:latest username/gin-test:latest。

这样推送完成之后就可以了,后续想 pull 下来,就直接 docker pull username/镜像:version。

Docker 网络

Docker 内部网络和宿主机的网络是隔离的,所以有时候我们需要做端口映射,来让外部可以访问容器内的服务。

通过 docker network create networkName 创建子网,在运行容器的时候可以通过 --network 指定网络。处于同一子网的容器可以通过容器的 name 互相访问,不同子网的容器不能互相访问。

举个例子:创建子网 1,启动两个容器 a、b,在 a 容器中可以直接通过 ping b 访问 b,不需要知道 b 的 IP 地址。

使用 docker network list 可以查看所有的子网。

通过 docker network rm 命令可以删除子网。

另外还可以使用 host 网络模式,直接使用宿主机的端口和 IP:

bash 复制代码
docker run --network host

Docker Compose 容器编排

Docker Compose 是容器编排技术,使用 yml 文件管理多个容器。

每一个 compose 文件会自动生成一个子网,文件内启动的容器自动加入该子网。

在这之前,我们可能尝试过用命令行启动 MySQL:

bash 复制代码
docker run -d \
--name my-mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
--network network1

在 yml 文件中,我们可以这样写:

yaml 复制代码
services:
  my-sql:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - 3306:3306
    volumes:
      - 宿主机地址:容器地址
    depends_on:
      - 另一个容器

如果多个容器之间存在依赖关系,有的需要依赖于另一个容器运行,就可以使用 depends_on 指定该容器启动在指定容器之后。同时文件最上面的 services 只能出现一次,不能在一个文件里声明多个。

使用该文件也非常简单,执行 docker compose up -d 就可以了。

停止:docker compose stop

停止并删除容器:docker compose down

相关推荐
多弗朗皮卡丘1 小时前
Linux 进程信号
linux·运维·服务器
qeen871 小时前
【Linux】动静态库的链接与加载过程
linux·运维·系统编程
重生之小比特2 小时前
【Linux系统】17 库制作与原理(上)
linux·运维·服务器
wzg20162 小时前
ubuntu 离线安装 docker-compose
linux·ubuntu·docker
Shadow(⊙o⊙)3 小时前
仿muduo实现高并发服务器——EchoServer完成
运维·服务器
时间售卖铺3 小时前
Docker镜像构建全解析:从原理到实战优化
运维·docker·云原生·容器
小豆庄4 小时前
会议录屏忘打码后的技术复盘:本地自动化隐私脱敏方案
运维·opencv·目标检测·自动化·视频·纹理贴图
码途行者4 小时前
Linux 服务器 Golang 安装及环境变量配置
linux·运维·服务器
爱和冰阔落4 小时前
【Linux网络】UDP 聊天室怎么实现?从在线用户管理、消息广播到双线程收发与线程池
linux·运维·网络·udp