百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

玩Docker,不求人~保姆级入门教程!

ztj100 2025-01-27 01:19 13 浏览 0 评论

Docker是NAS的重要玩法之一,没有Docker的NAS莫得灵魂,就像西方不能没有耶路撒冷!

开始分享教程以来,发现不少小伙伴对于Docker并不太了解,有的甚至是一脸懵的状态~本篇旨在帮助咱们玩家快速掌握Docker基本用法,满足大部分需要,更好的玩转NAS!

篇幅较长,尽可能细;如果觉得不错,还请支持~

那么,什么是Docker?

Docker是一种快速构建、运行、管理应用的工具,简单来说就是帮助咱们去部署各种项目以及项目所需的各种组件,也可以看作是一个运维工具。

过去的项目,基本只能通过手动命令来操作Linux服务器,通过一些脚本来实现部署,还是比较复杂、麻烦(命令多、安装包多、安装步骤复杂)。在现在微服务盛行的当前,Docker为我们的效率带来极大提升,无需成为运维大师,也能轻松玩起来!

举个栗子

传统方式部署Nginx比较麻烦,大致需要以下步骤:

  • 搜索并下载Nginx包体
  • 上传至Linux服务器
  • 编译及配置环境
  • 安装

通过Docker部署则仅需一条命令完事儿:

docker run -d --name nginx -p 80:80 nginx

也可写成:

docker run -d \
  --name nginx \
  -p 80:80 \
  nginx

本质也是一行命令,因为不够直观,所以用 \ 换行

复制粘贴再敲下回车键,即可全自动安装~

当然这里的命令行少了部分东西,放在后面说;但这种一键式部署方式,爽飞了有没有?

Docker 准备工作

想要体验Docker所带来的便利,首先要进行Docker的部署。很多情况下我们一般利用SSH工具连接服务器,通过命令行进行操作。

成品NAS

这里以威联通为例,初始化系统后,打开App Center安装名为Container Station的应用程序(威联通的官方Docker图像化管理工具)

除去能更轻松管理Docker,Container Station也是商店内部分应用软件的安装前提。这方面可看作购买使用品牌NAS的好处之一。

云服务器(VPS)、Linux虚拟机等

这里以阿里云服务器为演示平台,操作系统为Debian_12_x64(个人使用推荐Debian/Ubuntu),其它Linux发行版大同小异。

1更新软件包列表

输入以下命令并回车,等待包体安装更新:

apt update -y

这个命令可让系统的包管理器(APT)从配置的源中下载包的最新列表,以确保在安装新软件或更新现有软件时,能够获取到最新的版本。

2安装常用软件包

输入以下命令:

apt install sudo vim git wget curl -y


日常用完全够。Red Hat、CentOS或Fedora等,需使用它们各自的包管理器,如yum或dnf来安装软件包。

3安装Docker及Docker Compose

官方指引手册:https://docs.docker.com/engine/install

输入以下命令:

apt install docker -y # 安装docker

docker -v # 验证安装

systemctl enable docker # 设置docker开机自启

apt install docker-compose -y # 安装docker compose

docker-compose -v # 确认docker compose版本

4配置镜像加速

看需求,若镜像下载速度很慢,可以进行配置。

以阿里云为例,提供一个免费的加速器地址,获取入口:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

可以看到官方已经给出现成命令

一条条复制进去执行即可

Docker 入门

首先是两个关键名词:image(镜像)、container(容器)

基础讲解

还是以Nginx为例,文章开头我们的部署命令如下:

docker run -d \
  --name nginx \
  -p 80:80 \
  nginx

可以看到,我们回车执行命令后,Docker首先在本地搜索有无镜像,若没有则会去搜索并下载Nginx对应版本的镜像,然后自动运行它。

镜像中不仅包含了Nginx本体,还一并打包了它运行所需的环境、配置、系统函数库。

为了更直观理解镜像,不晓得大家是使用过绿色免安装版本的软件?某某软件园下载后解压后,也不用安装,进入文件夹找到并双击.exe文件直接就能用,Docker也可近乎理解成此。

Docker在运行镜像时会为每一个应用创建一个隔离、独立环境,这个环境称为容器,这样可完美规避不同应用间的冲突,实现同设备下不同环境需求的多应用部署,或是某个应用的集群部署,保证服务平稳运行。

如图所示,部署Nginx集群,并且都成功启动

命令解读

根据Docker hub的官方文档,咱们把Nginx的命令进行完善

docker run -d \
  --name nginx \
  -p 80:80 \
  -v /root/docker/data/nginx/html:/usr/share/nginx/html \
  -e TZ=Asia/Shanghai \ # 凑数的变量,方便演示
  --network inter \ # 胡写的,方便演示
  nginx

docker run -d : 创建并运行一个容器,-d表示让容器以后台模式运行

--name nginx : 为容器命名,完全看个人喜好,但必须是唯一的

-p 80:80 : 设置端口映射

  • 容器为隔离环境,外界不可访问。将容器的80端口映射到宿主机的80端口,这允许从宿主机访问容器内运行的服务。
  • 容器内端口由容器内的进程决定,而宿主机端口则可以任意指定,例如-p 90:80
  • -p 宿主机端口:容器内端口,示例中就是将宿主机的80映射到容器内的80端口

-e TZ=Asia/Shanghai : 配置容器内进程运行时的一些参数,我们称为环境变量

  • 格式:-e KEY=VALUE,KEY和VALUE都由容器内进程(作者)决定
  • TZ=Asia/Shanghai是设置时区;MYSQL_ROOT_PASSWORD=123是设置MySQL默认密码
  • 官方文档可能包含必须变量和可选变量,部署前仔细阅读

--network inter : 定义容器的网络连接类型,这个咱们放在最后的网络部分讲

nginx : 设置镜像名称,Docker会根据这个名字搜索并下载镜像

  • 格式:repository:tag,例如nginx:1.1,其中REPOSITORY可以理解为镜像名,TAG是版本号
  • 在未指定TAG的情况下,默认是最新版本,也就是mysql:latest
  • 以上为官方镜像格式,若想要拉取用户自建镜像,格式为username/my-custom-image:version,例如ydxian/nginx:1.1.0,通常ydxian/nginx也默认为最新版本
  • 当然不同镜像由于作者配置不同,胡乱填写可能导致部署失败,还请阅读安装手册

Docker 常见命令

命令就是为了去操作镜像和容器,不过无需硬记忆

所有命令见官方文档:https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec#YCejdEwpyo2hxRxpDx4cFFkDnQg

命令

释义

命令

释义

docker pull

拉取镜像

docker start

启动指定容器

docker images

查看本地镜像

docker restart

重启指定容器

docker rmi

删除本地镜像

docker rm

移除指定容器

docker run

创建并运行容器

docker ps

显示在运行的容器

docker stop

关闭指定容器

docker ps -a

列出所有容器

docker log

查看容器日志

docker inspect

查看容器详细信息

针对某个容器进行操作时,输入命令 容器名/容器ID前三位即可,例如docker stop nginx或docker stop 024。下图为一些操作演示

数据卷

首先是一些常用命令https://docs.docker.com/reference/cli/docker/volume

命令

释义

docker volume ls

列出所有数据卷

docker volume inspect

查看指定数据卷详情

docker volume create

创建数据卷

docker volume pruen

清除某数据卷

docker volume rm

移除某数据卷

无需死记硬背,控制台可通过docker volume help查看

数据卷是什么

数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁,与上面说过的端口(ports)有那么些类似。

咱们继续以Nginx为例,阅读官方文档可知Nginx有两个关键目录:

/usr/share/nginx/html专门托管静态资源,/etc/nginx/nginx.conf则负责保存配置文件。

那如果想对这两个部分进行配置,我们就得利用数据卷将两个目录与宿主机目录关联,方便操作

创建两个数据卷html和conf,Docker则会帮助我们为这两个数据卷在宿主机创建真实目录,位置为var/lib/docker/volums/html/_data和var/lib/docker/volums/conf/_data

只要是在Linux系统下,var/lib/docker/volums为默认位置,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data

这样一来,容器内的html和conf便会通过两个数据卷与宿主机的对应目录相关联,这便是咱们常说的挂载。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理

根据上文,咱们重新对Nginx进行部署:

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

Web输入http://localhost:80或http://host-ip:80出现以下界面

接着进行演示

docker volume ls

# 列出所有数据卷,出现以下内容
*DRIVER    VOLUME NAME
local     html*

docker volume inspect html

# 显示数据卷的详细信息,Mountpoint为宿主机挂载点
*[
    {
        "CreatedAt": "2024-04-09T13:41:08+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/html/_data",
        "Name": "html",
        "Options": null,
        "Scope": "local"
    }
]*

cd /var/lib/docker/volumes/html/_data
ls

# 列出静态资源文件,出现以下内容
*50x.html  index.html*

cat index.html

# 查看 index.html 文件,所示内容即为我们web端看到的欢迎页面内容
*<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>*

也就是说/var/lib/docker/volumes/html/_data与html数据卷完成了映射,html再与/usr/share/nginx/html映射,最终就实现了/var/lib/docker/volumes/html/_data与/usr/share/nginx/html间的映射。

结合图片更为明显

为了更进一步进行验证,咱们对index.html进行魔改,看看效果怎样。接着在这个目录下,输入以下命令:

vim index.html

修改后的代码如下,加了点花活

<!DOCTYPE html>
<html>
<head>
<title>Welcome to YDXian!</title>
<style>
html { color-scheme:light dark;}
body { width: 35em; margin: 0 auto;
font-family:Tahoma,Verdana, Arial,sans-serif;}
</style>
</head>
<body>
<h1>Welcome to YDXian!</h1>
<p><font color=#FC0003>A</font><font color=#F90006> </font><font color=#F60009>b</font><font color=#F3000C>r</font><font color=#F0000F>a</font><font color=#ED0012>i</font><font color=#EA0015>n</font><font color=#E70018> </font><font color=#E4001B>i</font><font color=#E1001E>s</font><font color=#DE0021> </font><font color=#DB0024>a</font><font color=#D80027> </font><font color=#D5002A>g</font><font color=#D2002D>o</font><font color=#CF0030>o</font><font color=#CC0033>d</font><font color=#C90036> </font><font color=#C60039>t</font><font color=#C3003C>h</font><font color=#C0003F>i</font><font color=#BD0042>n</font><font color=#BA0045>g</font><font color=#B70048>,</font><font color=#B4004B> </font><font color=#B1004E>b</font><font color=#AE0051>u</font><font color=#AB0054>t</font><font color=#A80057> </font><font color=#A5005A>i</font><font color=#A2005D>f</font><font color=#9F0060> </font><font color=#9C0063>y</font><font color=#990066>o</font><font color=#960069>u</font><font color=#93006C> </font><font color=#90006F>h</font><font color=#8D0072>a</font><font color=#8A0075>v</font><font color=#870078>e</font><font color=#84007B> </font><font color=#81007E>b</font><font color=#7E0081>i</font><font color=#7B0084>g</font><font color=#780087> </font><font color=#75008A>b</font><font color=#72008D>r</font><font color=#6F0090>e</font><font color=#6C0093>a</font><font color=#690096>s</font><font color=#660099>t</font><font color=#63009C>s</font><font color=#60009F>,</font><font color=#5D00A2> </font><font color=#5A00A5>y</font><font color=#5700A8>o</font><font color=#5400AB>u</font><font color=#5100AE> </font><font color=#4E00B1>c</font><font color=#4B00B4>a</font><font color=#4800B7>n</font><font color=#4500BA> </font><font color=#4200BD>d</font><font color=#3F00C0>o</font><font color=#3C00C3> </font><font color=#3900C6>w</font><font color=#3600C9>i</font><font color=#3300CC>t</font><font color=#3000CF>h</font><font color=#2D00D2>o</font><font color=#2A00D5>u</font><font color=#2700D8>t</font><font color=#2400DB> </font><font color=#2100DE>o</font><font color=#1E00E1>n</font><font color=#1B00E4>e</font><font color=#1800E7>.</font></p>
<p>For online cumentation and support please refer to
<a href="https://blog.ydxian.xyz/">blog.ydxian.xyz</a>.<br/>
Commercial support is available at
<a href="https://blog.ydxian.xyz/">blog.ydxian.xyz</a>.</p>

<p><em>HAVE A NICE DAY !!!</em></p>
</body>
</html>

保存后退出,再刷新Web界面,结果符合预期

挂载

对于挂载,小伙伴们应该就很熟悉了吧!把上面的数据卷搞明白,那便是轻轻松松!

# 挂载命令格式,必须以 / 或 ./ 起始
-v 本地目录:容器目录
-v 本地文件:容器文件
# 举例,假设我们所在的宿主机目录为 /root/docker/data/nginx
-v html:/usr/share/nginx/html # 此处冒号左侧 html 会被识别成数据卷
-v ./html:/usr/share/nginx/html # ./ 表示当前目录下的 html 目录,若不存在,Docker会自动创建
-v /root/docker/data/nginx/html:/usr/share/nginx/html # 宿主机上的绝对路径,可将宿主机的静态数据直接提供给Nginx,也是最常用且方便的形式

那么我们为什么要把容器内目录挂载到指定的本地目录呢?原因有以下几点:

  • 数据卷的目录机构较深,前面咱们也看到/var/lib/docker/volumes/html/_data这个目录又臭又长,每次操作起来非常麻烦!
  • 对于有些Docker项目,若不主动挂载,也会自动生成一个数据卷,一大串长字符那种

看看我威联通NAS自动生成的数据卷!

接下来进行演示,利用上文教程,咱们把nginx卸载重新安装

mkdir -p /root/docker/data/nginx/html

docker run -d --name nginx -p 80:80 -v /root/docker/data/nginx/html:/usr/share/nginx/html nginx

# 此时我们若Web访问,会出现403报错,因为宿主机目录下为空,需要我们自行提供静态数据

cd /root/docker/data/nginx/html

ls

# 创建文件,把之前的拷贝进去并保存退出

vim index.html

ls

# 看到新建文件成功,此时再刷新Web界面,就可再次看到页面

操作流程图片展示

起初无内容时的Nginx界面

在原来基础上把YDXian改成了QNAP

再次刷新界面

最后很重要的一点,如果我们挂载配置数据等文件,要提前准备好相应目录及文件;若未备好,执行命令后,Docker仅会自动创建名为nginx.conf的文件夹并报错

-v /root/docker/data/nginx/nginx.conf:/etc/nginx/nginx.conf

网络

网络嘛,顾名思义,咱们在命令解读部分稍微提到过。
常用类型有三种:bridge、host和自定义;

Bridge:

为通常默认的网络类型,若不额外设置,容器会连接到这个网络。它是一个私有的内部网络,容器间可以互相通信,主机也可以与容器通信。

Host

移除容器和Docker主机之间的网络隔离,容器直接使用宿主机的IP地址和网络端口,这意味着不需要额外的端口映射。使用--network host可以提高性能,并允许容器监听主机网络上的端口。例如大家都在用的Emby等流媒体服务。

自定义

对于咱们休闲玩家来说,基本不会这样做,如果容器间需要互相调用,若出现问题,可尝试选择此法。要事先命名并创建新网桥,例如docker network create inter,再输入docker network connect inter 容器名让其它加入。这样便可实现加入inter网络的容器间相互访问,并支持直接通过容器名访问,无需知晓IP

Nginx的IP地址为172.17.0.2

查看另一容器信息,IP地址为172.17.0.3

这就表示两个容器处在同一个网段,想一下咱们家里的局域网设备,同一路由器/交换机下的设备是不是也能够互相访问?

但有些疑惑,前面说过各个容器不是相互独立吗,为啥还能在同一网段?

细心的小伙伴可能已经发现,它们都有相同的网关172.17.0.1,看过我之前教程分享的朋友,有没有觉得这个IP很熟悉?没错,我们做反代经常会用到它!

其实在我们安装Docker那一刻起,它便会自动在设备中安装一个虚拟网卡docker 0,并且还会为这个虚拟网卡创建一个虚拟网桥,用于容器与宿主机间的通信。它的地址为172.17.0.1/16,172.17.0.1是docker0接口的IP地址,/16表示子网掩码,定义了IP地址范围是172.17.0.0到172.17.255.255。

注:以上只是大多数情况,具体的IP地址范围可能会因安装和配置不同而有所变化。

ifconfig
ip addr show docker0

关于自定义,因使用场景不多,这里仅简单演示

docker network create inter

network connect inter nginx

network connect inter emby

可以看到,初始的Nginx多出了一个名为inter的网络

若此法解决不了,建议先使用docker logs 容器名检查容器日志,了解错误详情;或使用docker exec -it 容器名 bash(或sh)进入容器内部,然后使用curl或其它工具测试容器间的网络连接。

Docker Compose

docker compose可帮助我们实现多个相互关联的docker容器的快速部署,这是它的一大优势。

通过威联通官方docker管理工具Container Station用此种方式部署也是很舒服滴

粘贴进YAML代码后,若指令有误,系统不会允许创建操作,根据提示排错完毕后才能进行创建。而且会进行提示,咱们逐一排错即可~下图中其实是environment后少了个:

这便是品牌NAS的好处之一,便利性高!

笔者日常也更喜欢通过这种方式进行部署,基本语法可以参考官方文档:https://docs.docker.com/compose/compose-file/compose-file-v3

与Docker run对比

docker-compose文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于service就是在定义某个应用的运行时参数,因此与docker run参数非常相似。

# docker run部署
docker run -d \
  --name nginx \
  -p 80:80 \
  -e TZ=Asia/Shanghai \
  -v /root/docker/data/nginx/html:/usr/share/nginx/html \
  --restart=always \
  --network inter\ # 自定义网络
  nginx

很多情况下部署失败是格式没对齐、漏空格、多/少符号导致

# docker compose部署
version: "3"

services:
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "80:80"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - /root/docker/data/nginx/html:/usr/share/nginx/html
    restart: always
    networks: # 若为默认桥模式,从这往下全部删除
      - news
networks:
  news:
    name: inter

常见对应关系

docker run

docker compose

释义

nginx

image: nginx

指定镜像版本

-p

ports

端口映射

-e

environment

设置环境变量

--name

container_name

指定容器名,唯一

--network

networks

将容器连接到指定网络

-v

volumes

卷映射,宿主机目录/文件映射至容器

--restart always

restart: always

设置重启策略

--env-file

env_file:

从文件加载环境变量

no

depends_on:

docker compose特有

大致部署流程

准备工作都差不多,如下

mkdir -p /root/docker/data/nginx  # 创建nginx文件目录

cd /root/docker/data/nginx # 进入该目录下

mkdir html # 创建要挂载的宿主机目录

cd html # 进入html目录下

vim index.html # 准备静态数据文件,保存后退出

cd .. # 返回上级目录,回到nginx下

vim docker-compose.yml # 在nginx下创建 .yml 文件

# 将上面代码粘贴进去后保存并退出

docker-compose up -d # 启动

执行vim docker-compose.yml后,如需编辑,英文状态下,按i可进行编辑,编辑完成后,按Esc返回正常模式,然后同时按下Shift和:,输入wq(写入并退出)或:q!(不保存退出),按下回车键即可退出.

最后

其实大部分Docker应用的部署都不算难~基础知识搞个差不多,部署时再多看看官方手册,很多答案都在那里,亲手操作个四五把就差不多咧。

祝大家玩的开心,咱们下期再见!

相关推荐

利用navicat将postgresql转为mysql

导航"拿来主义"吃得亏自己动手,丰衣足食...

Navicat的详细教程「偷偷收藏」(navicatlite)

Navicat是一套快速、可靠并价格适宜的数据库管理工具,适用于三种平台:Windows、macOS及Linux。可以用来对本机或远程的MySQL、SQLServer、SQLite、...

Linux系统安装SQL Server数据库(linux安装数据库命令)

一、官方说明...

Navicat推出免费数据库管理软件Premium Lite

IT之家6月26日消息,Navicat推出一款免费的数据库管理开发工具——NavicatPremiumLite,针对入门级用户,支持基础的数据库管理和协同合作功能。▲Navicat...

Docker安装部署Oracle/Sql Server

一、Docker安装Oracle12cOracle简介...

Docker安装MS SQL Server并使用Navicat远程连接

...

Web性能的计算方式与优化方案(二)

通过前面《...

网络入侵检测系统之Suricata(十四)——匹配流程

其实规则的匹配流程和加载流程是强相关的,你如何组织规则那么就会采用该种数据结构去匹配,例如你用radixtree组织海量ip规则,那么匹配的时候也是采用bittest确定前缀节点,然后逐一左右子树...

使用deepseek写一个图片转换代码(deepnode处理图片)

写一个photoshop代码,要求:可以将文件夹里面的图片都处理成CMYK模式。软件版本:photoshop2022,然后生成的代码如下://Photoshop2022CMYK批量转换专业版脚...

AI助力AUTOCAD,生成LSP插件(ai里面cad插件怎么使用)

以下是用AI生成的,用AUTOLISP语言编写的cad插件,分享给大家:一、将单线偏移为双线;;;;;;;;;;;;;;;;;;;;;;单线变双线...

Core Audio音频基础概述(core 音乐)

1、CoreAudioCoreAudio提供了数字音频服务为iOS与OSX,它提供了一系列框架去处理音频....

BlazorUI 组件库——反馈与弹层 (1)

组件是前端的基础。组件库也是前端框架的核心中的重点。组件库中有一个重要的板块:反馈与弹层!反馈与弹层在组件形态上,与Button、Input类等嵌入界面的组件有所不同,通常以层的形式出现。本篇文章...

怎样创建一个Xcode插件(xcode如何新建一个main.c)

译者:@yohunl译者注:原文使用的是xcode6.3.2,我翻译的时候,使用的是xcode7.2.1,经过验证,本部分中说的依然是有效的.在文中你可以学习到一系列的技能,非常值得一看.这些技能不单...

让SSL/TLS协议流行起来:深度解读SSL/TLS实现1

一前言SSL/TLS协议是网络安全通信的重要基石,本系列将简单介绍SSL/TLS协议,主要关注SSL/TLS协议的安全性,特别是SSL规范的正确实现。本系列的文章大体分为3个部分:SSL/TLS协...

社交软件开发6-客户端开发-ios端开发验证登陆部分

欢迎订阅我的头条号:一点热上一节说到,Android客户端的开发,主要是编写了,如何使用Androidstudio如何创建一个Android项目,已经使用gradle来加载第三方库,并且使用了异步...

取消回复欢迎 发表评论: