首页 > 其他分享 >Docker实操过程

Docker实操过程

时间:2024-10-01 17:45:11浏览次数:6  
标签:容器 ID 实操 镜像 docker Desktop 过程 Docker

Docker实操过程

体会

知乎上搜“docker入门”搜到的笔记总是起一个赚噱头的标题,然后点进去一看,里面大多是一些入门内容的简单罗列,要么对于背景内容长篇大论让读者抓不住重点,要么对于命令API简单罗列,入门者甚至连这些API如何衔接使用,这些命令大概发生了什么可能都没有概念,说是入门教程,实际跟着实操之后依然云里雾里。

image

链接

个人比较欣赏的入门教程是这个:Docker超详细教程 | 观星客 (chasonlee.github.io)

其中概念性介绍足够精炼,同时能说明核心的概念,而且实操部分足够详细,从例子讲起。

更新:该地址已经失效。

个人思考

下面是自己在实操后对一些更具体内容的思考补充。

关于DockerDesktop界面

image

如上图,Docker Desktop安装好后,第一个镜像应该是hello-world。稍后我们会用一下它。我个人的感受是先不要用Docker Desktop的可视化界面创建和操作镜像和容器,应该用命令行,多敲命令能更清楚地发现发生了什么,也能更明晰地感受到docker命令执行之后有一个什么结果。Docker Desktop可以作为已有镜像和容器的可视化展示。

上图中,Images镜像,Containers容器,镜像是容器的模板,容器是镜像的实例。镜像与容器好比C++中类与对象。所以同一个镜像可以有多个实例。

镜像或者是容器如何指定?一种是名字,一种是ID。镜像的名字就是Name:Tag的格式,如上图中的hello-world:latest。容器的名字通常就是创建它时指定的名字,用docker ps -a通常都可以看到。而不管是容器还是镜像,ID就是它创建时被分配的唯一hash码,如上图中的9c7a54a9a43c

可视化展示就不多做截图,下面以命令行为主。主打解释一个命令的诸多细节与效果

关于Docker命令行

(base) C:\Users\80563\Desktop>docker pull chasonlee/ubuntu_demo:latest
latest: Pulling from chasonlee/ubuntu_demo
9ff7e2e5f967: Pull complete
59856638ac9f: Pull complete
6f317d6d954b: Pull complete
a9dde5e2a643: Pull complete
583e635329f1: Pull complete
d74dae086c4f: Pull complete
Digest: sha256:f4396916a5cbb3ece8e5eb74a860d956b8957965675d5dde707ed4f316407b8c
Status: Downloaded newer image for chasonlee/ubuntu_demo:latest
docker.io/chasonlee/ubuntu_demo:latest

(base) C:\Users\80563\Desktop>
  • docker pull拉取镜像
  • chasonlee/ubuntu_demo:latest正是之前的镜像指定格式
(base) C:\Users\80563\Desktop>docker image ls
REPOSITORY              TAG       IMAGE ID       CREATED        SIZE
hello-world             latest    9c7a54a9a43c   6 months ago   13.3kB
chasonlee/ubuntu_demo   latest    59693b89568e   4 years ago    158MB

(base) C:\Users\80563\Desktop>docker images
REPOSITORY              TAG       IMAGE ID       CREATED        SIZE
hello-world             latest    9c7a54a9a43c   6 months ago   13.3kB
chasonlee/ubuntu_demo   latest    59693b89568e   4 years ago    158MB

(base) C:\Users\80563\Desktop>docker ps -a
CONTAINER ID   IMAGE                             COMMAND                   CREATED          STATUS          PORTS                  NAMES
44ebbb32efae   docker/welcome-to-docker:latest   "/docker-entrypoint.…"   31 seconds ago   Up 31 seconds   0.0.0.0:8088->80/tcp   welcome-to-docker
  • docker image ls或者docker images查看镜像
  • docker ps或者docker ps -a查看容器,前者只显示运行中的,后者显示所有的,包括已经停止的
(base) C:\Users\80563\Desktop>docker images
REPOSITORY              TAG       IMAGE ID       CREATED        SIZE
hello-world             latest    9c7a54a9a43c   6 months ago   13.3kB
chasonlee/ubuntu_demo   latest    59693b89568e   4 years ago    158MB

(base) C:\Users\80563\Desktop>docker run --rm hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

(base) C:\Users\80563\Desktop>docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
  • docker images查看有什么镜像,然后根据具体名字运行hello-world(组合招),因为实际中经常记不清具体名字。
  • 根据自带hello-world镜像创建一个容器并运行。
  • 图中这个容器的实际内容就是打印这段文字然后直接结束。
  • --rm表示这个容器如果stop,那就立即删除这个容器,而不是留着。如果没有--rm,那么就会留着这个容器。
  • docker ps显示确实没有了该镜像的容器实例。
  • 可以经常使用docker imagesdocker ps来查看现有的镜像和对应的容器以及ID,名称等
(base) C:\Users\80563\Desktop>docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

(base) C:\Users\80563\Desktop>docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED         STATUS                     PORTS     NAMES
a70726ad972b   hello-world   "/hello"   2 minutes ago   Exited (0) 2 minutes ago             amazing_lumiere
  • 没有加--rm的后果

  • 运行完容器,它已经停止(Exited),但是因为没有--rm所以还留着。此时要docker rm a70726ad972b或者docker rm amazing_lumiere手动删除

  • NAMES是amazing-lumiere是因为创建容器时如果不指定容器名(--name),就会自动给一个

  • -it是什么意思:i是交互模式(将当前命令行的终端输入输出接入容器的输入输出),t是伪终端,二者通常结合使用。

  • -d是后台运行的意思,有了这个参数,执行命令后不会将当前命令行转为容器中的命令行,而是只输出创建容器所分配的ID。之后再想进去(必须是容器已经在运行中)可以用docker attach ID

    • ID当然也可以写ContainerName
    • 实际上docker attach ID 的方法并不推荐,因为这样的话当前终端结束会导致该容器一同停止
    • 推荐的用法是exec,个人觉得叫“切入”比较贴切,即临时启动一个终端,让该(已经运行的该容器,如果没有运行需要先docker start ID 运行)执行一条命令,作为当前终端的启动任务,例如
      • docker exec a70726ad972b /bin/bash
      • 这样当前终端退出后不会导致该容器的停止
  • docker exec是针对已存在的容器的,docker run是针对镜像的。

  • Docker Desktop中,容器的log中也可看到容器的命令行输出。

一个综合的例子

image

如上是我在windows上开发的一个项目,这个项目的启动方式是在nl2sql_server_load/ 根目录下运行python -m app_nl2sql_server.app_server来启动。现在需要为它配一个镜像打包到linux服务器上去运行。

首先在项目根目录下放上requirements.txt,写上依赖包

Flask==3.0.3
mysql-connector-python==8.4.0
numpy==1.26.4
pandas==2.2.2
portalocker==2.8.2
pynvml==11.5.0
Requests==2.32.3
tabulate==0.9.0
vanna
vanna[chromadb,openai,mysql]
openpyxl
fastapi
sse_starlette
aiohttp

然后需要在项目根目录下放上Dockerfile ,里面写上(注意看里面的注释)这些指令

FROM robd003/python3.10:latest
# 其实对于部署来说
# 用 FROM python:3.10-slim 会专业
# 因为这个slim更精简,体积更小
# 而我这个后来打完镜像发现有1-2G了

# 将当前工作目录设置为 /app/nl2sql_server_load
# 后面的命令也都将会在WORKDIR上执行,包括你进去容器时也是
WORKDIR /app/nl2sql_server_load

# 复制当前目录(也就是项目根目录)的内容到当前工作目录
# 此时当前工作文件夹为WORKDIR,也就是 /app/nl2sql_server_load
# 第一个句点表示宿主机的当前目录,第二个是容器的当前目录
COPY . .
# 以下是一个小BUG,与本次例子关系不大
# COPY ./nl2sql_server_load/ /app/
# 不要像上面这样写,这样写只会把当前目录下的nl2sql_server_load文件夹的【内容】复制到/app中
# 而不会把这个文件夹作为子文件夹复制过去
# 要把该文件夹复制过去,应该写
# COPY ./nl2sql_server_load/ /app/nl2sql_server_load

# 安装所需的 Python 包
# RUN和下文的CMD不同,RUN作用于构建镜像时,
# 而CMD是在启动每一个由该镜像创建的容器时的默认启动命令,
# 即docker run <image_name>时的启动命令
RUN pip install --no-cache-dir -r nl2sql_server_load/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 那么对于这个CMD指令,如果想(根据镜像)启动容器并且不执行默认的启动命令,应该写
# docker run -it --entrypoint /bin/bash <image_name>
# 表示把/bin/bash作为本次该镜像创建的容器的启动命令,而不是默认的命令

# 暴露应用运行的端口
EXPOSE 63000

# 启动服务
# CMD python -m app_nl2sql_server.app_server
# 现实还是很难一步到位,
# 后来我实操发现还有bug,不能跑起来,所以这句其实没必要写
# 应该在创建并运行容器,在容器里面debug完成确认能跑起来再手动在容器中启动

然后在项目根目录下用该Dockerfile来构建镜像:

docker build -t oms:v1 .

也就是说,假设你有一个名为nl2sql_server_load的项目根目录,其中包含了一个Dockerfile,你想要基于这个Dockerfile创建一个新的镜像,并将其标记为oms,标签为v1。这里的.表示当前目录,也就是包含Dockerfile的目录。

构建完成之后,就可以基于该镜像创建容器

docker run -it --entrypoint /bin/bash -p 127.0.0.1:63000:63000 --name oms2 oms:v1

注意镜像名称要放在最后,不然不行。

注意该命令设置的端口映射。

这个时候就进去了容器,可以装些必要东西,然后再手动运行项目。

检查确认项目成功跑起来之后,可以根据该容器导出镜像文件

docker export oms2 -o container_backup.tar

然后把该.tar文件传到服务器上,再在服务器上用docker导入成镜像

docker import container_backup.tar oms:v2

就可以在服务器上用该镜像创建容器了。

docker run -it --entrypoint /bin/bash -p 127.0.0.1:63000:63000 --name oms2 oms:v2

备注:为什么要先写dockerfile构建镜像,由该镜像创建了容器,再由容器导出镜像文件,再传到服务器上用docker引入该镜像?有两个原因,一是dockerfile创建的镜像oms:v1所创建的容器并不一定直接可用,中间可能有bug。这个时候改完bug的容器相对于oms:v1来说已经有了一个更新。所以应该基于这个最新的容器导出成镜像。第二是服务器不连网,不能直接在服务器上用dockerfile来构建镜像。只能把镜像先打包好再传到服务器上用docker导入。

标签:容器,ID,实操,镜像,docker,Desktop,过程,Docker
From: https://www.cnblogs.com/isshiki-iroha/p/18443011

相关文章

  • 【防忘笔记】测试过程与技术
    测试人员应该想些什么我自己是做后端的,对于模棱两可的需求和莫名其妙的测试case是深恶痛绝的,所以有时候我就会想测试人员应该会需要注意什么?以他们的角度,他们更在乎什么最近有机会了解相关的知识,遂整理记录一下,以便之后在工作中更好的理解发生的各种事情以客户为中心这个真的......
  • 【Docker】Docker 容器的使用指南:如何进入容器并运行命令
    目录1.什么是Docker容器?2.进入Docker容器的方法2.1使用`dockerexec`2.2使用`dockerattach`2.3使用`dockerrun`3.常见选项与参数4.退出容器5.进入容器的实际操作步骤步骤1:查看正在运行的容器步骤2:进入容器步骤3:在容器中运行命令步骤4:退出容器6.......
  • 【PostgreSQL】提高篇——如何创建和使用自定义函数和存储过程,包括 PL/pgSQL 语言的使
    数据库管理中,存储过程和自定义函数是非常重要的概念,尤其是在使用PostgreSQL这样的关系数据库管理系统时。它们允许开发者将复杂的业务逻辑封装在数据库中,从而提高应用程序的性能、可维护性和安全性。使用PL/pgSQL语言编写的存储过程和函数可以实现数据处理、事务控制和复......
  • 智源:LLM训练过程中的指令相关性
    ......
  • 掌握Docker:简化KES单机安装与管理的最佳实践
    今天我们将继续深入探讨KES的单机安装,依然围绕Docker的使用展开。这一部分的内容将涵盖一些常见的陷阱以及在遇到问题时如何进行有效的反馈和解决。首先,我们需要找到官方的安装教程,确保以官方指南为主,同时结合我们自己的使用习惯。为什么我们如此青睐Docker,而不是选择传统的命令......
  • 七,MyBatis-Plus 扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用)
    七,MyBatis-Plus扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用)@目录七,MyBatis-Plus扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用)1.乐观锁2.代码生成器3.执行SQL分析打印4.总结:5.最后:1.乐观锁首先我们需要先了解开发中的一个常见场景,叫做并发请求。并......
  • 数据订阅与消费中间件Canal 服务搭建(docker)
    MySQLBin-log开启进入mysql容器dockerexec-itmysql5.7bash开启mysql的binlogcd/etc/mysql/mysql.conf.dvimysqld.cnf#在文件末尾处添加如下配置(如果没有这个文件就创建一个)[mysqld]#开启binloglog-bin=mysql-bin#log-bin=/var/lib/mysql/mysql-bin#或者配......
  • 阿里面试:说说 jvm 锁的膨胀过程?锁内存怎么变化的?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • DRF实操——项目部署
    DRF实操——项目部署一、Mysql集群1.集群方式1)Replication集群2)PXC集群2.Docker安装PXC知识补充:具名数据卷创建docker容器django后端接口服务二、Nginx概述作用安装配置三、uWSGI1.概述2.项目的配置3.将本地项目及环境打包到服......
  • [Uninstall] 软件彻底卸载工具的下载及详细安装使用过程(附有下载文件)
    一般软件安装的有问题,或者想重新安装其他版本就需要将原来的版本删除干净,但常常删不干净,本文分享一个软件彻底卸载工具,完成彻底卸载软件的工作下载链接在文末下载压缩包后解压!!安装路径不要有中文解压后得到UninstallToolv3.6.1文件双击exe文件假设这里要删除Git,则点......