Question: Has anyone been able to work with the js-yaml library to write a docker compose like this?

上下文:

我正在处理DotNet模板,并为我们的团队提供了一些预定义的应用程序架构模式.我想更进一步,为整个生态系统创建docker compose个.

主要问题是我需要更改令牌并写入YAML.

我已经在模板中try 了以下两种方法,无法获得有效的YAML输出.

command: "./daprd -app-id ecosystemtemplate-${application} -app-port ${EXPOSED_PORT:-4443} --resources-path /app/config"
command: [ "./daprd", "-app-id", "ecosystemtemplate-${application}", "-app-port", "${EXPOSED_PORT:-4443}", "--resources-path", "/app/config"

我如何让js-yaml库尊重被引用的项目,并应该保留引用?

取以上command个YAML并通过json2yaml.com运行,YAML-&>JSON和JSON-&>YAML看起来都是正确的.为了重新创建它,我首先将模板YAML复制到UI中,然后复制json并再次粘贴,从而更新YAML输出,这看起来是正确的.

enter image description here

如果我使用NodeJS运行它,我在YAML中会得到不正确的输出.imagecommandnetwork_mode都需要引号.我已经用了太多的方式来列出这一点.

enter image description here

当PoC转移到产品就绪的企业级应用程序时,PoC将变得更加参与.

enter image description here

示例:

根据模板,我创建了一个Solution.json文件,其中包含生态系统模板使用的信息.

enter image description here

以下代码用于读取Solution.json

async function createDockerComposeYaml () {
    console.log("Creating Docker Compose");
    const fileName = 'docker-compose.yml';
    const applicationDescriptor = '${application}';

    await (async () => {
        try {
          await fs.unlink(fileName);
        } catch (e) {
          // Swallow the error.
          // Normally happens when the file does not exist the first time.
        }
      })();

    try {
        const dockerComposeYaml = await fs.readFile('./docker-templates/compose/Docker-compose-template.yml', 'utf-8');
        const serviceYamlTokenized = await fs.readFile('./docker-templates/compose/Docker-compose-service-template.yml', 'utf-8');
        const daprSidecarYamlTokenized = await fs.readFile('./docker-templates/compose/Docker-compose-service-dapr-sidecar-template.yml', 'utf-8');

        let dockerCompose = YAML.load(dockerComposeYaml);

        solutions.forEach(solution => {
            // Build the service for the application.
            let serviceYaml = serviceYamlTokenized.replaceAll('${application}', solution.name.toLowerCase());
            serviceYaml = serviceYaml.replace('${dockerfile}', solution.dockerfile);
            const service = YAML.load(serviceYaml);

            // Build the service for the application dapr sidecar.
            const serviceSidecarYaml = daprSidecarYamlTokenized.replaceAll('${application}', solution.name.toLowerCase());
            const serviceSidecar = YAML.load(serviceSidecarYaml);

            if (dockerCompose.services === null) {
                dockerCompose.services = [];
            }

            dockerCompose.services.push(service);
            dockerCompose.services.push(serviceSidecar);
        });

        writeFile(fileName, YAML.dump(dockerCompose, { 'forceQuotes': true }));
    } catch(e) {
        console.log(e);
    }
}

内容:

Solution.json

{
  "name": "DddTemplate",
  "template": "ddd",
  "dockerfile": "DddTemplate/src/DddTemplate.Api/Dockerfile",
  "launchSettings": "DddTemplate/src/DddTemplate.Api/Properties/launchSettings.json"
}

Docker-compose-template.yml

version: '3.7'
name: EcosystemTemplate

volumes:

services:

Docker-compose-service-template.yml

  ${application}:
    image: ${DOCKER_REGISTRY-}${application}:${IMAGE_TAG}
    build:
      context: .
      dockerfile: "${dockerfile}"
      args:
        - IMG_REGISTRY=${REGISTRY:-mcr.microsoft.com}
    environment:
      - ASPNETCORE_URLS=${ASPNETCORE_URLS:-https://*:4443}
    ports:
      - "43301:${EXPOSED_PORT:-4443}"
    volumes:
      - ~/.aspnet/https:/https:ro

Docker-compose-service-dapr-sidecar-template.yml

  ${application}-dapr:
    image: "daprio/daprd:latest"
    command: "./daprd -app-id ${application} -app-port ${EXPOSED_PORT:-4443} --resources-path /app/config"
    depends_on:
      - ${application}
    network_mode: "service:${application}"
    volumes_from:
      - ${application}

推荐答案

这里有一个简单的建议:

您可以禁用引号,并使用replacer函数,然后只在您想要修改的字段和值上添加一些占位符(您可以相应地修改代码),然后这些值将被引用,然后创建YAML文件,但在编写文件之前从其中删除占位符.

试试这个:

const somePlaceholder = '@@';

// add fields that you want to process
const fields = ['image', 'command', 'network_mode'];

function myReplacer(key, value) {

    if (typeof value === 'string') {

        if (fields.includes(key)) {
        // or
        // if (!value.includes('${')) {

            // handle command field not being quoted by adding quotes
            if(key === 'command') {

                return `'${somePlaceholder}${value}${somePlaceholder}'`
            } else {

                return `${somePlaceholder}${value}${somePlaceholder}`;
            }

        } else {
            return value;
        }
    } else {
        return value;
    }
}


// replace placeholder
const replaced = YAML.dump(dockerCompose, { replacer: myReplacer }).replaceAll('@@', '');

writeFile(fileName, replaced);

Node.js相关问答推荐

仅当所需文档是最后一个文档时才更新MongoDB,否则插入

Sequelize-测试使用虚拟场更新模型

如何将Node.js与Nuxt.js一起使用?

如何在Mongoose for MongoDB中编写此查询

如何在docker容器上正确安装nodejs?

如何使用包含条件正确分页的 sequelize 查询?

未捕获的错误: 只能用作 元素的子元素,永远不会直接呈现.请将您的 包裹在

ResponseError:键空间ks1不存在

MongoDB Aggregate - 如何使用前一阶段的值作为下一阶段的字段名称?

类型中缺少属性,该类型是由类实现的接口

为当前目录提供服务的简单文件服务器

Webpack TypeScript module.hot 不存在

如何在 AWS 上的 Amazon Linux AMI 中自动启动 node.js 应用程序?

在 Node.js 中的两个不同进程之间进行通信

运行摩卡+伊斯坦布尔+通天塔

Nodejs 随机免费 tcp 端口

npm publish 导致'错误:EPERM:不允许操作,取消链接...',errno -4048

如何从 npm 注册表中删除 npm 包?

如何判断MongoDB本机nodejs驱动程序中是否存在集合?

Npm postinstall 仅用于开发