我尝试使用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
Screenshot 2020-08-16 16:46:16.png

推送到Docker Hub

Screenshot 2020-08-16 16:55:51.png

感受之情

使用Ansible,我们成功地完成了获取Docker镜像、构建、创建容器、启动以及将其推送到DockerHub的一系列操作。然而,由于最初设置nuxt-app时使用了交互式配置方法,因此无法在Dockerfile中预先编写命令来进行后续配置,并且我也没有想到更好的方法,所以我只能手动进入容器并执行nuxt-app。

实际上,在大约2或3年前的技术书籍和网站上,存在一个名为Ansible Container的方便构建和构建容器的工具。但是,截至2020年,该工具可能已经停止开发或不再推荐使用(即使尝试使用pip install ansible-container,也无法找到)。

Ansible提供了丰富的与Docker相关的模块,并且除了我们使用的两个模块之外,还有许多其他模块可供使用。如果您感兴趣,请查阅参考手册。

bannerAds