因为在VPS上有PostgreSQL的数据,我把它完整地复制到了WSL的Docker中,作为备忘录

Background.

如果在各个地方创建开发环境,那么每次搬迁数据库都会变得很麻烦,所以将/var/lib/postgresql目录下的PostgreSQL原始数据全部复制到本地,并在本地的Docker中加载它们。

环境

由于我之前没有相关知识,所以在VPS中同时运行了不同版本的Postgresql,并且目录结构也相应地设置了。因此,请您在阅读下面的方法时要明确考虑到这一前提。
VPS的操作系统是Ubuntu。
之所以使用WSL作为迁移目标环境,只是因为我想在本地方便地进行验证(这只是个人爱好和学习用途,而不是工作数据)。如果您平时使用的是Mac电脑,那么某些步骤将不再需要。

途径

基本上,我们计划将Postgres的Docker镜像中的/var/lib/postgresql/data目录持久化构建,并在停止后直接替换其中的内容。然而,这并不是一件容易的事情,所以我们使用docker-compose logs -f命令查看错误消息,并补充缺失的东西。请注意,无法保证文件不会消失或被覆盖,请备份好数据。

总结起来,我写了以下这样的docker-compose.yml文件。

version: '3'

services:
  postgres:
    image: postgres:10.21-alpine
    user: '1000:1000'
    volumes:
      - ./etc/passwd:/etc/passwd:ro
      - ./etc/group:/etc/group:ro
      - ./data2:/var/lib/postgresql/data
      - ./data:/var/lib/postgresql/10/main
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      - ./conf2:/etc/postgresql
      - ./conf:/etc/postgresql/10/main
      - ./etc/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
      - ./etc/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key:ro
      - ./tmp:/var/run/postgresql/10-main.pg_stat_tmp
    ports:
      - 5434:5432
    environment:
      POSTGRES_PASSWORD: postgres
    command: -c 'config_file=/etc/postgresql/postgresql.conf'

所以,目录结构应该是这样的。/conf和/data目录下的各种文件都需要完整复制。其他文件需要逐个搜索并复制。方法将在后文中介绍。

.
├── conf
│   ├── conf.d
│   ├── environment
│   ├── pg_ctl.conf
│   ├── pg_hba.conf
│   ├── pg_ident.conf
│   ├── postgresql.conf
│   └── start.conf
├── conf2
│   ├── conf.d
│   ├── environment
│   ├── pg_ctl.conf
│   ├── pg_hba.conf
│   ├── pg_ident.conf
│   ├── postgresql.conf
│   └── start.conf
├── data
│   ├── PG_VERSION
│   ├── base
│   ├── global
│   ├── pg_commit_ts
│   ├── pg_dynshmem
│   ├── pg_logical
│   ├── pg_multixact
│   ├── pg_notify
│   ├── pg_replslot
│   ├── pg_serial
│   ├── pg_snapshots
│   ├── pg_stat
│   ├── pg_stat_tmp
│   ├── pg_subtrans
│   ├── pg_tblspc
│   ├── pg_twophase
│   ├── pg_wal
│   ├── pg_xact
│   ├── postgresql.auto.conf
│   ├── postmaster.opts
│   └── postmaster.pid
├── data2
├── docker-compose.yml
├── docker-entrypoint-initdb.d
├── etc
│   ├── group
│   ├── passwd
│   ├── ssl-cert-snakeoil.key
│   └── ssl-cert-snakeoil.pem
└── tmp

关于docker-compose.yml文件,按顺序逐一解释。

    image: postgres:10.21-alpine

为了加载数据,必须将postgresql的版本与迁移前的版本保持一致(我认为)。由于版本是10.21,所以决定使用10.21的alpine镜像。

    user: '1000:1000'
    volumes:
      - ./etc/passwd:/etc/passwd:ro
      - ./etc/group:/etc/group:ro

这部分是按照以下的Qiita文章中的方法来做的。在这里的说明省略了。

 

根据链接说明创建./etc/passwd和./etc/group文件。文件内容与原文一样,直接复制粘贴即可(无需先启动alpine镜像然后提取./etc/passwd的步骤)。

      - ./data2:/var/lib/postgresql/data
      - ./data:/var/lib/postgresql/10/main
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      - ./conf2:/etc/postgresql
      - ./conf:/etc/postgresql/10/main

将数据和conf文件组放置。
第一行只是为了在第一次启动时检查持续化数据是否正确保存到Windows端,因此可能不必要。
第二行中,将从VPS复制来的数据放在./data中。
第三行是要放置想要运行的初始SQL文件的目录,但这里与本次无关,因此没有放置任何文件。
第四行,在参考网络文章时,不小心将command: -c ‘config_file=/etc/postgresql/postgresql.conf’写在了docker-compose.yml的最后一行,因此Docker镜像首先会在这个目录中查看是否有conf文件,虽然是冗余的,但仍然将./conf2配置为与./conf相同的文件结构,并编写了这行。
第五行是最终要读取的conf文件组,其中也包括pg_hba.conf等文件。在这里可以信任本地访问(稍后会执行)。

      - ./etc/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
      - ./etc/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key:ro

我复制粘贴了VPS上生成的自签名证书。不知为何,却被告知没有它就不能运行。可能是之前的配置造成的,但既然复制粘贴可以运行,那就暂且算了!
第二行是指定了”:ro”,但被告知文件必须是0600,于是我指定了,但结果并不是这样,在WSL(安装了ubuntu等操作系统)上必须运行chmod 0600,才能正常工作。

      - ./tmp:/var/run/postgresql/10-main.pg_stat_tmp

为什么tmp目录没有自动生成呢?可能是因为使用了alpine系统。当我毫无考虑地创建了上述行和tmp目录后,它就正常运行了。

完成以上的操作,請執行 docker-compose up -d –build,然後立即執行 docker-compose logs -f。如果沒有出現錯誤,則表示成功。

由於在VPS上公開了Web應用程式,我們根據 pg_hba.conf 做了密碼驗證和限制可訪問的資料庫等相關設定。但我們需要修改這些設定(不是 conf2,而是 conf 目錄)。在 WSL 的 Ubuntu 上安裝 psql,並連接到 port=5434(任意設定),應該可以進行內容的確認。

请用中文重新表达以下内容,只需要提供一种选项:

“I’m sorry, but I cannot make it to the meeting tomorrow due to a scheduling conflict. Can we reschedule it for another time?”

广告
将在 10 秒后关闭
bannerAds