我会通过用Docker部署一个Node.js编写的web应用程序,来深入地理解Docker容器的本质。

一、准备工作

在开始前,需要在你的Mac电脑中安装Docker。在官方网站上有各种环境下的安装指南,用Mac电脑的就看Install Docker Desktop on Mac

安装Docker

安装步骤非常简单:

  1. 如果是M1芯片的arm64架构,就下载Docker for Mac with Apple silicon

  2. 双击Docker.dmg文件,然后把鲸鱼图标拖放到Applications文件夹即可。

运行Docker

在应用中找到Docker图标,点击运行。

运行后,在菜单栏会看到多了一个鲸鱼图标:

然后,在终端用命令查下Docker的版本:

docker --version

再查下docker info是不是也正常。如果都正常,就可以用Node.js编写web应用了。

在这里,我是用Nestjs写的应用程序,代码非常简单。也就是用Nestjs的cli工具生成的,创建应用的这一步就直接跳过了,直接上代码:

// app.controller.ts部分
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service'; @Controller()
export class AppController {
constructor(private readonly appService: AppService) {} @Get()
getHello(): string {
return this.appService.getHello();
}
} // app.module.ts部分
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service'; @Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {} // app.service.ts部分
import { Injectable } from '@nestjs/common'; @Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
} // main.ts部分
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module'; async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

在上面的代码中,就是用Nest框架启动了一个Web服务器,只有一个简单的功能是:打印出“Hello World!”。

那么,将这样的一个应用程序容器化,第一步是制作容器镜像。

二、Docker的配置文件:Dockerfile

首先,我们在这个Nestjs的应用程序的根目录下创建一个文本文件,文件名是:Dockerfile,没有扩展名的。

# 使用官方提供的Node.js开发镜像作为基础镜像
FROM node:22-slim # 工作目录切换为 /usr/src/app
WORKDIR /usr/src/app # 将 package.json复制到当前目录下
COPY package.json ./ RUN npm config set registry https://registry.npmmirror.com/
# 使用npm命令安装这个应用所需要的依赖
RUN npm install RUN npm install -g pnpm COPY . . # 暴露给外界访问容器3000端口
EXPOSE 3000 # 设置容器进程为:pnpm run start:dev,即:这个Node应用开发环境的启动命令
CMD ["pnpm", "run", "start:dev"]

通过Dockerfile的内容,可以看到是用一些标准的大写词语来描述Docker镜像。这些大写的词语就是按上面内容顺序来处理的。

三、制作Docker镜像

接下来,可以用Docker制作这个应用的镜像了,在当前目录执行:

docker build -t nestjs-app .

这个-t是给这个镜像加tag,也就是起个名儿。docker build会自动加载当前目录中的Dockerfile,然后按照里面的顺序一个个的执行其中的大写词语。在这个过程里面,实际上就等同于Docker使用基础镜像启动了一个容器,然后在这个容器中一个个执行Dockerfile中的大写词语。

在每次执行后,都会生成一个对应的镜像层。

Docker build操作完成后,可以用 docker image命令查下结果:

docker image ls 

REPOSITORY           TAG                     IMAGE ID       CREATED         SIZE
nestjs-app latest 2badda7aef21 2 hours ago 1.11GB

四、使用Docker镜像启动容器

使用这个镜像,用docker run命令来启动容器:

docker run nestjs-app

在镜像名的后面,什么都不用写,这是因为在Dockerfile中已经指定CMD了,不然,就得把进程的开发环境启动命令加在后面:

docker run -p 3000:8080 nestjs-app pnpm run start:dev

在容器启动了之后,可以用docker ps命令看一下:

docker ps

CONTAINER ID   IMAGE               COMMAND                   CREATED
8015b4eac7eb nestjs-app "docker-entrypoint.s…" 23 seconds ago

在这个命令中,我通过-p 3000:8080告诉Docker,把容器中8080端口映射到宿主机的3000端口。

这样,访问宿主机的3000端口,就可以看到容器中应用程序返回的结果:

这是VSCode中的插件 Thunder client,类似用curl http://localhost:3000

这样,已经使用容器完成了一个web应用的开发与测试。

五、总结

这里我用了一个Node.js应用作为实例,讲解了Docker容器使用的主要场景。熟悉了这些操作,也就基本摸清了Docer容器核心功能。

在容器进程“pnpm run start:dev”,是进行在由Linux Namespace和Cgroups构成的隔离环境中;运行它所需要的各种文件,由挂载在rootfs层了。

白话Docker系列(二):用Web应用实例深入容器的更多相关文章

  1. [知识库分享系列] 二、Web(高性能Web站点建设)

    知识库分享系列: [知识库分享系列] 二..NET(ASP.NET) [知识库分享系列] 一.开篇 分享介绍 此知识库之所以为 Web 系列,因为和 .NET 没有完全的关系,其中的技术和实践实用于各 ...

  2. Docker系列二: docker常用命令总结

    https://docs.docker.com/reference/  官方命令总结地址 容器生命周期管理 1.docker run 创建一个新的容器并运行一个命令 docker run [optio ...

  3. Docker系列(二):Docker基础命令

    docker的部署安装(Linux kernel至少3.8以上): yum install docker docker1.8安装:(下面 是两个命令) # cat >/etc/yum.repos ...

  4. Docker系列(7)- 常用命令(3) | 容器命令

    容器命令 说明: 有了镜像才可以创建容器:下载一个centos镜像进行练习,相当于在Linux里面再见一个Linux虚拟机 [root@localhost ~]# docker pull centos ...

  5. Docker 系列二(操作镜像).

    一.镜像管理 1.拉取镜像 docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] -- Docker 镜像仓库地址 :一般是 域名或者IP[:端口号 ...

  6. ActiveMQ入门系列二:入门代码实例(点对点模式)

    在上一篇<ActiveMQ入门系列一:认识并安装ActiveMQ(Windows下)>中,大致介绍了ActiveMQ和一些概念,并下载.安装.启动他,还访问了他的控制台页面. 这篇,就用代 ...

  7. Docker系列(二)组件介绍

    镜像 镜像是一个只读的模版,可以用来创建Docker容器. 容器 Docker利用容器来运行应用,容器是从镜像创建的运行实例.它可以被启动.开始.停止.删除.每个容器都是互相隔离的,保证安全的平台.可 ...

  8. Docker系列二:Docker的基本结构

    Docker的基本结构 Docker 的三大基础组件 Docker有三个重要的概念:仓库 , 镜像 和 容器 ,它们是Docker的三大基出组件 Docker的组织结构 Docker处于操作系统和虚拟 ...

  9. windows下部署.netcore+docker系列二 (unbuntu 18.4 下 安装 docker)亲测!!!

    1.卸载sudo apt-get remove docker docker-engine docker.io containerd runc2.更新sudo apt-get update3.安装依赖包 ...

  10. Docker系列七: 使用Humpback管理工具管理容器(一款UI管理工具)

    Humpback 可以帮助企业快速搭建轻量级的 Docker 容器云管理平台,若将你的 Docker 主机接入到 Humpback 平台中,就能够为你带来更快捷稳定的容器操作体验. 功能特点 Web操 ...

随机推荐

  1. 【SQL周周练】一千条数据需要做一天,怎么用 SQL 处理电表数据(如何动态构造自然月)

    大家好,我是"蒋点数分",多年以来一直从事数据分析工作.从今天开始,与大家持续分享关于数据分析的学习内容. 本文是第 6 篇,也是[SQL 周周练]系列的第 5 篇.该系列是挑选或 ...

  2. 知识蒸馏 -- 定位蒸馏LD

    定位蒸馏 定位蒸馏:Localization Distillation,简称LD 论文地址: Localization Distillation for Dense Object Detection ...

  3. C++ ADL 与 模板

    什么是ADL ADL(Argument Dependent Lookup),参数依赖查找,明确的意思是依赖参数的函数查找,即对于函数调用,不仅会依照常规的名称查找规则,还会在函数参数所在的命名空间内查 ...

  4. JVM划重点:引用类型、垃圾回收算法和内存划分

    一.Java四种引用类型    每种编程语言都有操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过"引用"(Reference).在 Java ...

  5. 玩转AI新声态 | 玩转TTS/ASR/YuanQI 打造自己的AI助手

    前言 halo, 各位佬友这是我24年写的整理一下发出来, 可能有点老了, ai发展这么快...... 本次带来的是腾讯云玩转AI新声态语音产品应用实践,利用 TTS / ASR / 元器智能体 打造 ...

  6. .net入行第4年

    没错 我在2024-06-28发布了我的三年.net感想 时隔一年,我又来分享了 这一年的时间真的没有经过逛博客园 ,每天都在忙 首先,恭喜一下自己 -- 我现在也算是一个小老板了(虽然主业还是程序员 ...

  7. 超实用!手把手教你Dify版本升级

    很多情况下,我们需要升级 Dify 版本以获得新的功能和性能的提升,同时还能确保系统的安全性.稳定性和兼容性,从而更好地满足用户的需求. 那问题来了,怎么升级 Dify 版本呢? 接下来,我们以 Do ...

  8. 数据库的DML与DQL语句

    1: DML语句 ​ insert into values 1 insert into 表 values(值1,值2,值n); 2 insert into 表(字段1,字段2,字段n) values( ...

  9. FlashAttention安装失败的一种可能的原因,nvcc -V与nvidia-smi显示的CUDA版本号不一样

    $ pip install flash-attn --no-build-isolation 报错 RuntimeError: FlashAttention is only supported on C ...

  10. ChatMoney:你的短视频脚本制作利器

    本文由 ChatMoney团队出品 在当今这个快节奏的数字时代,短视频以其短小精悍.内容丰富的特点迅速崛起,成为大众娱乐和信息传播的重要载体.然而,对于许多创作者而言,如何构思一个引人入胜.富有创意的 ...