Fork me on GitHub

在无法联网的生产环境部署nocobase

由于生产环境不连接外网,您需要在联网的本地环境中提前准备好所有必要的Docker镜像、数据文件和配置文件,并通过U盘等方式传输到生产环境。根据服务器是否已安装Docker,部署步骤会有所不同。以下是完整的操作指南。

前提说明:

我用Docker运行了NocoBase,并配置了系统,现在想将该修改后的系统通过Docker部署到云服务器上。已知该项目有三个容器,镜像为:官方NocoBase、MySQL和运行了Flask的服务。

同时通过查看docker inspect,发现Mounts中使用了bind挂载,有一部分关键数据(如上传文件、缓存、插件存储等)存放在本地挂载目录中。我已经成功部署到测试用云服务器上,但现在需要将系统部署到不连接外网的生产环境,需要使用U盘拷贝等方式完成部署。请问如何按照“打包为镜像,部署到云服务器”的方法进行部署,要拷贝哪些东西,并分情况告诉我具体的部署实施步骤,情况1: Linux服务器已安装好了Docker;情况2: Linux服务器没有安装Docker。

文件层级为:

1
2
3
4
5
6
7
8
9
10
11
12
app
├── docker-compose.yml
├── flask_service
├── app.py
├── Dockerfile
└── requirements.txt
└── storage
├── apps
├── db
├── nocobase.conf
├── plugins
└── uploads

概述

由于生产环境不连接外网,您需要在联网的本地环境中提前准备好所有必要的Docker镜像、数据文件和配置文件,并通过U盘等方式传输到生产环境。根据服务器是否已安装Docker,部署步骤会有所不同。以下是完整的操作指南。


准备工作(在本地联网环境)

为了确保生产环境能够完整运行NocoBase系统,您需要准备以下内容:

  1. 保存Docker镜像

    • NocoBase镜像:假设使用的是官方镜像 registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest

      1
      2
      docker pull registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest
      docker save -o nocobase.tar registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest
    • MySQL镜像:假设使用的是 mysql:8.0

      1
      2
      docker pull mysql:8.0
      docker save -o mysql.tar mysql:8.0
    • Flask服务镜像:假设您已构建了一个自定义的Flask服务镜像 flask-service

      1
      2
      3
      cd flask_service  # 进入Flask服务的项目目录
      docker build -t flask-service . # 构建镜像
      docker save -o flask-service.tar flask-service # 保存镜像
  2. 备份MySQL数据库

    • 进入运行中的MySQL容器,备份数据库(假设数据库名为 nocobase,用户为 root,密码为 XXX):

      1
      docker exec -it mysql mysqldump -u root -pXXX nocobase > nocobase_backup.sql
  3. 打包本地挂载目录

    • 根据docker inspect的结果,关键数据存储在本地挂载目录 ./storage 中(包括上传文件、缓存、插件存储等)。将该目录压缩:

      1
      tar -czvf storage.tar.gz ./storage
  4. 准备docker-compose.yml

    • 复制您当前使用的 docker-compose.yml 文件,确保其中定义了NocoBase、MySQL和Flask服务及其挂载卷配置。稍后在云服务器上需要调整路径。
  5. (仅情况2)下载Docker和docker-compose安装包

需要传输的文件

将以下文件拷贝到U盘,传输到生产环境:

  • 所有情况

    • nocobase.tar(NocoBase镜像)
    • mysql.tar(MySQL镜像)
    • flask-service.tar(Flask服务镜像)
    • nocobase_backup.sql(MySQL数据库备份)
    • storage.tar.gz(本地挂载目录压缩包)
    • app.py(Flask服务挂载文件)
    • docker-compose.yml(服务配置文件)
  • 仅情况2(服务器未安装Docker)

    • docker-ce_xxx.deb(Docker安装包)
    • docker-compose(docker-compose二进制文件)

部署步骤

情况1:Linux服务器已安装Docker
  1. 传输文件

    • 使用U盘将上述文件拷贝到云服务器,例如放置在 /root/nocobase_deploy 目录下。
  2. 加载Docker镜像

    • 将保存的镜像加载到服务器的Docker环境中:

      1
      2
      3
      docker load -i nocobase.tar
      docker load -i mysql.tar
      docker load -i flask-service.tar
    • 1⃣️因flask-service是

      • 开发环境(联网):通过 build 配置从 flask_service 目录构建 flask-service 镜像,允许开发者修改代码并重新构建。

      • 生产环境(离线):使用已导入的 flask-service.tar 镜像(通过 docker load),不依赖联网拉取基础镜像(python:3.11-slim)或重新构建。

    • 2⃣️所以在生产环境中,修改 docker-compose.yml

    • build:
        context: ./flask_service
        dockerfile: Dockerfile
        
      改为
      
      image: flask-service:latest
      
      1
      2
      3
      4
      5
      6
      7

      3. **解压storage目录**

      - 解压挂载目录到指定路径:

      ```bash
      tar -xzvf storage.tar.gz -C /root/nocobase_deploy/
  3. 调整docker-compose.yml

    • 编辑 docker-compose.yml,确保挂载卷路径与云服务器上的实际路径一致(检查volumes)。例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      services:
      mysql:
      image: mysql:8.0
      volumes:
      - mysql_data:/var/lib/mysql
      - /root/nocobase_deploy/storage/uploads/python_statistic:/var/lib/mysql-files
      environment:
      MYSQL_ROOT_PASSWORD: XXXXXXXXXXXXX
      MYSQL_DATABASE: nocobase
      app:
      image: registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest
      volumes:
      - /root/nocobase_deploy/storage:/app/nocobase/storage
      ports:
      - "13000:13000"
      flask:
      image: flask-service
      volumes:
      - /root/nocobase_deploy/storage/uploads/python_statistic:/app/uploads
      ports:
      - "5000:5000"
      volumes:
      mysql_data:
    • 根据实际需求调整端口映射和环境变量。

  4. 启动服务

    • docker-compose.yml 所在目录运行:

      1
      docker compose up -d
  5. 恢复MySQL数据库

    • 确保MySQL容器已启动,然后将备份数据导入:

      1
      docker exec -i [mysql] mysql -u root -pXXXXXXXXXXXXXXXXXX nocobase < nocobase_backup.sql

情况2:Linux服务器没有安装Docker
  1. 传输文件

    • 使用U盘将情况1的所有文件以及 docker-ce_xxx.rpmdocker-compose 拷贝到云服务器,例如放置在 /root/nocobase_deploy 目录下。
  2. 安装Docker

    • 安装Docker软件包:

      1
      yum localinstall -y *.rpm
    • 安装成功后,继续启动 Docker:

      1
      2
      3
      systemctl enable docker
      systemctl start docker
      docker version
  3. 安装docker-compose

    • 安装docker-compose:

      1
      2
      cp docker-compose /usr/local/bin/
      chmod +x /usr/local/bin/docker-compose
    • 验证安装:

      1
      docker compose version
  4. 后续步骤

    • 按照情况1的步骤2-6执行:
      • 加载Docker镜像
      • 解压storage目录
      • 调整docker-compose.yml
      • 启动服务
      • 恢复MySQL数据库

验证

部署完成后,执行以下操作确认系统正常运行:

  • 检查容器状态:

    1
    docker ps
  • 访问NocoBase服务(默认端口13000)和Flask服务(默认端口5000),确保功能正常。


注意事项

  • 路径一致性:云服务器上的挂载路径必须与 docker-compose.yml 中的配置一致。
  • 数据库密码:备份和恢复数据库时使用的密码需与 docker-compose.yml 中的 MYSQL_ROOT_PASSWORD 保持一致。
  • 架构兼容性:确保本地和云服务器的CPU架构一致(如均为x86_64),否则需在对应架构下重新构建镜像。
  • 端口冲突:检查云服务器上的端口(13000、5000等)是否被占用,必要时修改端口映射。

📦 推荐打包备份命令(可选)

你也可以打一个压缩包:

1
tar czvf nocobase_full_backup_$(date +%Y%m%d).tar.gz nocobase_backup.sql storage/

总结

通过上述步骤,您可以将修改后的NocoBase系统(包括NocoBase、MySQL和Flask服务)成功部署到不联网的生产环境。关键在于提前打包镜像、备份数据和挂载目录,并在目标服务器上正确恢复和配置。

✅ 总结部署流程图(简略版)

1
2
3
4
5
6
7
8
9
10
11
12
联网电脑 ——> 打包镜像 + 数据 + 配置
|

拷贝到U盘

插入目标服务器
┌──────────────────────┐
│ 情况一:已安装Docker │ → load镜像 → 启动compose → 导入DB
└──────────────────────┘
┌──────────────────────┐
│ 情况二:无Docker环境 │ → 离线安装 → 同上
└──────────────────────┘

不重新打包镜像,直接修改 Docker 容器中的 app.py 代码

通过以下方式将本地修改后的 app.py 复制到容器,但不推荐直接修改容器文件:直接编辑容器内的 app.py 是临时的,容器重启后修改会丢失,因为容器是基于镜像的快照运行的。

1
docker cp /path/to/local/app.py my_container:/path/to/container/app.py

附件一:docker-compose.yml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
networks:
nocobase:
driver: bridge
services:
mysql:
image: mysql:8.0
restart: always
networks:
- nocobase
environment:
MYSQL_ROOT_PASSWORD: XXXXXXXXXXXXXXXXXXXXXXXXXXX
MYSQL_DATABASE: nocobase
MYSQL_USER: nocobase
MYSQL_PASSWORD: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- /root/lee/nocobase/storage/uploads/python_statistic:/var/lib/mysql-files
command: --secure-file-priv=/var/lib/mysql-files
app:
image: registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest
restart: always
networks:
- nocobase
depends_on:
- mysql
environment:
- APP_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- DB_DIALECT=mysql
- DB_HOST=mysql
- DB_DATABASE=nocobase
- DB_USER=nocobase
- DB_PASSWORD=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- DB_UNDERSCORED=true
- TZ=Asia/Shanghai
- NOCOBASE_PKG_USERNAME=
- NOCOBASE_PKG_PASSWORD=
volumes:
- ./storage:/app/nocobase/storage
ports:
- "13000:80"
flask:
build:
context: ./flask_service
dockerfile: Dockerfile
container_name: excel-importer
restart: always
networks:
- nocobase
environment:
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- MYSQL_USER=nocobase
- MYSQL_PASSWORD=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- MYSQL_DATABASE=nocobase
volumes:
- /root/lee/nocobase/storage/uploads/python_statistic:/app/uploads
ports:
- "5000:5000"
depends_on:
- mysql
volumes:
mysql_data:

附件二:flask服务的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM python:3.11-bullseye
# 使用清华源,加速 apt
RUN sed -i 's|http://deb.debian.org|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list && \
apt-get update && apt-get install -y \
gcc \
libpq-dev \
python3-dev \
build-essential \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
COPY . .
CMD ["python", "app.py"]

相关问答

  1. 我使用root用户安装docker成功了,切换成普通用户执行 docker load -i时报错权限不足

    这是因为默认情况下,普通用户不能访问 Docker 守护进程(dockerd)

    方法:将普通用户加入 docker 用户组

    1. 创建 docker 组(如果不存在)
    1
    sudo groupadd docker
    1. 将当前用户添加到 docker
    1
    sudo usermod -aG docker your_username

    请将 your_username 替换成你的普通用户名。

    1. 重新登录当前用户(重要!必须重新登录或重启 shell 才能生效):
    • 可以使用 su - your_username 重新登录,或直接重新 SSH 登录。
    1. 测试是否能成功运行 docker 命令
    1
    docker load -i your_image.tar
  2. 没有 /usr/local/bin/ 的写权限,怎么安装docker-compose

    解决方法:安装到本地用户目录(无需 root 权限)
    你可以将文件放在自己的用户目录下的 bin/ 文件夹,并将其加入 PATH:

    1
    2
    3
    mkdir -p ~/bin
    mv docker-compose-Linux-x86_64 ~/bin/docker-compose
    chmod +x ~/bin/docker-compose

    然后在 ~/.bashrc~/.bash_profile 中添加如下行(如果尚未添加):

    1
    export PATH=$HOME/bin:$PATH

    执行以下命令使其立即生效:
    1
    source ~/.bashrc

    然后你就可以通过 docker-compose 命令使用它了(注意路径):
    1
    docker-compose version

  3. root用户能否将某路径的文件权限向普通用户开放

    把某个路径(例如 /opt/docker_images)及其 所有子文件和子文件夹 的所有权转交给用户 user1,可以使用下面这个命令:一次性更改整个路径及其所有子项的所有者:

    1
    >chown -R user1:user1 /opt/docker_images
-------------The End-------------