本文介绍了如何使用 METEOR_SETTINGS 环境变量在 AWS/EBS 上配置 Meteor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试在 AWS/EBS(亚马逊网络服务、Elastic Beanstalk)环境中设置 Meteor.

Trying to set up a Meteor on an AWS/EBS (Amazon Web Services, Elastic Beanstalk) environment.

Meteor dev-run 可以传递一个命令行标志:--settings settings.json 其中 settings.json 是一个包含服务器/客户端键/值的文件配置(作为格式正确的 JSON).

A Meteor dev-run can be passed a command line flag: --settings settings.json where settings.json is a file containing server/client key/value configs (as properly-formatted JSON).

Meteor 的部署使用了一个 METEOR_SETTINGS 环境变量,而不是在命令行中传递配置文件.如果提供,它应该包含一个 json 文档,例如 settings.json 的内容,例如:

Instead of passing the config file in command line, Meteor's deployment uses a METEOR_SETTINGS environment variable. If provided it is expected to contain a json document such as contents of settings.json, for example:

$ METEOR_SETTINGS=$(cat settings.json)
$ echo $METEOR_SETTINGS
{ "public": { "s3path": "https://d2v4p3rms9rvi3.cloudfront.net" } }

问题是当我在 EBS 控制台中将 METEOR_SETTINGS 的值设置为这个值时:

The problem is that when I set the value of METEOR_SETTINGS to this value in the EBS console:

AWS/EBS 丢弃引号,转义斜杠(如屏幕截图所示),并发送 Meteor:

AWS/EBS discards the quotes, escapes the slashes (as seen in screenshot), and sends Meteor:

{public:{s3path:https://d2v4p3rms9rvi3.cloudfront.net}}

如节点启动错误所示:

-------------------------------------
/var/log/nodejs/nodejs.log
-------------------------------------
npm WARN deprecated backwards-incompatible changes made to `npm run-script` and
npm WARN deprecated semver behavior.

> [email protected] start /var/app/current
> node main.js


/var/app/current/programs/server/boot.js:283
}).run();
   ^
Error: METEOR_SETTINGS are not valid JSON: {public:{s3path:https://d2v4p3rms9rvi3.cloudfront.net}}
    at packages/meteor/packages/meteor.js:21:1
    at Package (packages/meteor/packages/meteor.js:42:1)
    at /var/app/current/programs/server/packages/meteor.js:1277:4
    at /var/app/current/programs/server/packages/meteor.js:1286:3
    at /var/app/current/programs/server/boot.js:242:10
    at Array.forEach (native)
    at Function._.each._.forEach (/var/app/current/node_modules/underscore/underscore.js:79:11)
    at /var/app/current/programs/server/boot.js:137:5

为了解决这个问题,我在 value 字段中尝试了 JSON 对象的各种变体:转义引号,用单引号将整个 json 部分括起来,用单引号替换双引号,以及其他尝试 - 都没有解决.

Bumping against this problem I tried all sorts of variations for the JSON object in the value field:escaping the quotes, enclosing the entire json part with single quotes, replacing double-quotes with single-quotes, and other attempts - neither solved it.

问题是:

如何设置 METEOR_SETTINGS 以便 Meteor rcv &解析正确吗?

How can METEOR_SETTINGS be set so that Meteor rcv & parse it correctly?

注意:要求之一是相同的构建部署到开发、暂存和生产环境.需要为每个环境单独设置配置,因此如果有另一种方法将设置注入到 EBS 环境中,而无需修改也可以解决它的构建.

Note: one of the requirements is that the same build deploys to dev, staging and production environments. Configs need to be set separately for each environment thus if there's another way to inject the settings into the EBS environment w/o modifying the build that will also solve it.

推荐答案

在与 AWS Support 讨论这个问题后,我意识到 AWS/EBS 不支持在环境变量中存储 JSON.这是因为环境变量作为键/值字符串存储在未编码的 JSON 中(显然,在 CloudFormation 中).这里的底线有点令人失望:

After discussing this issue with AWS support I realized that AWS/EBS does not support storing JSON in environment variables. This is because the environment variables are stored as key/value strings in unencoded JSON (apparently, in CloudFormation). The bottom line here a bit disappointing:

这确实很不幸,但是有几个解决方法.

This is indeed unfortunate, however there are a couple of workarounds.

将 json 配置移动到 s3 存储桶中,并将以下内容放在 .ebextensions/app.config 文件中:

Move the json configs into an s3 bucket and place the following content in a .ebextensions/app.config file:

container_commands:
  01_setvariable:
    command: "aws s3 cp s3://<bucket-name>/nodejs.conf /tmp/deployment/config/#etc#init#nodejs.conf

这将使用从您的 s3 存储桶中检索到的内容完全覆盖 /etc/init/nodejs.conf.自然有机会使用微调/花哨的 bash 脚本来设置/覆盖单个设置.

This will entirely override /etc/init/nodejs.conf with content retrieved from your s3 bucket. Naturally there's an opportunity to set/override individual settings using fine-tuned/fancy bash scripting.

我最终没有选择这种方法,因为它涉及另一个实体(一个 S3 存储桶)并且开发迭代需要一个新版本部署,这不是非常快.

注意:这是我想出的一个简单的代码破解.似乎不需要太多努力就将所有这些混乱抛在脑后.

我最初的需求是将 AWS/EBS env vars 传播到客户端,因此我决定绕过 METEOR_SETTINGS 变量并直接使用 env 填充 Meteor.settings.public来自节点 process.env 空间的变量.白名单由一个简单的列表管理.添加一个 server/lib/config.js 文件:

My original need was to propagate AWS/EBS env vars to the client, so I decided to bypass the METEOR_SETTINGS variable and populate Meteor.settings.public directly with env vars from node's process.env space. The whitelisting is managed by a simple list. Add a server/lib/config.js file with:

Meteor.startup(function () {
    // public settings that need to be exposed to the client can be added here
    var publicEnvs = {
        S3_PATH: 's3path'
    };
    var modified;
    _.each(publicEnvs, (value, key) => {
        let envValue = process.env[key];
        if (envValue) {
            Meteor.settings.public[value] = envValue;
            modified = true;
        }
    });
    if (modified) {
        __meteor_runtime_config__.PUBLIC_SETTINGS = Meteor.settings.public;
    }
});

万岁,您的客户可以访问您选择的环境变量!

Hurray, your client can access the env vars of your choice!

例如,通过此更改,可以在客户端上以 Meteor.settings.public.s3path 的形式访问在 EBS 控制台中定义的 S3_PATH 环境变量.很简单,没有很多活动部件:)

For example with this change, an S3_PATH environment variable defined in the EBS console can be accessed as Meteor.settings.public.s3path on the client. Quite simple, and without many moving parts :)

这篇关于如何使用 METEOR_SETTINGS 环境变量在 AWS/EBS 上配置 Meteor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 03:37