一次简单的 Docker 使用
在 Docker 中,镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 要在 Docker 中运行开发 Ghost 需要按照以下步骤: 1. 拉取 Node.js 指定版本镜像; 2. 启动容器,挂载本地目录,暴露出容器的端口; 3. 进入容器,新建用户和用户目录; 4. 安装 Ghost 并运行;

前言
背景
由于最近要使用 Ghost
开发一个官网,想在本地安装来做开发。但是在安装的过程中提示 Node.js
运行时版本不支持当前的 12 版本,因此无法安装。当然,也可以通过 nvm
或者 HomeBrew
来调整 Node.js
的版本,但是由于当前也正在开发别的项目,也用到了 Node.js
运行时。为了不影响其他项目的开发,因此想使用 Docker
来解决当前存在的问题。
环境
- Ghost:2.26;
准备工作
- 安装好
Docker
;
预备知识
镜像(Image)
和 容器(Container)
的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
具体步骤
拉取指定 Node.js
版本镜像
$ docker pull node:10
启动容器
具体操作
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
因为 Docker
的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。
$ docker run -p 2368:2368 -v /Users/mehunk/Documents/Dev/Demo/ghost:/ghost -d --name ghost node:10
-p
的意思是,将容器2368
端口映射到宿主机的2368
端口(前面是宿主机端口,后面是容器端口);-v
的意思是,宿主机/Users/mehunk/Documents/Dev/Demo/ghost
的目录映射到容器/ghost
目录上;-d
是指让当前的容器在后台运行;--name
是指将给当前的容器命名,否则要使用当前容器,就需要使用自动生成的一长串字符串了;
原理
当利用 docker run
来创建容器时,Docker
在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
- 利用镜像创建并启动一个容器;
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层;
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
- 从地址池配置一个 ip 地址给容器;
- 执行用户指定的应用程序;
- 执行完毕后容器被终止;
在镜像中安装 Ghost
启动容器以后需要进入到容器中。
$ docker exec -it ghost bash
- 只用
-i
参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回; - 当
-i
-t
参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符;
新建用户
由于 Ghost
安装不能使用 root
用户,需要新建一个其他用户。
# 新建用户组
$ groupadd -r oni
# 新建用户
$ useradd -r -g oni oni
# 创建用户目录
$ mkdir /home/oni
$ chown oni:oni /home/oni
安装 Ghost
# 全局安装 ghost-cli
$ npm install [email protected] -g
# 切换到新建的 oni 用户,并进入到要安装的目标文件夹
$ su oni && cd /ghost
# 使用 ghost-cli
$ ghost install local
为了能够让宿主机访问到容器里面运行的 Ghost
应用,需要修改 Ghost
配置文件,将绑定的 ip 地址从 127.0.0.1
修改为 0.0.0.0
。
然后重启应用。
这时就可以在宿主机的浏览器输入 http://locahost:2368/ghost
打开刚刚启动的 Ghost
应用了。
常用命令
# 列出所有本地镜像
$ docker image ls
# 删除镜像文件
$ docker image rm [imageName]
# 列出所有本地正在运行的容器
$ docker container ls