# 从独立容器迁移到独立的 Web 和数据容器

**URL:** https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413
**Category:** Sysadmins
**Tags:** docker, how-to, advanced-setup, two-container
**Created:** [2015年五月29日 14:12 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413 "2015-05-29T14:12:22Z")
**Posts on this page:** 20
**Page:** 3

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年四月10日 10:08 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/48 "2020-04-10T10:08:13Z")

</div>

> [@pfaffman](#):
>
> 我一直担心的是，由于一些用户可能无法理解其原理，他们会尝试使用它，随后却无法使用任何文档，因为“重建应用”将不再有效，而且也难以判断何时需要重建数据库容器。

你好，Jay @pfaffman，感谢你发布的这篇帖子，以及关于这个“双容器”主题的其他帖子，包括 Sam 在这方面写的文章。

问题：

我们一直在尝试按照你提到的方式设置两个容器：一个用于 `data`，另一个用于 `web-only`，但在 macOS 上运行过程中遇到了不少阻碍。

不过，在担心如何在 macOS 或 Ubuntu 上调试这个“双容器配置”之前，我们想先确认这样做是否出于正确的理由。

我们想要进行“双容器操作”的原因是，希望在重建 Web 应用（例如安装插件时）时，网站不会停机。此外，当我们调整自研插件时，有时发现唯一能确保更改生效的方法就是重建（这是另一天的故事）。我也一直在努力搭建一个“快速且友好”的 Web 开发环境，但尚未达到满意程度；不过这也是另一个话题。

所以，我的问题是：“双容器”设置是否能显著减少仅重建 Web 部分应用时的停机时间？

这样理解是正确的，对吧？

当我们安装插件或对其进行调整时，是否只需要重建“web-only”的 yml 文件，而不需要重建 data yml 文件？

我们来自 LAMP 论坛背景，因此对插件的更改大多可以在生产环境中实时完成（除非操作失误，否则不会停机）。此外，我们也曾开发过一些 VueJS Web 应用，在桌面端构建后，只需上传并将新应用部署到位，升级/更新 VueJS 部分几乎不会造成停机。然而，在使用 Discourse 时，我们会遇到停机时间，这是我们不希望发生的（哪怕只有几秒钟）。

“双容器”方案在我们执行以下操作时，是否能显著减少停机时间：(1) 重建应用（用于插件、代码调整等）或 (2) 从完整备份恢复？

我觉得再次提出这个问题可能会“挨骂”，因为我们正在寻找一种在生产环境中运行 Discourse 并实现近乎零停机更改的方法，而目前尚未找到像 LAMP 或 VueJS 应用那样容易实现的方式。

因此，我们才对“双容器”方法如此感兴趣并努力尝试，但至今尚未成功部署。

谢谢！

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年四月10日 15:23 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/49 "2020-04-10T15:23:03Z")

</div>

> [@neounix](#):
>
> 那么，我的问题是，“双容器”设置是否能显著减少仅 Web 部分的应用重建时的停机时间？

是的。在构建新容器时，现有的 Web 容器会继续运行。因此，停机时间仅取决于启动新 Web 服务器所需的时间，通常不到一分钟，但这绝非零停机方案。如果您需要零停机，则需要在前面部署一个反向代理，以便在新容器启动并开始工作后再关闭旧容器。（此外，如果新容器的数据库迁移导致旧容器出现问题，除非采取其他复杂措施，否则仍会出现停机时间）。

> [@neounix](#):
>
> 当我们（1）重建应用（用于插件、代码调整等）或（2）从完整备份恢复时，“双容器”方案是否能显著改善停机时间？

从备份恢复时没有区别。

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年四月11日 03:28 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/50 "2020-04-11T03:28:26Z")

</div>

谢谢你，Jay @pfaffman，

你绝对是这里最顶尖、最有价值的资源，毫无疑问！

你觉得这个可能有点疯狂的想法怎么样（基于我目前有限的理解）：

在前端设置 `nginx` 作为反向代理；参考这个教程：

> [@Add an offline page to display when Discourse is rebuilding or starting up](https://meta.discourse.org/t/adding-an-offline-page-when-rebuilding/45238):
>
> warning This guide is intended for advanced users, who are already using nginx outside the docker container. By following this guide you make your setup more complicated and will lose some speed benefits like HTTP2 if you’re not running Ubuntu 16.04 or later. Proceed with caution! When Discourse is rebuilding or starting up, your users will usually either see an error message from their browser… …or a not-so-nice 502 error message from Nginx: If you’re a perfectionist …

然后设置两个目录/实例，使用 discourse\_docker（独立模式），例如：

1. /var/discourse1
2. /var/discourse2

在这两个实例中，将 discourse\_docker（独立模式）配置为监听不同的套接字，修改每个实例中的以下模板：

```plaintext
 - "templates/web.socketed.template.yml"

```

简而言之，我们只需在某个安静时段重建生产环境，使其在另一个容器中运行并监听不同的套接字（`nginx.https.sock2`），这样就不会有套接字冲突；我们也可以以独立模式构建（目标是消除对两个容器（`data` 和 `web-only`）的需求）。

例如（用于讨论/说明），在 discourse1 的 `web.socketed.template.yml` 中：

```plaintext
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 80;/
     to: |
       listen unix:/shared/nginx.http.sock;
       set_real_ip_from unix:;
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 443 ssl http2;/
     to: |
       listen unix:/shared/nginx.https.sock ssl http2;
       set_real_ip_from unix:;

```

而在 discourse2 中：

```plaintext
 - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 80;/
     to: |
       listen unix:/shared/nginx.http.sock2;
       set_real_ip_from unix:;
  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 443 ssl http2;/
     to: |
       listen unix:/shared/nginx.https.sock2 ssl http2;
       set_real_ip_from unix:;

```

不过，与其让 discourse 模板自动完成这些操作，我们只需手动切换 `/etc/nginx/conf.d/discourse.conf` 中的套接字并重启 nginx，这样就可以从 `web.socketed.template.yml` 模板中移除 `replace:` 指令。

在这个提议的（可能有点疯狂）配置中，我们可以让两个独立容器监听两个不同的套接字（互不冲突），只需配置 `nginx` 连接到所需的套接字并重启 `nginx` 即可。

这看起来清晰、简单，或许对某些不想（或不需要）为单个 discourse 实例（应用）维护两个容器（data 和 web-only）复杂性的用户来说很有用（特别是在实时实例没有新帖子的空闲时段）。

当然，从数据角度来看，最稳健的配置（尤其是对于繁忙的网站）仍然是“双容器”方案，因为我们会希望 `data` 和 `web-only` 实例（现在分别监听两个不同的套接字：`sock` 和 `sock2`）。

在带有 `nginx` 前端的“双容器”方案中，“标准配置”是让两个 web-only 容器监听同一个套接字，因此它们不能同时运行；但如果（仅举例）让它们监听不同的套接字，它们就可以同时运行，我们只需使用 `nginx` 配置文件（并重启 `nginx`）即可在两者之间切换。

我的理解正确吗？

我是不是正在（虽然缓慢但希望稳步地）理解这一切？

谢谢！

_仅作为补充说明：_ 我已经在其中一台桌面 Mac 上成功配置了“双容器”方案：

![Screen Shot 2020-04-11 at 12.41.24 PM](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/meta/optimized/3X/5/4/54f8cbf1d7431ead4638a1a35919d112b6a21929_2_690x31.jpeg)

我们安装过程中唯一的注意事项是必须手动创建这些目录（并设置所有权和权限），因为这些目录出于某种原因没有被脚本自动创建：

~discourse/discourse/shared/data  
~discourse/discourse/shared/web-only

当然，一开始我尝试使用空密码连接数据库，但失败了（虽然说明中确实提到要设置密码，但我当时只是在尝试）。

接下来，我将设置 `nginx` 前端，并尝试将 web-only 应用切换到该配置，使用 `websocket`。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年四月11日 15:12 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/51 "2020-04-11T15:12:08Z")

</div>

这确实信息量很大。不过，没必要保留两个 discourse 目录。只需在 containers 目录下创建多个 yml 文件即可，文件名可以随意命名。

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年四月11日 15:43 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/52 "2020-04-11T15:43:18Z")

</div>

感谢确认。经过今天的尝试，我们的配置确实如此（单一目录）。

两个容器的配置（2CC）一切顺利，但在 macOS 上配置 nginx 反向代理时遇到了困难。

无法建立到 /shared 目录中 Unix 域套接字的有效连接，尽管该套接字在容器外部是可以访问的。我们尝试了 nginx、Python 和 socat（用于测试），但总是出现 61 错误（连接被拒绝）。嗯……

一整天都卡在“连接被拒绝”的问题上！！

明天又是新的一天。

---

<div class="post-metadata">

### Author: ![Bathinda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bathinda/32/135888_2.png) [@Bathinda](https://meta.discourse.org/u/Bathinda)
#### Post date: [2020年四月18日 08:40 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/53 "2020-04-18T08:40:27Z")

</div>

我有一个小问题。  
如果我们只有一个容器配置（只有 ‘app.yml’），并执行 ./launcher bootstrap app 命令。  
那么我们的网站/前端会停止吗？

如果会停止，那么为什么 ‘bootstrap web-only’ 不会停止我们的网站？

如果不会停止，那么在容器重建时，双容器设置在时间节省方面有什么好处？换句话说，如果我们可以在引导单个容器的同时保持网站运行，那为什么还需要两个独立的容器呢？

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年四月18日 12:28 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/54 "2020-04-18T12:28:28Z")

</div>

> [@Bathinda](#):
>
> 我有个小问题。  
> 如果我们只有一个容器配置（只有 `app.yml`），并执行 `./launcher bootstrap app`。  
> 那么我们的网站/前端会停止吗？

不会，前提是你创建一个新的 `.yml` 文件，例如命名为 `new_image`。

> [@Bathinda](#):
>
> 如果不会，那为什么 `bootstrap web-only` 不会停止我们的网站？

如果配置正确，bootstrap 操作本身不会启动或停止任何服务。经过 bootstrap 的镜像并未运行，这就是它们被称为“已 bootstrap”的原因。

不过，你需要创建一个新的 `yml` 文件，因为你需要创建一个具有新镜像名称的新镜像。

因此，使用新的镜像名称时，新的已 bootstrap 镜像尚未运行。它仅仅处于“已 bootstrap”状态。

> [@Bathinda](#):
>
> 如果不会，那么双容器设置在重建容器时的时间优势体现在哪里？换句话说，如果我们能在 bootstrap 单一容器的同时保持网站运行，那为什么还需要两个独立的容器？

你可以用新名称（不是 `app`）构建新镜像，构建完成后，我们称之为 `new_image`。

然后，如果你想替换正在运行的镜像（我们称之为 `old_image`），可以执行以下操作：

```plaintext
./launcher stop old_image; ./launcher start new_image

```

在你的情况下：

```plaintext
./launcher bootstrap new_image # 数据镜像和 Web "app" 镜像正在运行
./launcher stop app; ./launcher start new_image

```

因为数据容器已经构建完成，你可以节省时间：(1) 无需重新构建数据镜像；(2) 在重建 Web 镜像时无需停机，因为你可以在其他镜像运行时构建它（即 bootstrap 镜像）。

这要快得多；但使用反向代理置于容器前面会更快。

在你最初的问题中，你有一个名为 `app` 的正在运行的镜像。如果你尝试再次 bootstrap 这个名为 `app` 的镜像，那么你就是在重建同一个镜像（同名）。这不会为你节省任何时间，正如你的直觉告诉你的那样。

现在清楚了吗？

如果还不清楚，请随时提问。每个人都可以学习，而学习是令人兴奋的。这（实际上）很容易理解，但如果你是初次接触这些概念，可能需要一点时间。

---

<div class="post-metadata">

### Author: ![Bathinda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bathinda/32/135888_2.png) [@Bathinda](https://meta.discourse.org/u/Bathinda)
#### Post date: [2020年四月19日 03:40 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/55 "2020-04-19T03:40:39Z")

</div>

说实话，我什么都没理解。我尝试过，但失败了。

我的问题很简单。  
如果我们有两个容器的设置，并且我们“启动”（而不是重建）我们的“仅 Web”容器，那么当前的 Web 容器会继续工作（因为我们的网站显示为正常/可用）。

如果我们是单容器设置，比如 ‘app.yml’，然后我们启动这个 ‘app’ 容器，我们的网站是否仍能继续工作？

如果解释很简单，那么为什么会这样？

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [2020年四月19日 05:13 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/56 "2020-04-19T05:13:35Z")

</div>

也许你应该雇个人来帮你？

---

<div class="post-metadata">

### Author: ![Bathinda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bathinda/32/135888_2.png) [@Bathinda](https://meta.discourse.org/u/Bathinda)
#### Post date: [2020年四月19日 05:28 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/57 "2020-04-19T05:28:20Z")

</div>

没问题。

只是个小疑问。其中一部分，或许可以用“是/否”来回答。

没什么大不了的。

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年四月19日 06:17 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/58 "2020-04-19T06:17:32Z")

</div>

> [@Bathinda](#):
>
> 只是有个小疑问。其中一部分或许可以用“是/否”来回答。

我的建议是，亲自尝试一下，享受这个过程。

实际上，在自己的测试环境中亲自尝试，比在论坛上提问并等待回复所花的时间更少。

如果你亲自尝试，就能得到问题的答案；因此，你应该在测试场景中尝试这些操作，这样就不会破坏你的生产应用 🙂

Discourse 是开源的，并且可以免费下载和配置，这要归功于联合创始人慷慨的奉献。这意味着你可以而且应该利用这一开源优势，自由地创建、销毁、重建和再次销毁测试应用（次数不限）。

如果你不愿意在基础系统管理任务上投入一些精力，@codinghorror 曾有一个很好的建议，即在这里雇佣本地人才。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年四月19日 10:21 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/59 "2020-04-19T10:21:51Z")

</div>

> [@Bathinda](#):
>
> 如果我们有两个容器的设置，并且我们“引导”（而非重建）我们的“仅 Web”容器，那么当前的 Web 容器将继续工作（因为我们的网站显示为正常/可用）。

是的。（除非引导过程以某种方式迁移数据库，导致正在运行的容器无法再使用它）。在旧容器关闭和新容器启动的过程中，您会有停机时间。

> [@Bathinda](#):
>
> 如果我们是单容器设置，比如‘app.yml’，然后我们引导这个‘app’容器，我们的网站是否还能继续工作？

不能。您无法让两个数据库进程同时访问相同的文件。

---

<div class="post-metadata">

### Author: ![Bathinda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bathinda/32/135888_2.png) [@Bathinda](https://meta.discourse.org/u/Bathinda)
#### Post date: [2020年四月19日 11:40 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/60 "2020-04-19T11:40:55Z")

</div>

> [@pfaffman](#):
>
> 你不能让两个数据库进程同时访问相同的文件。

哦！！  
感谢澄清这个问题。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年四月19日 14:51 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/61 "2020-04-19T14:51:45Z")

</div>

因此，通过将数据库置于您正在构建的容器之外，您可以构建一个新的 Web 容器来操作该数据库，而另一个 Web 容器则继续运行。

---

<div class="post-metadata">

### Author: ![Iceman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iceman/32/181309_2.png) [@Iceman](https://meta.discourse.org/u/Iceman)
#### Post date: [2020年五月20日 10:14 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/62 "2020-05-20T10:14:13Z")

</div>

关于这个方案有个小疑问：在这种设置下，如何进行 Rebuild 操作？

假设我们从头开始采用 @pfaffman 添加的双容器设置，那么会有两个容器：“app”: “data” 和 “web\_only”。

所有的 Rebuild 操作都指向 “web\_only” 容器，那么我们需要对 “data” 容器做什么吗？还是说 “web\_only” 的启动过程会自动处理？（之所以这么问，是因为我在做测试时发现 data 容器从未在任何时刻停止运行。）

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年五月20日 11:20 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/63 "2020-05-20T11:20:45Z")

</div>

> [@Iceman](#):
>
> 对此方法有个小疑问：在这种配置下，如何进行重建（Rebuilds）？

我们使用“三个容器”和一个反向 nginx 代理：

1. data
2. socket1
3. socket2

假设我们当前正在运行 socket1（即你所说的“仅 Web”模式），并且想要重建并测试某些内容。我们会重建 socket2，而 socket1 继续运行。由于每个容器都使用 Unix 域套接字，且共享套接字位于不同的文件中（位置不同），因此它们可以同时运行。

然后，假设 socket2 已构建完成并准备就绪。

我会执行以下操作：

```plaintext
ln -sf /var/discourse/shared/socket2/nginx.http.sock /var/run/nginx.http.sock

```

现在我们已经切换到 socket2 并在线运行。

例如，如果出现问题，我只需执行以下操作：

```plaintext
ln -sf /var/discourse/shared/socket1/nginx.http.sock /var/run/nginx.http.sock

```

这样我们就回到了之前的状态，继续运行 socket1。

为了好玩，我在 bash 登录配置文件中添加了一些代码，这样每次登录服务器时，它都会告诉我当前运行的是哪个套接字（容器）：

```plaintext
Last login: Fri May 15 09:39:39 2020 from 159.192.33.138
srw-rw---- 1 root docker 0 May 5 07:38 /var/run/docker.sock
lrwxrwxrwx 1 root root 44 May 15 09:16 /var/run/nginx.http.sock -> /var/discourse/shared/socket/nginx.http.sock

```

希望这能帮到你。

就我个人的看法（IMHO），这（总体而言）是“最佳做法”（也是我在生产环境中的“默认标准”，而非在测试或开发环境中），但这仅代表我个人观点，你的情况可能有所不同（YMMV）。设置过程需要稍微多花一点功夫，但我觉得在生产环境中非常值得。

* * *

注意事项：

* * *

最好将原始模板 `yml` 文件备份到安全的地方，因为模板可能会被覆盖，从而引发问题。因此，我们倾向于“保存所有 `yml` 文件”，先执行“拉取（pull）”，然后“检查 `yml` 文件”，最后再启动（出于充分的谨慎考虑）。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年五月20日 12:43 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/64 "2020-05-20T12:43:22Z")

</div>

除非 PostgreSQL（刚刚发生）或 Redis（大约在过去 6 个月内发生）进行升级，否则您无需重新构建数据容器。

大多数情况下，您只需将说明中的 web\_only 替换为 app。我的笔记位于：[Managing a Two-Container Installation - Documentation - Literate Computing Support](https://support.literatecomputing.com/t/managing-a-two-container-installation/310)

---

<div class="post-metadata">

### Author: ![Iceman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iceman/32/181309_2.png) [@Iceman](https://meta.discourse.org/u/Iceman)
#### Post date: [2020年五月21日 07:50 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/65 "2020-05-21T07:50:21Z")

</div>

> [@neounix](#):
>
> 依我之见，这（总体而言）是“最佳做法”（也是我在生产环境而非测试或开发环境中的“默认标准”），但这仅代表个人观点，效果因人而异。设置起来确实需要多花一点功夫，但我认为在生产环境中这样做非常值得。

那么，在这种方法中，您拥有两个 Web 实例，并利用闲置的那个用相同的数据进行测试？这很有趣，一旦我确定了整个“节省空间”的策略，我一定会尝试一下 😛

> [@pfaffman](#):
>
> 除非 PostgreSQL（如刚刚发生的情况）或 Redis（大约在过去 6 个月内发生过升级）有升级，否则您无需重建数据容器。
> 
> 大多数情况下，您只需将说明中的 web\_only 替换为 app 即可。我在 [管理双容器安装 - 文档 - Literate Computing 支持](https://support.literatecomputing.com/t/managing-a-two-container-installation/310) 中记录了相关笔记。

非常感谢。我已通读您的文章，只有一个小问题：您这里指的是“数据”容器对吗？（即如文章中所述，重建数据容器而不是 web\_only）？还是说有什么我没注意到的技巧（例如：在进行重大升级时，需要将它们合并在一起，然后再分开）？

---

<div class="post-metadata">

### Author: ![neounix](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neounix/32/215617_2.png) [@neounix](https://meta.discourse.org/u/neounix)
#### Post date: [2020年五月21日 07:59 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/66 "2020-05-21T07:59:28Z")

</div>

> [@Iceman](#):
>
> 所以在这个方案中，您有两个 Web 实例，并利用空闲的那个用相同的数据进行测试？这很有趣，等我确定好整个“节省空间”的策略后，一定会尝试一下。

是的，我们在一个基于 socket 的容器中进行测试、添加和重建，同时在另一个容器上运行。

是的，两者都使用同一个数据容器。数据容器并不“关心”它正在与哪个 Web 应用程序“通信”。

其实非常简单，一旦您掌握了如何在共享的 Unix 域 socket 上运行容器，而不是通过外部暴露的 TCP/IP 端口运行，就明白了。

我们发现这并不会占用太多空间，不过话说回来，我们在生产环境中并不会因为磁盘空间有限而受限，因为磁盘空间并不昂贵。

---

<div class="post-metadata">

### Author: ![Iceman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iceman/32/181309_2.png) [@Iceman](https://meta.discourse.org/u/Iceman)
#### Post date: [2020年五月23日 13:00 UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/67 "2020-05-23T13:00:44Z")

</div>

感谢您的详细说明。我刚刚在测试环境中尝试让两个“应用容器”指向同一个 Data One，结果运行得非常顺利。

不过，我无法将其迁移到生产环境（PRD），因为我无法在生产环境中重建数据容器，而且在没有解决这个问题之前，我不想更改任何配置。目前它只是停止运行，并报错：`discourse@discourse FATAL: terminating connection due to administrator command`。

[上一頁](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413.md?page=2)

[下一頁](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413.md?page=4)
