前端对Docker简单了解

Docker

1. 是什么?

在计算机上的隔离环境中运行应用程序:node app,react app Mogodb等

2. 目的

在他人电脑上,提供与自己开发一致的环境

理解这三个东西就够了

三者关系

镜像是什么?

Images 镜像 是独立的,如果修改了内容,需要构建一个全新的镜像

镜像里包括了应用程序运行所需的一切。

镜像是由多层组成的,多层的叠加

容器是什么?

一个容器Container(隔离进程,执行程序)分享镜像

卷是什么?

把本地或者一些资源映射到容器中,实现热更新等

举个例子

例子说明

我需要用node写个接口,在浏览器上访问localhost:4000/时,可以看到相关内容

准备

javascript 复制代码
一: 创建文件夹api
二: npm init
一直敲回车,创建出了pakejson.json文件
三: 安装包 npm install --save cors express
四: 创建app.js件,内容如下
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
app.get('/', (req, res) => {
  res.json([
    {
      "id":"1",
      "title":"Book Review: The Bear & The Nightingale.ABCD"
    },
    {
      "id":"2",
      "title":"Game Review: Pokemon Brillian Diamond"
    },
    {
      "id":"3",
      "title":"Show Review: Alice in Borderland"
    }
  ])
})
app.listen(4000, () => {
  console.log('listening for requests on port 4000')
})

先别急,我们先想一下,如果你现在是从git上面拉取的这个项目你会想要,实现这个例子,怎么做?

  1. 确保自己电脑有node

  2. npm install 去安装包

  3. node app.js 运行该文件

  4. 访问localhost:4000

那么接下来,我们用docker来做这些事情。

docker相关操作

前提准备

1. Docker Desktop

所有镜像操作,都得打开此软件进行

2. 项目里加入Dockerfile文件

里面表明了构建镜像要做哪些事情

需要在项目下创建Dockerfile文件,如果使用VSCode,可以安装docker插件

Dockerfile文件就是创建镜像的关键文件,值得注意的是,你还需要启动 Docker Desktop软件

javascript 复制代码
#FROM 指令是 Dockerfile 中的第一条指令,
#它为后续命令(如 RUN、COPY)设定了基础环境。
#最好指定运行的版本,保证了稳定的输出
FROM node:20.19.6

#指定后面的工作目录
WORKDIR /app

#复制文件
COPY package.json .

#安装包
RUN npm install

#第一个.是复制源文件的相对目录,第二个.是复制到镜像中的路径,镜像是有自己的结构的
COPY . .

#容器暴露出的接口
EXPOSE 4000

#运行指令
CMD ["node", "app.js"]

3. 最好加入.dockerignore

COPY复制源文件时,忽略复制一下的文件、文件夹

javascript 复制代码
node_modules

*.md

创建镜像

在Dockerfile文件的根目录下,执行docker相关指令

构建镜像 -t tag的意思 . 是Dockerfile的根路径

myapp2就是镜像名称,你要是想同一镜像名,不同的版本的话

myapp2:v1 如图Tag就会显示v1,如果你不加,Tag就会显示latest,表示这就是最新版本

javascript 复制代码
docker build -t myapp2 .

如图所示,构建镜像成功了

创建容器

这是在软件上操作

用docker指令操作

docker run 是创建并运行容器的意思,每次执行都是创建一个新的容器

-p 4000:4000 端口port 把本地的4000端口映射到容器的4000,没有这一步,在浏览器上可访问不到

-d detached 分离模式 独立于后台运行长期驻守的服务,不受其他干扰

myapp2是上面创建的镜像的名称

javascript 复制代码
docker run --name myapp_c1 -p 4000:4000  -d myapp2

ok,到这一步,你就可以去访问

localhost:4000

试一试效果,发现也可以访问

接下来,我们试着改变app.js内容,看能浏览器能不能同步更新

我们会发现没有及时更新,这是因为我们创建了一个镜像,这个镜像就是一个独立的只读的内容,容器根据镜像创建出独立的运行环境,当然不会发生改变。

做法: 删除镜像容器,重新创建新的镜像容器

弊端:每次npm install会很耗时

如果不使用镜像,在本地实现,实时更新怎么做?

node要是实时更新,我们在本地安装全局的nodemon

执行nodemon app,js 实现接口实时更新

使用docker怎么做?

  1. 安装nodemon

  2. 卷可以解决这个问题
    接下来我们要修改一下Doderfile文件和package.json文件

javascript 复制代码
Dockerfile文件如下

FROM node:20.19.6

RUN npm config set registry https://registry.npmmirror.com

RUN npm install -g nodemon

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 4000

CMD ["npm", "run","dev"]

----------------------------------------------------------------------------------
package.json的scripts的dev的命令,发生改变

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon -L app.js",
}

层缓存

还有一个点,Dockerfile文件的命令是一层一层往下读的,有执行的顺序

如果执行时没有发生改变,就会拿缓存内容,这样可以提高效率

如果有行命令读取到,你做出了改变,那么接下来的执行工作,都会重新执行

所以你会发现为什么会单独先COPY package.json,再安装包,再复制其他的源文件

如果你只是改变了app.js内容,包没有发生改变,如果Copy . .在前,它发现app.js发生改变后,就会把后面每层的指令重新执行,那么每次都会重新安装包,效率就会下降。
好了理解这个后,我们再来说卷,如果说把本地下的文件都放在卷里,卷再映射给容器,卷更新,容器 就会更新

需要映射到容器文件的绝对路径 -v Volumes 代表着卷

--rm 移除,当停止容器时,就删除容器等

-v C:\Users\luback\Desktop\docker\api:/app

// Dockerfile的绝对路径的上级:容器工作路径

-v /app/node_modules

//创建并映射容器的匿名卷

那么了解了我们要做什么,我们开始从小在VScode的终端上执行下面操作

创建新镜像

javascript 复制代码
docker build -t myapp2:nodemon .

创建容器,卷

记得把4000:4000映射的容器都给停掉,不然会报错

查看docker容器正在运行的进程

docker ps

根据容器ID/名称停止容器进程

docker stop ContainerID/Names

javascript 复制代码
docker run --name myapp_c_nodemon -p 4000:4000 --rm -v C:\Users\luback\Desktop\docker\api:/app -v /app/node_modules  myapp2:nodemon

欧克,我们再试一下,修改app.js文件内容,发现及时更新了

对镜像,容器,卷有了认知后,你会发现命令好长

docker run --name myapp_c_nodemon -p 4000:4000 --rm -v C:\Users\luback\Desktop\docker\api:/app -v /app/node_modules myapp2:nodemon

又是创建容器,又是映射端口,又是创建卷,又是关联相关镜像

如果是有前后端的项目,多个项目想集中使用,有没有什么办法,使这些指令过程变得更加便捷的方法?

Docker Compose

解决:数据库,前端,后端都启动,并且同时运行所有的容器,使他们相互通讯。

主要是使用.ymal文件,里面记录了所有项目的执行命令,在通过指令,快速实现互通

javascript 复制代码
 // 执行
docker-compose up 

//停止容器,但是镜像和卷会保留下来
docker-compose down

//停止容器且删除镜像
docker-compose down --rmi

// 删除由docker comppose创建的镜像,卷
docker-compose down --rmi all -v

多项目运行,举个例子

我的后端项目接口是localhost:4000

我的前端React项目启动访问地址是localhost:3000

那么如何使用docker,使双方进行通信。

如图的效果

javascript 复制代码
一:在api文件放入命名为docker的文件夹下(随便取的名字)
二:在docker文件的终端上创建一个react前端项目
 npx create-react-app my_book
三:修改my_book src/App.js内容,主要是访问后端接口的数据并展示在页面
import { useEffect, useState } from 'react'
import './App.css';

function App() {
  const [blogs, setBlogs] = useState([])
  useEffect(() => {
    fetch('http://localhost:4000/')
      .then(res => res.json())
      .then(data => setBlogs(data))
  }, [])

  return (
    <div className="App">
      <header className="App-header">
        <h1>all blogs</h1>
        {blogs && blogs.map(blog => (
          <div key={blog.id}>{blog.title}</div>
        ))}
      </header>
    </div>
  );
}

export default App;

四:在my_app下创建Dockerfile文件,这样my_app才能构建镜像,.dockerignore也加上
Dockerfile内容

FROM node:20.19.6
WORKDIR /app
COPY package.json .
RUN npm config set registry https://registry.npmmirror.com
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

.dockerignore内容
node_modules

欧克,api后端项目有了,my_book前端项目有了,在docker文件下,创建一个

docker-compose.yaml 文件

下面是举例的目录

注意首行缩进

services: // 就是执行的命令

api://镜像名称

build: ./api //Dockerfile所在路径,创建镜像

container_name: api_c //创建容器的名称

ports:

  • '4000:4000' //映射端口

volumes: //创建卷

  • ./api:/app

  • /app/node_modules

mybook:

build: ./my_book

container_name: mybook_c

ports:

  • '3000:3000'

stdin_open: true //这两个是开启交互模式

tty: true //意味着访问后端地址可以是 localhost:4000
你会不会思考,前端更新,会不会也需要想后端项目一样去做卷映射?

但是为什么这里的执行命令没有做这步操作

你可以尝试一下,前端页面不会更新的,那是因为,前端项目会打包,浏览器只会读取成静态资源,所有你就算用卷做映射也没用,因为并浏览器读取的静态资源没有变

然后只能每次重新打镜像容器做更新了

如果测试想前端页面做到后端热更新这种,额,我目前还不了解这一块,如果你知道,欢迎留言,相互学习。

好了,回归正题,以下就是docker-compose.yaml的内容

javascript 复制代码
version: '3.8'
services:
  api:
    build: ./api
    container_name: api_c
    ports:
      - '4000:4000'
    volumes:
      - ./api:/app
      - /app/node_modules
  myblog:
    build: ./myblog
    container_name: myblog_c
    ports:
      - '3000:3000'
    stdin_open: true
    tty: true

在docke文件下执行VScode的终端命令

docker-compose up

这一行代码,就可以把构建镜像,容器,卷,端口等系列操作做完

javascript 复制代码
docker-compose up  // 执行
docker-compose down //停止容器,但是镜像和卷会保留下来
docker-compose down --rmi //停止容器且删除镜像
docker-compose down --rmi all -v // 删除由docker comppose创建的镜像,卷

你可以去浏览器访问一下
localhost:4000
localhost:3000

值得注意的是,你可以通过 docker ps 确保运行的容器没有占用端口

最后

如何在Docker Hub上分享镜像

这地址有着很多免费的镜像源,想了解一下,就看看

https://hub.docker.com/https://hub.docker.com/

javascript 复制代码
#创建镜像,注意Vscode执行命令的路径在项目的Docderfile路径上
C:\Users\luback\Desktop\docker\api

docker build -t thnetninjauk/myapi .

#登录 dorcker 账号
docker login

#推送到线上
docker push thnetninjauk/myapi
javascript 复制代码
#可以尝试拉去这个项目的镜像

docker pull thnetninjauk/myapi

常用指令

javascript 复制代码
构建镜像 -t tag的意思 . 是Dockerfile的根路径
docker build -t myapp2 .

查看所有镜像
docker images

运行某镜像,使用image的name,并创建使用容器命名为myapp_c1 run有重新创建的意思
docker run --name myapp_c1  myapp (到这一步,是无法在本地查看的,因为没有指明映射端口)

查看docker容器正在运行的进程
docker ps

根据容器ID/名称停止容器进程
docker stop ContainerID/Names

本地映射端口到容器端口,-p port端口的意思
-d  detached 分离模式 独立于后台运行长期驻守的服务,不受其他干扰
docker run --name myapp_c1 -p 4000:4000  -d myapp


查看所有的容器 -a  all的意思
docker ps -a


重启某容器,这次不需要映射端口,在创建的时候已经是做好了的
docker start ContainerID/Names


删除镜像 rm   remove的意思 -f force强制清除的意思,尽管有容器存在,也会被删除
docker image rm ImageName/ID
docker image rm ImageName/ID -f


删除容器,还可以连着删
docker container rm ContainerID/Name ContainerID2/Name2



删除Docker所有内容,删除所有镜像,删除所有容器,删除所有的卷
docker system prune  -a


为镜像添加版本
docker build -t myapp:v1


运行指定版本的镜像
docker run --name myapp_c -p 4000:4000 myapp:v1


--rm 的标志意味着停止容器的时候就删除它
docker run --name myapp_c_nodemon -p 4000:4000 --rm  myapp:nodemon



需要映射到容器文件的绝对路径 -v 代表着卷
docker run --name myapp_c_nodemon -p 4000:4000 --rm -v C:\Users\luback\Desktop\docker\api:/app  myapp:nodemon



本地不需要的卷,容器却需要的卷,用匿名卷映射给容器
docker run --name myapp_c_nodemon -p 4000:4000 --rm -v C:\Users\luback\Desktop\docker\api:/app -v /app/node_modules  myapp:nodemon
相关推荐
XIAOHEZIcode1 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220702 天前
如何搭建本地yum源(上)
运维
武子康2 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
大树885 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠5 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质5 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工5 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn865 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智5 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_5 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化