您现在的位置是:网站首页> 边看边学

docker 技术收集

摘要

docker 技术收集


1.jpg





***当Docker下载镜像出问题时使用临时镜像下载***

AI学习 Docker

Linux安装docker

Docker镜像源收集

Docker Desktop不能查找到镜像

Docker原理

Docker 1小时快速上手教程,无废话纯干货

Docker 容器内部如何访问本机的服务

Docker Desktop安装使用

docker compose 部署和docker部署区别

如何进入docker容器编辑容器内文件

Docker容器网络互访

docker 本地文件夹给容器用如何做

Docker如何创建自己的镜像

现在 Github 上有很多应用都提供了 Docker 部署的选择




AI学习 Docker

####【豆包】

如何自建docker仓库

...


####【豆包】

docker如何创建自己的镜像

...



Linux安装docker

在 Linux 系统上安装 Docker 可以按照以下步骤进行,以下方法适用于大多数主流 Linux 发行版:

Ubuntu/Debian 系统

1.更新系统包并安装依赖:

sudo apt update

sudo apt install ca-certificates curl gnupg lsb-release


2.添加 Docker 官方 GPG 密钥:

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


3.设置 Docker 稳定版仓库

echo "deb [arch=$(dpkg --print-architecture) 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


4.安装 Docker 引擎

sudo apt update

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


CentOS/RHEL 系统

1.安装必要的依赖:

sudo yum install -y yum-utils


2.设置 Docker 仓库

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo


3.安装 Docker 引擎

sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin


启动并验证 Docker

1.启动 Docker 服务:

sudo systemctl start docker


2.设置 Docker 开机自启

sudo systemctl enable docker


3.验证 Docker 是否安装成功

sudo docker run hello-world

如果一切正常,这个命令会下载一个测试镜像并运行,最后输出 "Hello from Docker!" 等信息,表明 Docker 已成功安装并可以正常工作。





Docker镜像源收集

2025年目前还可用的docker镜像源:

docker.1ms.run

docker.domys.cc

docker.imgdb.de

docker-0.unsee.tech

docker.hlmirror.com

cjie.eu.org

docker.m.daocloud.io

hub.rat.dev

docker.1panel.live

docker.rainbond.cc,


临时使用

docker pull 镜像源/需要拉取的镜像

举例:docker pull docker.1ms.run/nginx:latest

1.png

下载后的镜像名称是带镜像源的如下图:

1.jpg


Docker Desktop不能查找到镜像

注:如因网络问题无法拉取docker镜像可按下方步骤操作配置镜像源:

Setting->Docker Engine->添加上换源的那一段,如下图:

"registry-mirrors":["https://hub.rat.dev","https://docker.1panel.live"],

1.png



Docker原理

Docker 是一个开源的应用容器引擎,它的核心思想是通过轻量级的容器技术来实现应用的快速部署、迁移和运行。Docker 的运行原理涉及到操作系统底层的命名空间(Namespaces)、控制组(Cgroups)和联合文件系统(Union File System)等技术。以下是一个详细的讲解,结合 Nginx 镜像的例子来说明。

1. Docker 的核心原理

Docker 的运行依赖于 Linux 内核的特性,主要包括以下几点:

(1) 命名空间(Namespaces)

命名空间是 Linux 内核的一种特性,用于隔离进程的运行环境。Docker 使用命名空间来实现容器的隔离,让每个容器看起来像是独立的系统。
  • PID Namespace:隔离进程 ID,容器中的进程只能看到自己命名空间内的 PID。
  • Network Namespace:隔离网络栈,容器可以有自己的 IP 地址、端口和网络接口。
  • Mount Namespace:隔离文件系统挂载点,容器可以有自己的挂载点。
  • UTS Namespace:隔离主机名和域名,容器可以有自己的主机名。
  • IPC Namespace:隔离进程间通信资源,容器内的进程无法与宿主机或其他容器通信。
  • User Namespace:隔离用户 ID 和组 ID,容器内的用户和组与宿主机无关。

(2) 控制组(Cgroups)

控制组是 Linux 内核的另一种特性,用于限制、记录和隔离进程组的资源使用(如 CPU、内存、磁盘 I/O 等)。Docker 使用 Cgroups 来分配和限制容器的资源使用,确保容器不会过度占用宿主机的资源。

(3) 联合文件系统(Union File System)

联合文件系统是一种分层的文件系统,允许将多个目录叠加在一起,形成一个统一的视图。Docker 使用联合文件系统来构建镜像和容器的文件系统。镜像由多层组成,每一层都是只读的,而容器在运行时会在镜像的基础上添加一个可写的层。

2. Nginx 镜像的运行原理

假设我们运行一个 Nginx 镜像,以下是它在 Docker 中的运行过程:

(1) 镜像的结构

Nginx 镜像通常基于一个基础操作系统(如 Alpine Linux 或 Ubuntu),并包含 Nginx 的二进制文件、配置文件和依赖库。镜像的文件系统是分层的,每一层都是只读的。

(2) 容器的启动

当运行 docker run nginx 时,Docker 会执行以下步骤:
  1. 加载镜像:Docker 从镜像仓库(如 Docker Hub)拉取 Nginx 镜像。
  2. 创建容器:Docker 为容器分配一个独立的命名空间和 Cgroups,隔离进程、网络、文件系统等资源。
  3. 挂载文件系统:Docker 将镜像的只读层和一个可写的容器层联合挂载,形成容器的根文件系统。
  4. 启动进程:Docker 在容器中启动 Nginx 进程,该进程运行在容器的命名空间中。

(3) 容器的运行环境

  • 操作系统容器运行在宿主机的 Linux 内核上但容器的文件系统是独立的,基于镜像中的文件系统。例如,如果 Nginx 镜像是基于 Alpine Linux,容器的文件系统会包含 Alpine 的库和工具,但容器的内核是宿主机的内核
  • 隔离性:容器内的进程无法直接访问宿主机或其他容器的资源,因为它们被隔离在独立的命名空间中。
  • 资源限制:Docker 使用 Cgroups 限制容器的资源使用,例如 CPU 和内存。

3. 总结:Nginx 容器运行在哪个操作系统上?

Nginx 容器运行在宿主机的 Linux 内核上,但容器的文件系统是基于镜像的,通常包含一个轻量级的操作系统(如 Alpine Linux)。容器并没有独立的内核,而是共享宿主机的内核。
  • 文件系统:容器的文件系统是镜像中的文件系统,例如 Alpine Linux 的文件系统。
  • 内核:容器使用宿主机的内核。
  • 进程隔离:容器内的进程运行在独立的命名空间中,无法直接访问宿主机或其他容器的资源。

4. 示例:运行 Nginx 容器

假设宿主机是 Ubuntu 系统,运行以下命令:
bash复制    
docker run -d -p 8080:80 nginx
   
  • 容器的文件系统基于 Nginx 镜像(通常基于 Alpine Linux)。
  • 容器的内核是宿主机的 Ubuntu 内核。
  • 容器的 Nginx 进程运行在独立的命名空间中,监听容器内的 80 端口,而宿主机的 8080 端口被映射到容器的 80 端口。

5. Docker 的优势

  • 轻量化:容器共享宿主机的内核,启动速度快,资源占用少。
  • 隔离性:容器之间完全隔离,互不干扰。
  • 可移植性:容器可以在任何支持 Docker 的环境中运行,无需关心底层操作系统。
通过这些原理,Docker 能够高效地运行像 Nginx 这样的应用,同时提供良好的隔离性和资源管理能力。



Docker 1小时快速上手教程,无废话纯干货

点击查看课件

点击查看Docker Desktop安装使用

点击查看docker在线教程

Docker 不是独立的虚拟机,两者的核心区别在于虚拟化层次和资源隔离级别

Docker 容器的本质

共享内核:容器内的进程直接运行在宿主机内核上(例如在 Linux 宿主机上运行 Ubuntu 容器时,实际使用的是宿主机 Linux 内核)。

用户空间隔离:通过 Namespace 隔离进程的视图(如文件系统、网络、PID 等),通过 Cgroups 限制资源使用(如 CPU、内存)。

轻量级:容器仅是进程及其依赖的打包,无需虚拟化硬件或运行完整操作系统。


为什么容器不是虚拟机?

无法运行不同内核的系统:例如,Linux 宿主机上的 Docker 容器无法直接运行 Windows 程序(需借助特殊工具),而虚拟机可以运行任何操作系统。

进程级隔离:容器内的进程在宿主机上可见(但被隔离),虚拟机内的进程完全独立。

依赖宿主机的内核:容器镜像仅包含用户空间的程序和依赖库,不含内核,因此容器无法脱离宿主机内核独立运行。


Docker 容器和镜像之间有什么关系?

Docker 容器和镜像之间的关系可以理解为蓝图和实例的关系:

1、定义: Docker 镜像是容器的只读模板,包含了运行容器所需的代码、库、环境变量和配置文件

2、实例化: 当 Docker 镜像运行时,它会成为一个容器,即镜像的实时、可写版本

3、层叠构建: Docker 镜像是通过一系列的层叠构建而成,每个层代表镜像构建过程中的一个步骤。

默认的源地址:

"registry-mirrors": [

    "https://hub.docker.com"

  ]


最新可用地址可以直接问AI:

如:https://docker-0.unsee.tech/


国内可用的源:

"registry-mirrors": [

    "https://docker.m.daocloud.io",

    "https://noohub.ru",

    "https://huecker.io",

    "https://dockerhub.timeweb.cloud",

    "https://docker.rainbond.cc",

    "https://dockerhub.icu",

    "https://docker.chenby.cn",

    "https://docker.1panel.live",

    "https://docker.awsl9527.cn",

    "https://docker.anyhub.us.kg",

    "https://dhub.kubesre.xyz",

    "https://docker.1ms.run",

    "https://docker.xuanyuan.me"

  ]


Docker 容器内部如何访问本机的服务

要让Docker容器访问宿主机上的服务,可以使用特殊的网络地址host.docker.internal。这个地址在Docker 18.03及以上版本的Windows和Mac上可用。

在容器内部,使用host.docker.internal代替localhost或127.0.0.1。


本机如何访问docker内服务

要从本机访问Docker容器内的服务,您可以使用以下方法:

1.端口映射:使用 -p 参数将容器端口映射到本机端口。

例如,如果您有一个运行在容器内部端口80的Web服务,并且您想通过本机的端口8080访问它,您可以这样运行容器:

docker run -p 8080:80 your-image

然后您可以通过访问 http://localhost:8080 或者 http://127.0.0.1:8080 从本机访问该服务。


2.连接到Docker网络:如果您想要从本机访问容器,而不是通过端口映射,可以将您的容器连接到Docker默认网络。


首先,创建一个网络(如果还没有的话):

docker network create my-network

然后,运行您的容器并将其连接到该网络:

docker run --network=my-network --name=my-container your-image


现在,您可以通过容器名称来从任何其他连接到同一网络的容器或本机访问它。

例如,使用 docker exec 命令从本机ping容器:

docker exec my-container ping $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container)


或者,如果您的容器暴露了一个内部端口,您可以直接通过容器的内部IP地址来访问服务:

curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container):80

请根据您的具体需求和服务配置选择适当的方法。


典型命令例子

docker pull nginx:latest  下载镜像

docker images 显示下载的镜像

docker run -d -p 81:80 nginx  运行镜像  -d是后台运行 -p是映射端口  外部端口81 内部端口80

docker ps 显示正在运行的镜像

进入运行的镜像

docker exec -it 92[这个是运行的id]  bash

提示 

root@92[这个是运行的id]

退出镜像容器

exit

这时候按正常的usr目录之类的操作了

cd /usr/share/nginx/html/

cat index.html

修改index.html

echo hello >index.html

再次访问chrome ctrl+F5强制刷新

退出运行的镜像 exit

强制删除运行的镜像

docker rm -f 92[这个是运行的id]

当前镜像保存

docker commit 92[这个是运行的id] m1[保存为m1]


docker commit 命令用于从一个已经运行的容器中创建一个新的镜像。这个命令并不会将镜像保存到特定的位置,而是会保存在 Docker 的本地镜像库中。

如果你想要保存镜像到一个文件,你可以使用 docker save 命令。

例如,如果你想要保存一个名为 myimage:mytag 的镜像到一个名为 myimage.tar 的文件中,你可以使用以下命令:

docker save myimage:mytag -o myimage.tar

这将会创建一个名为 myimage.tar 的文件,里面包含了 myimage:mytag 镜像的所有层及相关的元数据。

要从这个文件加载镜像,你可以使用 docker load 命令:

docker load -i myimage.tar

这将会把 myimage.tar 文件中的镜像加载到本地的 Docker 镜像库中。

查帮助 docker commit  --help


提交自己的镜像

(以nginx镜像为例)

(这里提交的是到系统本地仓库)

docker pull nginx        #以nginx镜像为例 

docker run -itd --name mynginx nginx /bin/bash #创建一个名为mynginx的容器 

docker exec -it mynginx /bin/bash #进入容器,增加一些自己的内容,比如装一个vim等 

#注意:下面在mynginx:v1.0前面加的guianjun是对应到Docker Hub自己账号的公网仓库名一致,否则后面将无法推送到公网Docker Hub自己的仓库下面,如果只是推送到本地系统仓库,则可以不用加

docker commit -m "安装了vim" mynginx guianjun/mynginx:v1.0    #提交容器 

docker images          #查看镜像是否提交成功 

docker image history guianjun/mynginx:v1.0   #查看镜像提交记

1.png‘’

docker run -itd --name mynginx_test mynginx:v1.0    

 #进入容器发现已经装好vim

docker exec -it mynginx_test /bin/bash


上传自己制作的镜像到远程仓库

docker push --help

上传镜像到公网仓库

首先现在Docker Hub注册自己的账号

1.png

docker login

1.png

docker image push guianjun/mynginx:v1.0

1.png

1.png推送成功




dockerfile编写(想当于批处理) 文件内容如下

FROM nginx #基于nginx镜像构建新镜像

ADD ~/ /usr/share/nginx/html  #将当前文件copy到容器的指定html目录


运行dockerfile

docker build -t m2 .  #当前dockerfile构建一个镜像


可以运行新构建的m2

docker run -d -p 100:80 m2


将镜像保存为文件

docker save m2 > 1.tar  


删除镜像

docker rmi m2


加载tar文件

docker load <1.tar

这时候镜像m2再次出来

docker images 查看


运行还可以指定名字

docker run -d -p 999:80 --name mynginx  m2


文件映射

docker run -d -p 999:80  -v /usr/123 :/usr/share/nginx/html -v 'pwd' :/usr/123 m2



搜索docker的镜像

docker search  nginx 


复制文件

sudo docker cp /Users/front/Downloads/beifen.bak MSSQL_1433:/var/opt/mssql/backup



docker compose 部署和docker部署区别

Docker 部署

指直接使用 docker run 命令或 Dockerfile 构建镜像后,手动管理单个容器的生命周期(启动、停止、删除等)。适用于仅需部署单个容器的简单应用(如单独运行一个 Nginx 或 MySQL 容器)。

Docker Compose 部署

是 Docker 官方提供的工具,通过一个 YAML 配置文件(docker-compose.yml)定义多个关联的容器(如前端、后端、数据库、缓存等组成的完整应用),并使用 docker-compose 命令一键管理这些容器的启动、停止、重启等操作。


部署单个 Nginx 容器

Docker 部署:

需要手动输入命令,指定端口、挂载目录等参数:

bash

docker run -d --name nginx -p 80:80 -v /app/html:/usr/share/nginx/html nginx:latest


Docker Compose 部署

先编写 docker-compose.yml:

yaml

version: '3'

services:

  nginx:

    image: nginx:latest

    ports:

      - "80:80"

    volumes:

      - /app/html:/usr/share/nginx/html


再执行启动命令:

bash

docker-compose up -d


指定文件部署:

docker-compose -f xn.yml up -d


部署多服务应用(如 Web + MySQL)

Docker 部署:

需分步骤创建网络、启动 MySQL、启动 Web 容器,并手动关联网络:

bash

# 创建网络

docker network create mynet

# 启动 MySQL

docker run -d --name mysql --network mynet -e MYSQL_ROOT_PASSWORD=123 mysql:5.7

# 启动 Web 容器(假设依赖 MySQL)

docker run -d --name web --network mynet -p 8080:8080 my-web-app:latest


Docker Compose 部署:

配置文件自动处理网络和依赖:

yaml

version: '3'

services:

  mysql:

    image: mysql:5.7

    environment:

      - MYSQL_ROOT_PASSWORD=123

  web:

    image: my-web-app:latest

    ports:

      - "8080:8080"

    depends_on:  # 声明依赖关系(启动顺序)

      - mysql



一键启动:

bash

docker-compose up -d  # 自动创建网络,按依赖顺序启动容器

总结

Docker 部署适合简单场景,灵活但繁琐,需手动管理容器间的依赖和网络。

Docker Compose 部署通过配置文件简化了多服务应用的部署流程,自动处理网络、依赖和协作,更适合开发环境和中小型多服务应用。



如何进入docker容器编辑容器内文件

1. 进入 Docker 容器

首先需要找到容器的 ID 或名称,然后进入容器的交互式终端:


bash

# 查看正在运行的容器

docker ps


# 进入容器(替换CONTAINER_ID或容器名称)

docker exec -it CONTAINER_ID /bin/bash

# 如果容器内没有bash,可以尝试sh

docker exec -it CONTAINER_ID /bin/sh


-it 参数表示交互式终端,允许你在容器内输入命令。

2. 编辑容器内的文件

进入容器后,可以使用容器内已安装的文本编辑器编辑文件:


如果容器内有 vim:

bash

vim 文件名


如果容器内有 nano:

bash

nano 文件名


如果容器内没有任何编辑器,可以先安装(需要容器内有包管理工具且有网络):

bash

# Debian/Ubuntu系统

apt-get update && apt-get install vim


# CentOS/RHEL系统

yum install vim


3. 其他编辑方式(不进入容器)

如果不想进入容器,也可以通过以下方式编辑文件:

方法 1:直接在宿主机编辑容器文件

容器的文件系统实际上存储在宿主机的特定位置,可以通过以下命令找到文件路径并在宿主机编辑:


bash

# 查找容器文件在宿主机的路径(替换CONTAINER_ID和容器内文件路径)

docker inspect -f '{{ .GraphDriver.Data.MergedDir }}' CONTAINER_ID

# 然后在宿主机中使用该路径直接编辑文件(需要root权限)


方法 2:将容器文件复制到宿主机编辑后再复制回去

bash

# 复制容器内文件到宿主机

docker cp CONTAINER_ID:容器内文件路径 宿主机目标路径


# 在宿主机编辑文件后,再复制回容器

docker cp 宿主机文件路径 CONTAINER_ID:容器内目标路径


选择哪种方法取决于你的具体需求和容器的配置情况。进入容器直接编辑是最常用和直观的方式。

1.png

docker cp 9e2aafa76234:/app/config.json d:\\config.json


Docker容器网络互访

docker network create mynet

# 启动容器时连接到 mynet 网络

docker run -d --name container1 --network mynet nginx

docker run -d --name container2 --network mynet mysql


# 此时 container1 可以通过 "container2" 这个名称访问到 mysql 容器


自定义网络(如 mynet)内置了 DNS 解析功能,会自动将容器名称(container2)映射到其 IP 地址。因此,container1 中可以直接使用 container2 作为 “主机名” 访问 MySQL 服务。

在 container1 内部访问 container2 的 MySQL 服务

ping container2


$pdo = new PDO(

    'mysql:host=container2;port=3306;dbname=test',

    'root',       // MySQL 用户名(默认 root)

    'password'    // MySQL 密码(需与 container2 启动时设置的一致)

);



docker 本地文件夹给容器用如何做

命令格式

docker run -v [本地绝对路径]:[容器内目标路径]:[权限] [镜像名]

容器内目标路径以/开头

docker run -it -v ~/my-project:/data ubuntu

被映射的目录在容器的根目录下

1.png



关键参数说明

本地绝对路径:必须是完整路径(如 Windows 的 C:\Users\test\data,Linux/macOS 的 /home/user/data)。

容器内目标路径:容器内要映射到的路径(如 /app/data),不存在会自动创建。

权限(可选):

ro:只读(容器内无法修改本地文件)。

不写则默认「读写」(容器和本地均可修改)。


示例(以 Linux/macOS 为例)

将本地 ~/my-project 文件夹,映射到容器内的 /workspace,运行一个 Ubuntu 容器:


bash

# 1. 先在本地创建文件夹(可选,不存在会报错)

mkdir -p ~/my-project


# 2. 启动容器并挂载

docker run -it -v ~/my-project:/workspace ubuntu


进入容器后,在 /workspace 下创建文件,本地 ~/my-project 会同步出现;反之亦然。

2. 推荐方式:数据卷(Docker 管理的存储)

数据卷是 Docker 专门管理的目录(默认存放在 /var/lib/docker/volumes/),比绑定挂载更稳定(不受本地路径变动影响),适合长期存储数据。

操作步骤

创建数据卷

bash

docker volume create my-volume  # 创建名为 my-volume 的卷


挂载数据卷到容器

命令中用「卷名」替代本地路径,Docker 会自动管理卷的实际存储位置:

bash

docker run -it -v my-volume:/app/data ubuntu



查看卷详情(可选)

查看卷的实际存储路径、挂载容器等信息:

bash

docker volume inspect my-volume



Docker如何创建自己的镜像

创建自己的 Docker 镜像主要有两种方式:通过docker commit命令从容器创建(不推荐,缺乏可追溯性)和通过Dockerfile构建(推荐,可重复、易维护)。以下是详细步骤:

方法一:通过 Dockerfile 构建镜像(推荐)

Dockerfile是一个文本文件,包含构建镜像所需的一系列指令。通过docker build命令可基于 Dockerfile 自动构建镜像,这是工业级标准做法。

步骤 1:创建项目目录并编写 Dockerfile

新建一个目录(用于存放 Dockerfile 和相关文件):

mkdir my-docker-image && cd my-docker-image

创建并编辑Dockerfile(文件名必须为Dockerfile,无扩展名):

touch Dockerfile

vim Dockerfile  # 或使用nano、vscode等编辑器


步骤 2:编写 Dockerfile 指令

以下是一个简单的示例(构建一个基于 Python 的 Web 应用镜像):

dockerfile

# 基础镜像(必须是第一个指令)

FROM python:3.9-slim


# 维护者信息(可选)

LABEL maintainer="yourname@example.com"


# 设置工作目录(后续命令在此目录执行)

WORKDIR /app


# 复制当前目录下的文件到容器的/app目录

COPY . /app


# 安装依赖(RUN用于执行命令)

RUN pip install --no-cache-dir -r requirements.txt


# 暴露容器端口(仅声明,需配合docker run -p映射)

EXPOSE 5000


# 容器启动时执行的命令(启动应用)

CMD ["python", "app.py"]

常用 Dockerfile 指令说明

FROM:指定基础镜像(如ubuntu:20.04、nginx:alpine)。

RUN:在镜像构建阶段执行命令(如安装软件、配置环境)。

COPY/ADD:复制本地文件到镜像中(ADD支持 URL 和自动解压,推荐优先用COPY)。

WORKDIR:设置工作目录(类似cd,后续指令在此目录执行)。

EXPOSE:声明容器运行时监听的端口(仅为文档说明,需docker run -p实际映射)。

CMD:容器启动时执行的命令(可被docker run后的命令覆盖)。

ENTRYPOINT:类似CMD,但不可被覆盖(常用于固定启动参数)。


步骤 3:准备项目文件

以上述 Python 示例为例,需在my-docker-image目录下准备:

app.py(应用代码):


from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello():

    return "Hello, My Docker Image!"

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=5000)


requirements.txt(依赖列表):

flask==2.0.1


步骤 4:构建镜像

在Dockerfile所在目录执行docker build命令:

# -t 给镜像命名并指定标签(格式:仓库名:标签,标签默认latest)

docker build -t my-python-app:v1 .

. 表示当前目录(Dockerfile 所在路径)。

构建成功后,通过docker images可看到新镜像:

docker images | grep my-python-app


步骤 5:测试镜像

运行基于新镜像的容器,验证功能:

# -p 映射主机端口到容器端口(主机端口:容器端口)

docker run -d -p 5000:5000 --name my-app-container my-python-app:v1

访问http://localhost:5000,若看到 "Hello, My Docker Image!",说明镜像构建成功。


方法二:通过 docker commit 从容器创建(不推荐)

这种方式是先运行一个基础容器,手动修改后将其 “快照” 为新镜像。缺点是无法追踪修改过程,难以维护。

步骤 1:运行基础容器并修改

# 运行一个Ubuntu容器并进入交互模式

docker run -it --name my-temp-container ubuntu:20.04 /bin/bash


# 在容器内进行修改(如安装软件)

apt update && apt install -y nginx

# 修改完成后按Ctrl+D退出容器


步骤 2:提交为新镜像

# 将修改后的容器提交为新镜像

docker commit my-temp-container my-nginx:v1

my-temp-container是容器名,my-nginx:v1是新镜像的名称和标签。


镜像优化最佳实践

1.使用轻量级基础镜像:如alpine版本(体积小,适合生产环境),例如python:3.9-alpine代替python:3.9。

2.合并 RUN 指令:用&&和\合并命令,减少镜像层数:

dockerfile

RUN apt update && \

    apt install -y nginx && \

    rm -rf /var/lib/apt/lists/*  # 清理缓存,减小体积

3.使用.dockerignore文件:排除不需要打包进镜像的文件(如node_modules、.git),减少镜像体积。

4.多阶段构建:仅保留运行所需文件(例如编译阶段用一个镜像,运行阶段用另一个轻量镜像)。


推送镜像到仓库(可选)

若需共享镜像,可推送到 Docker Hub 或私有仓库:


# 登录Docker Hub(需先注册账号)

docker login


# 给镜像打标签(格式:仓库用户名/镜像名:标签)

docker tag my-python-app:v1 yourusername/my-python-app:v1


# 推送镜像

docker push yourusername/my-python-app:v1

通过 Dockerfile 构建镜像的方式可通过代码管理工具(如 Git)追踪变更,是团队协作和持续集成的首选方案



现在 Github 上有很多应用都提供了 Docker 部署的选择

点击查看原文

现在 Github 上有很多应用都提供了 Docker 部署的选择,其中不少复杂的应用甚至把 Docker 部署作为最推荐的方案。拿一个机器人平台 AstrBot为例。官方文档里面在部署方面只有三行指令:

git clone https://github.com/AstrBotDevs/AstrBot

cd AstrBot

sudo docker compose up -d

默认读取当前目录的docker-compose.yml或docker-compose.yaml


那它背后到底发生了什么呢?

当我们第一次 docker compose up 或者 docker run 某个容器时,Docker 会先在本地看看是否存在对应的 镜像(image)。

如果已经有了,就直接用这个镜像创建一个新的 容器(container) 实例。

如果没有,docker 会自动去DockerHub上拉取。

第一次拉取镜像速度可能比较慢(可能需要配置科学上网或者配置docker镜像站点,国内访问速度比较慢),但以后只要敲一句 docker start,几乎立刻就能起来。


而且 Docker 还有一个好处:容器和宿主机是隔离的。容器里安装的各种包、各种配置,对于电脑本身不会有任何的影响。就算哪天这个容器崩了,你只需要一句 docker rm 把它删掉,再重新跑一次 docker run,环境就是干干净净的。


Docker 基本指令

docker build . -t name:自己写 Dockerfile,然后构建一个镜像。

docker run image-name:基于镜像启动一个容器

docker stop container-name:停止一个正在运行的容器(但容器内数据还在)。

docker rm container-name:删除容器实例。

docker rmi image-name:删除镜像。


一个简化版本的dockerfile


FROM node:22.18.0-alpine


WORKDIR /app

COPY . . 

RUN npm ci --only=production

RUN mkdir -p /app/data /app/logs && chown -R node:node /app/data /app/logs


VOLUME ["/app/data", "/app/logs"]

EXPOSE 8080 8081

CMD ["npm", "run", "start"]

























Top