我尝试使用Ansible构建Nuxt.js的Docker容器
背景
有几篇博客文章提到在Docker容器中安装Ansible,并使用Ansible安装Docker。但是,使用Ansible Playbook构建Docker容器的文章仍然很少,所以我决定执行Ansible,并将结果作为一篇文章记录下来,以构建Vue.js框架的Nuxt.js Docker容器。
进行
将以下内容编写成Ansible的Playbook,以便执行:
– 获取Docker镜像
– 构建Nuxt.js容器
– 将镜像推送至Docker Hub
关于要构建的Nuxt.js容器的DockerFile,请参考这本技术书籍以进行试验并学习Docker容器开发。
各种工具 (Gè
-
- Ansible 2.9.10
-
- Docker 19.03.11
-
- Docker API 1.40
-
- Python 3.8.2
- Docker SDK Python 1.80
对于使用Ansible的模块来说,我们会使用docker_image和docker_container。
这些模块需要Docker API版本大于等于1.20和Docker SDK Python版本大于等于1.80,因此需要提前升级版本。此外,并非必需,但一些docker_image模块的选项需要Ansible版本大于等于2.8才能正常工作,所以最好也升级Ansible版本。
预先准备
首先,您需要获取一个Node镜像,并使用一个名为create-nuxt-app的工具来预先构建一个将app目录设置为主目录的Dockerfile,这样您就可以轻松地构建Nuxt.js项目。
FROM node:latest
WORKDIR /app
构建此Dockerfile后,创建一个Node容器,然后连接并构建Nuxt.js项目的模板。
docker run –rm -it <容器ID> bash
yarn create nuxt-app(容器中)
执行后,将以交互方式询问配置方法,请根据个人喜好进行自定义设置。
完成模板的创建后,打开新终端并将创建的模板复制到本地机器上。
docker cp <容器ID>:/app .
现在准备工作已完成,接下来创建Dockerfile和Playbook。
目录结构
目錄結構如下。
$ tree
├── dockerFile
│ ├── Dockerfile
│ └── app/(Nuxt.jsのひな型)
└── build_image.yml
└── create_container.yml
创建DockerFile
我会创建一个Dockerfile,将从Node容器中带来的本地Nuxt.js模板放置到Nuxt.js容器中,这样就可以构建Nuxt.js。
FROM node:latest
ENV NUXT_HOST=0.0.0.0
ENV NUXT_TELEMETRY_DISABLED=1
WORKDIR /app
COPY ./app/package.json ./app/yarn.lock ./
RUN yarn install
COPY ./app .
CMD ["yarn", "run", "dev"]
创建Playbook
接下来,我们将创建一个用于构建Nuxt.js容器镜像的Playbook。
- name: Build Nuxt.js image
hosts: localhost
tasks:
- name: build nuxt.js
docker_image:
build:
path: ./dockerFile
name: yuta28/ansible-test
tag: Nuxtimage
push: yes #イメージビルド後自動的にDockerHubへpushする
source: build
register: build_result
- debug: var=build_result
在docker_image选项中指定了Dockerfile的路径。name选项用于为生成的Docker镜像命名。yuta28是我的Docker Hub账户名,在推送到Docker Hub时,需要将镜像命名为Docker Hub账户名/仓库名,因此我选择了这样的名称。通过最后的source选项指定build来从Dockerfile构建镜像。
最后,我将创建一个用于基于镜像创建容器的Playbook,名为create_container.yml。
- name: Create and buid container
hosts: localhost
tasks:
- name: Nuxt container
docker_container:
name: NuxtContaier
image: yuta28/ansible-test:Nuxtimage
state: started
ports:
- "127.0.0.1:8080:3000" #コンテナ内のポート3000にNuxt.jsが構築されるのでローカルのポート8080から参照できるようにマッピング
tty: true
detach: true
register: contaier_result
- debug: var=contaier_result
执行Ansible
由于准备工作已经完成,现在可以执行Ansible了。
$ ansible-playbook build_image.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Build Nuxt.js image] ***************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [build nuxt.js] *********************************************************************************************************************************************************************************
[WARNING]: The default for build.pull is currently 'yes', but will be changed to 'no' in Ansible 2.12. Please set build.pull explicitly to the value you need.
changed: [localhost]
TASK [debug] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
"build_result": {
"actions": [
"Built image yuta28/ansible-test:Nuxtimage from ./dockerFile",
"Pushed image yuta28/ansible-test to docker.io/yuta28/ansible-test:Nuxtimage"
],
~~~~~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~~~~~~
"warnings": [
"The default for build.pull is currently 'yes', but will be changed to 'no' in Ansible 2.12. Please set build.pull explicitly to the value you need."
]
}
}
PLAY RECAP *******************************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook create_container.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Create and buid container] *********************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [Nuxt container] ********************************************************************************************************************************************************************************
changed: [localhost]
TASK [debug] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
"contaier_result": {
"ansible_facts": {
"docker_container": {
"AppArmorProfile": "docker-default",
"Args": [
"yarn",
"run",
"dev"
],
~~~~~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~~~~~~
}
}
PLAY RECAP *******************************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我已经成功地创建了容器,没有任何问题。
我将使用docker ps命令来确认容器是否正在运行,并尝试访问Nuxt.js的示例页面。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f5597614f5d5 yuta28/ansible-test:Nuxtimage "docker-entrypoint.s…" 37 minutes ago Up 37 minutes 127.0.0.1:8080->3000/tcp NuxtContaier

推送到Docker Hub

感受之情
使用Ansible,我们成功地完成了获取Docker镜像、构建、创建容器、启动以及将其推送到DockerHub的一系列操作。然而,由于最初设置nuxt-app时使用了交互式配置方法,因此无法在Dockerfile中预先编写命令来进行后续配置,并且我也没有想到更好的方法,所以我只能手动进入容器并执行nuxt-app。
实际上,在大约2或3年前的技术书籍和网站上,存在一个名为Ansible Container的方便构建和构建容器的工具。但是,截至2020年,该工具可能已经停止开发或不再推荐使用(即使尝试使用pip install ansible-container,也无法找到)。
Ansible提供了丰富的与Docker相关的模块,并且除了我们使用的两个模块之外,还有许多其他模块可供使用。如果您感兴趣,请查阅参考手册。