Meteorjs和Meteor-Up MongoDB迁移到新的主要版本ðIS
#javascript #教程 #meteor #mongodb

问题:您有一个与MUP一起部署的流星应用程序,并且自年龄以来运行可靠,但是它使用了旧的MongoDB版本。现在,您无法将流星更新为新版本,因为它需要MongoDB(related issue here)的较新版本。

就我而言,这是一个旧的mongodb版本3.4.1,它仍在服务器上运行。流星释放为2.7.3,需要mongodb 5+。仅仅增加mup.js配置中的MongoDB版本就无法解决(请参阅即将到来的部分)。

ðä本教程将通过整个升级过程指导您。主要重点是确保数据安全,因此您将获得良好且顺利的升级体验。

!¸免责声明:我对与本教程所涉及的任何步骤有关的任何问题概不负责。此外,本文包含会员链接,标有*


如果您试图部署无论如何都会发生什么

我已经知道它不起作用,因为我定期阅读Meteor changelog,以及他们的announcements in the Meteor forums*the Meteor blog*。但是,我想测试一个登台实例,无论如何它是否可以工作。

当然,它没有用:

Started TaskList: Start Meteor
[xxx.xxx.xxx.xxx] - Start Meteor
[xxx.xxx.xxx.xxx] - Start Meteor: SUCCESS
[xxx.xxx.xxx.xxx] - Verifying Deployment
[xxx.xxx.xxx.xxx] x Verifying Deployment: FAILED

          ------------------------------------STDERR------------------------------------
(7) Failed to connect to 172.17.0.2 port 3000: Connection refused
=> Logs:
=> Setting node version
NODE_VERSION=14.18.3
v14.18.3 is already installed.
Now using node v14.18.3 (npm v6.14.15)
default -> 14.18.3 (-> v14.18.3 *)
=> Starting meteor app on port 3000
/built_app/programs/server/node_modules/fibers/future.js:313                        throw(ex);
                            ^
    MongoServerSelectionError: Server at mongodb:27017 reports maximum wire version 5, but this version of the Node.js Driver requires at least 6 (MongoDB 3.6)

ð〜节省了麻烦并跳过此步骤!

最好的是,您甚至不尝试此事,而是为迁移做好准备。


手动迁移的替代方案

如果您已经在自己的服务器上迁移MongoDB版本遇到麻烦,那么您可能需要尝试使用托管的MongoDB托管服务和Meteor cloud*,因为它们可以完美工作!


迁移概述 -

对于完全工作的迁移到新的主要版本的mongoDB,我们需要执行以下步骤:

  • 准备迁移的系统
  • 备份您的当前数据
  • 卸下所有Docker容器
  • 删除所有mongoDB数据
  • 更新mupmup.js
  • 用MUP设置新环境
  • SSH进入服务器
  • 添加SSH2设置(支持RSA)https://github.com/zodern/meteor-up/issues/1318
  • 将MongoDB数据还原为新的DB
  • 部署应用程序

迁移的准备

为了使迁移尽可能流利,您应该做好充分的准备。确保在您的末端检查所有下一步!

步骤1-安装最新的mup

$ meteor npm install -g mup

ðd注意,应该在全球安装mup

步骤2 -SSH和SCP

确保您可以使用SSH访问服务器。您可以通过更改为部署目录(您的mup.js文件所在的位置)并运行meteor mup ssh

您还需要scp,因此请确保它已安装在系统上。

如果您使用的是SSH的RSA密钥,并且您的服务器在Ubuntu Server上使用22.04或更新的koude4 will not be able to do requests via ssh ("All configured authentication methods failed").

您必须应用解决方法以使mup使用SSH或(更好)使用ed25519方法代替rsa

如果您需要使用RSA键,则需要SSH进入服务器并执行以下操作:

user@target-server:~# sudo echo "PubkeyAcceptedKeyTypes=+ssh-rsa" >> /etc/ssh/sshd_config
user@target-server:~# sudo systemctl restart sshd.service

ðÖ我假设您不是ssh作为根,但是,如果这样做,请忽略sudo命令

步骤3-准备好您的mup.js文件

必须检查码头图像与您将部署的新流星版本兼容。一个很好的选择是zodern docker images

还要在配置中检查MongoDB版本,因为它至少应为5.0.0

如果已经编译了可能给出的最小mup.js配置,以防您来自较旧的mup版本:

module.exports = {
  servers: {
    one: {
      host: 'XXX.XXX.XXX.XXX',
      username: 'www-user'
    }
  },

  app: {
    name: 'myApp',
    path: '../',

    servers: {
      one: {},
    },

    buildOptions: {
      serverOnly: true,
    },

    env: {
      // If you are using ssl, it needs to start with https://./de
      ROOT_URL: 'https://myapp.tld',
      MONGO_URL: 'mongodb://localhost/meteor',
      MONGO_OPLOG_URL: 'mongodb://mongodb/local',
      HTTP_FORWARDED_COUNT: 1,
      port: 8080,
      // other env flags, like
      // MAIL_URL etc.
    },

    docker: {

      image: 'zodern/meteor:latest',

      // if you need run build instructions as ROOT, see
      // https://github.com/zodern/meteor-docker/issues/20
      // buildInstructions: [],


      // (optional) It is set to true when using a docker image
      // that is known to support it. Builds a new docker image containing the
      // app's bundle and npm dependencies to start the app faster and
      // make deploys more reliable and easier to troubleshoot
      prepareBundle: true,

      // (optional, default is false) Uses the new docker image builder
      // during Prepare bundle. When enabled,
      // Prepare Bundle is much faster
      useBuildKit: true,
    },

    // Show progress bar while uploading bundle to server
    // You might need to disable it on CI servers
    enableUploadProgressBar: true
  },

  mongo: {
    version: '5.0.5',
    servers: {
      one: {}
    }
  },

  // (Optional)
  // Use the proxy to setup ssl or to route requests to the correct
  // app when there are several apps

  proxy: {
    domains: 'myapp.tld',
    ssl: {
      forceSSL: true,
      // Enable let's encrypt to create free certificates.
      // The email is used by Let's Encrypt to notify you when the
      // certificates are close to expiring.
      letsEncryptEmail: 'webmaster@myapp.tld'
    },
    clientUploadLimit: '500M'
  }
}

步骤4-打开一个新的终端窗口

打开一个新的,干净的终端窗口,为整个教程保持打开!< / strong>我们将在教程期间使用一些本地壳变量,然后将其放开,一旦窗口 / TAB关闭!

ð了当然,我可以单个脚本提供整个教程,但是您不会学到那么多。此外,这样的脚本仍然需要大量的配置或互动,超出了本教程的范围。


迁移ð§ð§§

现在是时候完成此操作了。抓住您选择的热饮料,静音手机,并确保您可以在接下来的30到60分钟内100%聚焦。


步骤1-备份当前数据

首先,您应该为备份文件创建本地目录。确保此目录要么超出您的项目或.gitignore的一部分,否则您可以在GIT存储库中检查生产数据!

$ mkdir -p ~/backups/myapp/

现在,您可以使用sshscp和Docker命令的组合来创建备份并将其“下载”到本地文件夹。

为了使事情更容易理解,您可以使用一些局部变量来准备命令:

$ BAK_PATH=~/backups/myapp/ # don't use quotes here!
$ BAK_SSH_PATH="user@xxx.xxx.xxx.xxx" # your ssh login, basically
$ BAK_DB_NAME="myApp" # usually the "app" field in mup.js, beware of case-sensitivity!
$ BAK_FILE="$BAK_DB_NAME-mongodump-$(date +%Y-%m-%d-%H-%M).gz"
$ BAK_TEMP_ARCHIVE_DOCKER="/root/mongodump.gz" # backup archive path within docker container
$ BAK_TEMP_ARCHIVE="~/$BAK_FILE" # backup archive path on server os

现在构造SSH命令以生成服务器上的DB转储:

$ ssh -t $BAK_SSH_PATH "sudo docker exec -it mongodb mongodump --archive=$BAK_TEMP_ARCHIVE_DOCKER --gzip --quiet && sudo docker cp mongodb:$BAK_TEMP_ARCHIVE_DOCKER $BAK_TEMP_ARCHIVE"
# be patient, don't cancel...

ð了这里会发生什么?

命令告诉您的MongoDB容器将mongodump运行到容器拥有的Path /root/mongodump.gz,然后立即将此文件复制到服务器的文件系统(加上将其重命名为myapp-mongodump-2023-02-01-10-13.gz之类的东西)。

)。

最后,您可以使用scp将此文件下载到本地文件系统。另外,您也可以将其上传一些外部服务器或S3存储器或用于存储备份的任何位置。

$ scp $BAK_SSH_PATH:$BAK_TEMP_ARCHIVE $BAK_PATH
myapp-mongodump-2023-02-01-10-18.gz       100%  150MB   6.7MB/s   00:22    
$ ls -la $BAK_PATH # verify file has been downloaded
total 153420
drwxrwxr-x 2 user user      4096 Feb  1 10:23 .
drwxrwxr-x 3 user user      4096 Feb  1 10:17 ..
-rw-r--r-- 1 user user 157086575 Feb  1 10:24 myapp-mongodump-2023-02-01-10-18.gz

从这里,您可以将备份导入到本地流星开发设置中并查找错误。我很快就会为此添加一个自己的教程。


步骤2-擦除服务器中的数据和容器ð§¹

警告!从这里,您将删除内容,这可能会破坏您的设置而无需恢复。确保您的DB备份完整性就足够了。

转到您的.deploy文件夹(或包含mup.js文件的文件夹)并停止 /销毁一切:

$ cd .deploy
$ meteor mup stop
Started TaskList: Stop Meteor
[xxx.xxx.xxx.xxx] - Stop Meteor
[xxx.xxx.xxx.xxx] - Stop Meteor: SUCCESS
$ meteor mup mongo stop
Started TaskList: Stop Mongo
[xxx.xxx.xxx.xxx] - Stop Mongo
[xxx.xxx.xxx.xxx] - Stop Mongo: SUCCESS
$ meteor mup meteor destroy --force
The app will be completely removed from the server.
Waiting 5 seconds in case you want to cancel by pressing ctr + c

Started TaskList: Destroy App
[xxx.xxx.xxx.xxx] - Stop App
[xxx.xxx.xxx.xxx] - Stop App: SUCCESS
[xxx.xxx.xxx.xxx] - Destroy App
[xxx.xxx.xxx.xxx] - Destroy App: SUCCESS

现在,SSH进入服务器并删除存储在容器外的MongoDB数据:

ðÖ警告!下一步删除了所有mongoDB数据!

$ ssh $BAK_SSH_PATH
user@target-server:~# rm -rf /opt/mongodb
user@target-server:~# rm -rf /var/lib/mongodb
user@target-server:~# exit

现在我们有一个“干净”状态来设置新环境。

...

步骤3-设置新环境,MUP 1.5+±±

停留在您的部署文件夹中,并确保它包含更新的mup.js文件(请参阅带有示例文件的准备部分)。然后运行以下命令:

$ meteor mup setup

Started TaskList: Setup Docker
[xxx.xxx.xxx.xxx] - Setup Docker
[xxx.xxx.xxx.xxx] - Setup Docker: SUCCESS

Started TaskList: Setup Meteor
[xxx.xxx.xxx.xxx] - Setup Environment
[xxx.xxx.xxx.xxx] - Setup Environment: SUCCESS

Started TaskList: Setup Mongo
[xxx.xxx.xxx.xxx] - Setup Environment
[xxx.xxx.xxx.xxx] - Setup Environment: SUCCESS
[xxx.xxx.xxx.xxx] - Copying Mongo Config
[xxx.xxx.xxx.xxx] - Copying Mongo Config: SUCCESS

Started TaskList: Start Mongo
[xxx.xxx.xxx.xxx] - Start Mongo
[xxx.xxx.xxx.xxx] - Start Mongo: SUCCESS

Started TaskList: Setup proxy
[xxx.xxx.xxx.xxx] - Setup Environment
[xxx.xxx.xxx.xxx] - Setup Environment: SUCCESS
[xxx.xxx.xxx.xxx] - Pushing the Startup Script
[xxx.xxx.xxx.xxx] - Pushing the Startup Script: SUCCESS
[xxx.xxx.xxx.xxx] - Pushing Nginx Config Template
[xxx.xxx.xxx.xxx] - Pushing Nginx Config Template: SUCCESS
[xxx.xxx.xxx.xxx] - Pushing Nginx Config
[xxx.xxx.xxx.xxx] - Pushing Nginx Config: SUCCESS
[xxx.xxx.xxx.xxx] - Cleaning Up SSL Certificates
[xxx.xxx.xxx.xxx] - Cleaning Up SSL Certificates: SUCCESS
[xxx.xxx.xxx.xxx] - Configure Nginx Upstream
[xxx.xxx.xxx.xxx] - Configure Nginx Upstream: SUCCESS

Started TaskList: Start proxy
[xxx.xxx.xxx.xxx] - Start proxy
[xxx.xxx.xxx.xxx] - Start proxy: SUCCESS

您可以使用meteor mup status验证安装,也可以通过meteor mup mongo shell直接使用MongoDB Interactive Shell。如果看起来一切都不错,那么您可以继续下一步并将备份还原到新的DB中。


步骤4-将MongoDB数据恢复到新的db –â项中

首先,确保服务器上仍存在备份。如果没有,请通过scp上传:

$ scp $BAK_PATH $BAK_SSH_PATH:$BAK_TEMP_ARCHIVE

然后SSH进入服务器,然后将文件移至Docker容器中并运行mongorestore

$ ssh $BAK_SSH_PATH
user@target-server:~# docker cp ./myapp-mongodump-2023-02-01-10-18.gz mongodb:/root/mongodump.gz

文件已复制,现在打开mongodb容器的交互式外壳:

user@target-server:~#  docker exec -it mongodb /bin/bash
root@mongodb:/#

您不在容器中,现在可以执行mongorestore命令:

root@mongodb:/# mongorestore --archive="/root/mongodump.gz" --gzip --verbose --convertLegacyIndexes --nsInclude="myapp.*"
# ... long verbose output
2023-02-01T10:14:00.937+0000    2425 document(s) restored successfully. 0 document(s) failed to restore.

还原包括档案(我们在/root/mongodump.gz下的容器中复制到容器中),GZIP标志和要包括的名称空间(在我们的情况下是myapp.*)(包括myapp数据库中的所有集合)。

请注意,需要--convertLegacyIndexes来确保您的索引仍在使用新DB。

如果您的所有文档都成功恢复,您可以退出容器外壳和SSH,然后继续部署新应用。


步骤5-部署应用程序ð

最后,您可以使用
部署应用程序

$ meteor mup deploy

从这里开始,一切都应该按以前的方式工作,但是现在运行了更新的流星和mongodb。


故障排除ð§

MongoServerError:E11000重复密钥错误集合:myApp.Roles索引:name_1 dup键:{name:null}

打开mongo shell并删除索引:

$ meteor mup mongo shell
meteor:PRIMARY> use myapp
meteor:PRIMARY> db.roles.dropIndexes()
exit
$ meteor mup meteor restart

Outlook:自动化本教程

我强烈建议将这些步骤包含在代码中以进行进一步自动化。您可以尝试将其写入BASH脚本或Nodejs CLI工具。另请注意,涉及的许多步骤将SSH手动进入服务器或为Docker容器打开外壳。

通常不需要手动处理这些步骤。


来源


关于我

我在dev.to上定期发布文章,大约流星 javascript

您还可以在GitHubTwitterLinkedIn上找到(并与我联系)。

如果您喜欢阅读的内容并想支持我,则可以sponsor me on GitHubsend me a tip via PayPal

通过访问their blog*来跟上流星的最新发展,如果您像我一样进入流星并想向世界展示,则应查看Meteor merch store*