Zonebit

个人的奋斗还是历史的进程?

View the Project on GitHub

4 March 2025

docker镜像从打包到部署123

by ganlyun

前言

docker,作为现今互联网应用的地基其重要性不言而喻,本文主要通过实践操作对docker镜像的打包部署加深了解

在这之前,需要先明确2个概念

  1. 镜像
  2. 容器

镜像是静态的容器,他们之间的关系类似类和实例,通过镜像可以生成实例,这就可以保证每个容器在刚生成时是一致的,比如我们通过bash操作在一个容器的根路径执行了rm -rf这样的毁天灭地的命令,然后容器再也进不去了,只需要删除它,然后从镜像重新启动一个即可

了解了docker镜像和容器的关系,就知道我们需要做什么:

基于自己的app打包镜像 -> 新环境导入镜像 -> 从镜像生成容器实例让app运行

step1: 准备一个web应用

首先我们需要一个web应用,我使用的是基于nodejs+express的一个静态导航页面,这一步可以说是最简单的,让express充当一个静态资源服务器

step2: 准备环境

因为我的操作设计两台机器,一台win服务器(没有联网(大坑)),一台linuxPC,所以需要先给两台设备都装上docker

docker官网上推荐你直接下载对应平台的docker-desktop——一个集成了所有docker相关操作的GUI,商业味儿十足

好处是安装足够简单,坏处是——商业味儿十足

在联网的环境下,desktop很好使,安装基本不会遇到任何问题,很快就可以跑起来

在不联网的机器就有点麻烦,desktop不但提供不了便利,而且还变成了阻碍,过程按下不表,这个时候我们就需要直接安装docker-engine

==因为服务器是win平台,必须借助wsl才能运行linux镜像==,所以我们可以直接在wsl中安装linux版本的docker-engine

重点从这里开始


线内操作可跳过

访问离线包下载地址(noble是指ubuntu24,x86架构64位)

下载下来的是一堆deb文件,用U盘拷到服务器上以后,在wsl上执行

# 服务器wsl
sudo dpkg -i *.deb

不出意外的话,终端会报错说缺一些依赖


这时候我们就需要下面这个工具

# linuxPC
# 安装apt-rdepends依赖,这个依赖可以列出你安装软件的依赖
sudo apt-get install apt-rdepends

# 通过这个命令下载所有的依赖
apt-rdepends docker-ce | grep -v "^ " | xargs apt-get download

还是一些deb文件,用U盘拷到服务器上以后,在wsl上执行

# 服务器wsl
sudo dpkg -i *.deb

这个时候,不出意外docker就搞定了,通过下面命令检查是否安装成功

# 服务器wsl
docker --version

step3: 镜像打包

因为我的代码都在服务器上,所以我需要在服务器上执行镜像打包操作

新建一个Dockerfile放在web项目的根路径

# 使用官方 Node.js 镜像作为基础镜像,形式是 名称:标签
FROM node:18-slim

# 设置工作目录
WORKDIR /app

# 将项目代码复制到工作目录
COPY . .

# 安装项目依赖
RUN npm install

# 暴露应用的端口(根据你的应用修改)
EXPOSE 3000

# 定义容器启动时运行的命令
CMD ["node", "index.js"]

每条指令的含义都很清晰,但是现在缺少基础镜像,在linuxPC通过命令或者界面可以下载到node:18-slim

docker pull node:18-slim

之后用命令导出为一个tar包

docker save node:18-slim node18_slim.tar

在服务器上导入

docker load -i node18_slim.tar

然后就可以执行打包镜像的命令了

# hang123是web应用项目的名称,latest是默认的标签名称,可以自行修改
docker build -t hang123:latest .

打包的过程中会执行npm install命令,所以如果是离线机器的话,还需要解决依赖问题,可以直接将node_modules拷贝到项目里,确保安装成功

step4: 运行容器

打包完成以后就可以用镜像来跑容器实例了

# -d 是指后台运行
# -p 配置端口映射,这里需要跟Dockerfile里面配置的暴露端口一致,宿主机端口也设置了3000,可以自行修改
# --name 容器名称,如果不配置,会随机生成一个
# 最后的参数就是镜像名称了
docker run -d -p 3000:3000 --name hang123 hang123:latest

执行成功的话,浏览器就可以通过宿主机IP的3000端口成功访问了

撒花

总结

在跟docker互动的过程中,所有的操作基本都是围绕镜像和容器展开的,所以先理解概念很重要

后续一些常用的操作,比如镜像的导入导出,通过commit从容器生成镜像,容器和宿主机之间拷贝文件,都是有必要熟悉了解的

下一步,可以学习下k8s

tags: docker镜像打包 - 离线安装 - 容器化部署 - nodejs - express