问题标签 [12factor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
331 浏览

12factor - 为什么云应用程序的文件系统是短暂的

“超越 12 因素 APP”和“在云中设计和运行应用程序的注意事项”( https://docs.cloudfoundry.org/devguide/deploy-apps/prepare-to-deploy.html ) 指出文件系统是短暂的. 但是,在使用 openstack 进行测试时,我得到了不同的结果:

  1. 使用 openstack 服务器创建 VM 使用 centos qcow2 镜像创建,无外部存储

  2. ssh 到虚拟机,在 /home/centos 下创建文件

  3. 重启虚拟机

  4. VM启动后,该文件仍然存在。

我理解错了吗?

书中引用:

  1. 云友好型应用程序不仅在云中运行;它们还包含弹性可扩展性、临时文件系统

  2. 在“日志”一章中:云应用程序不能对它们运行的​​文件系统做任何假设,除了它是短暂的

引用“在云中设计和运行应用程序的注意事项”: “避免写入本地文件系统”:“本地文件系统存储是短暂的。”...“当应用程序实例崩溃或停止时,资源平台回收分配给该实例的任何本地磁盘更改,包括自应用程序启动以来所做的任何本地磁盘更改。当实例重新启动时,应用程序将使用新的磁盘映像启动。虽然您的应用程序可以在运行时写入本地文件,但这些文件应用程序重新启动后将消失。”

0 投票
6 回答
17528 浏览

docker - Tomcat、Docker、日志和标准输出?

我在docker中运行tomcat,但看不到日志。它们被写入 tomcat/logs 下的各种日志文件,但是当 tomcat 在 docker 容器中运行时我看不到它们。

这是我的 Dockerfile

这就是我构建图像并从中启动容器的方式:

我的应用程序在tomcat部署MYAPP.war后创建日志文件:/var/log/MYAPP.log

我应该如何修改 Dockerfile 以及我应该使用哪个命令来运行它(“docker run ...”),以便在使用 oneliner “docker run -it --rm -p 8080:8080 --name”启动容器 MYAPP 之后立即MYAPP MYAPP" /var/log/MYAPP.log 的内容会打印到标准输出吗?

我尝试将以下命令添加到 Dockerfile 中,但没有帮助。

0 投票
1 回答
56 浏览

12factor - 使用 ENV 变量是个好主意吗?

背景

我们的应用程序使用 MySQL 数据库和更多服务。

为了将我们的应用程序连接到这些服务器,我们将用户名和密码保存在一个prod.config文件中。如果我们在开发中,我们使用dev.config文件等等......

最近,我一直在研究行业中的良好做法(例如https://12factor.net/),其中大多数(如果不是全部)指定连接数据库和其他服务的用户名和密码等信息不应该在配置文件中,而不是在 ENV 变量中。

如果您不知道 12 因子规格是什么,您可以查看此免费教程:

问题

现在,起初这看起来不错。Travis 或 CircleCI 等许多 CI 工具已经强制你这样做了。这里的问题是当您最小的应用程序使用多个服务时。

在我们的例子中,对于我们最小的应用程序,我们需要 13 个 ENV 变量。不在任何特定文件中的变量,它们都必须在它们运行的​​机器的 ENV 中。

我看不出这怎么能被视为一种好的做法。我理解不使用所有这些敏感数据推送您的配置文件的主要想法,但这种方法会带来几个问题:

  1. 当机器重新启动时,您会丢失所有 ENV 变量。
  2. 如果你想避免前面的问题,你需要在机器启动时运行一个脚本,设置这些变量,这意味着你会将它们存储在一个文件中,从而破坏了整个目的。
  3. 你把这些变量保存在哪里?他们需要在你脆弱的脑袋之外的其他地方!

问题

  • 我将如何解决以前的问题?
  • 为什么将私有信息保存在 ENV 变量中被视为一个好主意?
0 投票
1 回答
393 浏览

symfony - 如何在已部署的 SF4 应用程序上处理环境变量

Symfony 自 Symfony 3 以来引入了一个新的 Dotenv 组件,它允许我们将环境变量作为应用程序参数来处理。这看起来非常好,这是根据12factor app manifesto遵循的最佳实践。

现在,关于 Symfony 4,他们进一步推动了这种做法,这就是我开始通过.env文件使用环境变量的原因。

然后我想部署,我意识到.env文件不能保存在服务器上,因为它与拥有parameters.yml文件相同。

所以我一直在深入研究文档,发现这篇文章解释了我们可以通过一些网络服务器指令直接创建环境变量。这对于通过 FPM 执行的代码非常有用,但它并没有告诉我们在通过 CLI 运行命令时如何处理环境变量。

我怎样才能做到这一点?是否应该在某处存储等效的.env文件?但是参数会重复吗?

我欢迎任何帮助;)

0 投票
5 回答
18076 浏览

docker - 如何将环境变量传递给前端 Web 应用程序?

我正在尝试将前端 Web 应用程序容器化,但在弄清楚如何传递环境变量时遇到了麻烦。该应用程序是一个 Angular 应用程序,因此它是 100% 的客户端。

在典型的后端服务中,传递环境变量很容易,因为一切都在同一台主机上运行,​​因此后端服务可以轻松选择环境变量。但是,在前端应用程序中,情况有所不同:应用程序在客户端的浏览器中运行。

我想通过环境变量配置我的应用程序,因为这使部署更加容易。所有配置都可以在其中完成,docker-compose.yml无需维护多个图像,一个用于每个可能的环境。只有一个不可变的图像。这遵循 12 因素应用理念,可在https://12factor.net/config上找到。

我正在构建我的应用程序映像,如下所示:

app/config.ts中,我有:

理想情况下,我想在我的docker-compose.yml

所以我相信我应该改变它app/config.ts来替换REST_API_URL环境变量。由于我更喜欢​​不可变的 Docker 映像(所以我不想在构建期间进行此替换),我很困惑如何在这里取得进展。我相信我应该支持在启动 nginx 代理之前更改app/config.ts运行时。然而,这个文件被缩小和 webpack 捆绑的事实使得这更加困难。

任何想法如何解决这个问题?

0 投票
0 回答
241 浏览

node.js - 处理由 redis 连接的 websocket 服务器实例中的有状态逻辑

我正在 Node 中开发基于 Web 的实时游戏,其中 Node 服务器实例使用 redis 作为通用数据存储。这适用于简单的事情,比如存储每个玩家的聊天或数据。然而,游戏逻辑包含在它自己的 Javascript 模块中——游戏的每个实例都会跟踪很多状态,包括游戏板和每次移动后的状态历史。

我看到两个选项:

  1. 将游戏对象保存在节点工作实例中(在实例之间均匀平衡,例如使用 nginx 的负载平衡)。这是我继承的一个类似项目使用的方法,但我不喜欢它,因为在部署后,主节点进程必须将游戏恢复到每个工作节点进程。这样就违反了十二因素准则
  2. 将游戏状态存储在redis中,例如玩家移动后,节点工作人员从redis中获取游戏状态,将其放入游戏逻辑模块中,并进行移动计算。我对这种方法的主要关注是速度 - 游戏状态不容易适应 redis 数据结构,因此在从 redis 设置/获取状态时会有很多 JSON.parse 和 JSON.stringify 调用,除非我很重重写游戏逻辑以处理更原始的数据类型。

我的目标是让我的节点工作人员保持无状态,以便部署更简单,同时不使用 redis 在速度或效率方面做出任何重大牺牲。有任何想法吗?

0 投票
3 回答
13852 浏览

reactjs - 在不同环境中运行的 react.js redux 生产构建中将环境变量呈现给浏览器

https://github.com/gothinkster/react-redux-realworld-example-app上的 react redux realworld.io 应用程序的自述文件说要编辑src/agent.js以更改API_ROOT指向不同的后端 api 实例。我们希望进行设置,以便API_ROOT可以通过在我们运行生产构建的多个环境(例如,“staging”和“live”)中不同的环境变量来定义。

我们遵循 12factor.net 原则在 openshift kubernetes 上的容器中运行,其中代码构建一次,然后通过环境进行升级。我们可以使用单个命令启动新环境,因此我们不希望在代码中使用 switch 语句来命名每个环境并API_ROOT为每个环境硬编码后端。相反,我希望能够在新环境中运行现有的生产构建容器映像,使用环境变量更改API_ROOT指向我们要测试的正确后端 API。

我查看了许多不同的博客、stackoverflow 答案和官方文档。主要问题是典型的解决方案process.env.API_ROOT在构建时“烘焙”环境变量,否则有一个开关,将所有环境的细节硬编码到代码中。两者都不令人满意,因为我们希望能够在现有容器中获取最新的稳定代码,并使用在那里运行的 API 在新环境中运行它。

到目前为止,我最接近的是编辑代码以将其呈现process.env.API_ROOT为将<script>其设置在window.API_ROOT变量上的标签。然后检查是否存在,否则在为 API_ROOT 定义 const 时使用默认值。这感觉非常具有侵入性并且有点脆弱,我不清楚在https://github.com/gothinkster/react-redux-realworld-example-app的示例应用程序中呈现这样一个脚本标签的最佳位置是哪里

0 投票
2 回答
527 浏览

php - 可以“构建”(“编译”)Docker 映像以不需要 Docker 吗?

我对 Docker 进行实验和开发的经验非常少,而在暂存和部署方面,我对 Docker 的经验为零——所以请原谅任何听起来幼稚的事情。

主要问题

假设我有一个 Docker 映像(甚至是一个docker-compose.yml由多个映像和服务组成的文件),它在运行时为我的应用程序设置环境并运行我的应用程序 - 允许在公共开放端口上进行连接并响应请求。

为了在生产中运行这个镜像(因此为了在生产中运行我的应用程序),生产服务器必须安装 Docker。这感觉像是违反了十二要素应用程序的设计。特别是当您考虑端口绑定原则时:

十二因素应用程序是完全独立的

就像一个应用程序不应该依赖 Apache 或 nginx 来安装一样,一个应用程序也不应该依赖 Docker 来安装吗?

这让我想知道是否有办法将 Docker 运行时和映像“打包”、“构建”或以其他方式“编译”成可执行二进制文件。可以部署到任何服务器并作为单个进程运行而无需先安装 Docker 的东西。

现在,我可能只是在想这完全错误的。出于这个原因,我已经详细说明了我在下面遇到的担忧和问题

是什么引起了这一切

我有一个以前使用Cloud9开发的 Web 应用程序项目。当我将此项目推送到生产环境时,我通过 SSH 手动登录到生产服务器并执行git pullcomposer updatenpm installgulp. 我有点麻烦,但对于我工作的非常小的规模来说,这已经足够了,这比通过 FTP 上传我的所有依赖项要好得多。

但是,我偶尔会遇到外部依赖项的挑战。有些东西在开发中运行良好,然后当我将它推送到生产环境时,我意识到生产服务器有一个过时的 MySQL 版本。或者生产服务器上安装的 pngquant 版本有 bug。或者服务器上的 nginx 配置与开发中的 nginx 配置不完全匹配,并且在路由格式错误的请求时会导致一些边缘情况。

今天,当我尝试在CodeAnywhere而不是 Cloud9 中加载我的项目时,所有这些问题都立即出现了。我必须确保:

  • PHP 版本已更新
  • NodeJS 已更新
  • NPM 已更新
  • 卷曲已安装
  • 安装了所有必需的 PHP 扩展
  • 安装了几个 GNU 库
  • ETC

我花了几个小时试图让这段代码运行——这是写的代码

遇到所有这些问题让我想起了十二要素应用程序设计。所以我跳到网站上,想了想弄清楚我做错了什么。

注意:我不只是单独开发,然后直接部署到生产环境。我实际上在 BitBucket 中设置了这个项目,我使用票务系统来跟踪更改,为每个票创建一个分支,并在合并到 master 之前在暂存环境中签出分支。因此,我创建了一个非常强大的系统来管理更改,以避免错误进入生产环境并允许敏捷开发。但是,当涉及到在暂存或生产中检查分支时,它是相同的手动废话:git pull, composer update, npm install, gulp.

我喜欢 Docker 的地方

在源代码控制的配置文件中定义我的工作环境的能力将消除我的大部分问题。我再也不需要确保 PHP 是最新的、确保 NodeJS 是最新的、确保安装了 cURL 等。如果 Docker 映像具有所有依赖项,那么在部署到暂存或生产时它仍然具有这些依赖项. 各个发展阶段之间的环境一致性将使我的生活轻松。

另外,我还没有玩过这么高级的东西,但我知道使用 Docker 很容易设置自动部署。如果我可以单击 BitBucket 中的一个分支,然后单击“发送到暂存”,一分钟后将其部署并准备好进行测试——这将每周为我节省数小时的时间。如果我可以类似地在将代码合并到 master 时将代码自动部署到生产中,那不仅可以节省我的时间,而且可以避免完成的功能在 BitBucket 中停滞不前并且永远不会出现在客户面前的风险。

最后,这可能最终成为一个有争议的问题,我理解 Docker 使绿色/蓝色部署变得更加容易。目前,当我将新更改推送到生产环境时,生产服务器会短暂脱机。通常只持续 15-20 秒,但一次是整整一个小时。在这 15-20 秒的窗口中,我正在运行composer updatenpm installgulp。前两个命令通常不需要做任何事情(因为我的依赖项不经常更改)并且gulp通常在 15 秒内完成。但是,当依赖项更改或出现较大问题(例如需要升级 MySQL)时,站点可能会关闭一小时。如果我可以缓慢而平静地部署到辅助生产服务器,然后在我验证它工作正常时在几毫秒内翻转开关,这将意味着更少的停机时间和更多的客户满意度。

当然最后一个可能是一个有争议的点,因为我目前没有使用“构建”步骤(十二因素应用程序的另一部分),所有这些步骤都应该是“构建”阶段的一部分——不是“部署”阶段。

我不喜欢 Docker 的地方

它又是一种学习工具。为了理解和开发我的应用程序,您已经需要了解:

  • PHP
  • 作曲家
  • Symfony
  • 拉拉维尔
  • 节点JS
  • 新PM
  • 吞咽
  • 引导程序
  • VueJS
  • (可能还有很多我现在想不起来的事情)

将“Docker”添加到该列表仅意味着如果我将这个项目交给另一个开发人员,那么培训某人会变得更加困难。我想要更少的依赖,而不是更多。

此外,我所知道的任何操作系统都没有默认 Docker。因此,它不像 cURL,虽然它在技术上是第三方依赖项,但您通常可以期望人们拥有它。相反,它是一个必须单独安装的整体野兽。

前一个问题我无法真正规避。如果我选择使用 Docker,这意味着在我的工具箱中为这个应用程序添加了一个工具。但是,如果 Docker 映像可以以某种方式编译为独立的二进制文件,则可以避免后一个问题。

0 投票
0 回答
1281 浏览

node.js - 如何解决环境变量冲突和污染?

语境:

随着我的 Node.js 项目越来越大,对配置的需求也在增加。这个项目是我从“旧配置文件”(例如,a config.jsor config.json)切换到 dotenv ( .env) 文件来配置产品的第一个项目。

但是,使用的环境变量数量之多引发了一个问题。这些环境变量都与操作系统和网络配置有关,因此使用 dotenv 技术配置应用程序似乎是合理的。

问题:

假设已经设置了一个环境变量;那会弄乱配置。这方面的一个实际示例是,当您将项目上传到一些较大的(云)主机时:PORT机器的环境变量已设置,因此可能会覆盖默认值(参见下面的示例),或者您可能会使用的值预计。对于系统管理员来说,这些错误很难调试。

如何处理这些陷阱?

现在的情况:

我目前正在[name of product]_[name of variable]用作我的环境变量的模板。感觉就像是 hack(还记得 JS 中的私有成员吗?),而且很可能有更好的解决方案可用。

我想到的第二个选项是.env通过设置产品中使用的所有变量在文件中非常明确。然而,这里的可靠性似乎是一个弱点:如果有人要删除一个设置,整个“防御机制”就会消失,产品再次容易受到这些错误的攻击。

0 投票
1 回答
817 浏览

security - Cloud Foundry 后端和公共应用程序

在大多数解决方案中,一些应用程序应该是公共的,而一些应用程序应该仅供内部访问。

这种解决方案是否有经过验证的配置模式?

执行此操作的简单方法可能是创建两个 CF 空间(在同一个 CF 组织中):

  • internal space
    • 此空间中的应用程序绑定到internal domain(例如:*.my-internal-cf.cloud),指向internal load-balancer
    • internal domain主要共享域
    • 无法从internal load-balancerInternet 访问,只能对来自 Cloud Foundry 的应用程序进行访问
    • internal space有权访问后备服务(cf 安全组)
  • public space: _
    • 此空间中的应用程序绑定到public domain(例如:*.my-pub-cf.cloud),指向public load-balancer
    • public load-balancer可从 Internet 访问,并且仅将流量传递给public domains
    • public space后备服务的访问权限有限,甚至只能访问internal space(cf 安全组)中的应用程序

这种配置安全吗?

可以更轻松地完成吗?