news 2026/5/16 3:18:15

Docker工作空间镜像:构建标准化开发环境的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker工作空间镜像:构建标准化开发环境的完整指南

1. 项目概述:一个神秘的“工作空间”镜像

最近在整理Docker镜像仓库时,发现了一个名字相当长的镜像:metagalaxy-crystal/copaw_workspace_default_20260329_075700。这个名字乍一看有点让人摸不着头脑,既不像常见的Web服务(如nginx),也不像标准的基础环境(如python:3.11)。它更像是一个特定项目在某个时间点(2026年3月29日07:57:00)构建的、用于某种“工作空间”的完整环境快照。对于开发者、运维工程师,或者任何需要快速复现一个复杂开发环境的人来说,这类镜像的价值不言而喻。它意味着你可以跳过繁琐的依赖安装、环境配置,直接获得一个开箱即用、状态已知的标准化工作环境。

这个镜像的命名本身就蕴含了大量信息。metagalaxy-crystal很可能是组织或项目名称,copaw可能是某个内部工具、平台或项目的代号,workspace_default指明了这是一个默认的工作空间配置,而最后的时间戳20260329_075700则精确记录了它的构建时刻。这种命名方式在CI/CD流水线或自动化构建系统中非常典型,用于追踪和版本化管理环境。本文将深入拆解这类“工作空间”镜像的核心价值、内部构造、使用场景以及如何基于它进行高效的开发和协作。无论你是想理解这个特定镜像的用途,还是希望为自己的团队构建类似的环境标准化方案,这篇文章都将提供从原理到实操的完整指南。

2. 工作空间镜像的核心价值与设计思路

2.1 为什么需要“工作空间”镜像?

在软件开发中,“环境问题”一直是困扰团队协作和项目上线的经典难题。“在我机器上是好的”这句调侃背后,是操作系统差异、系统库版本、语言运行时、依赖包版本、环境变量配置等一系列复杂因素交织成的泥潭。Docker容器技术通过隔离和镜像标准化,为这个问题提供了优雅的解决方案。而“工作空间”镜像,则是这一方案的更进一步。

一个标准的应用运行镜像(比如一个跑Python Flask应用的镜像)通常只包含运行应用所必需的最小依赖。而一个“工作空间”镜像,其定位是一个完整的开发沙箱。它除了包含运行环境,更包含了开发、调试、测试所需的全套工具链。想象一下,新成员加入项目,不再需要花费一两天甚至更长时间来照着冗长的README.md配置环境,他只需要一条docker run命令,就能获得一个与所有老成员完全一致的、包含IDE插件、代码格式化工具、调试器、测试框架、数据库客户端甚至内部CLI工具的桌面级开发环境。这极大地降低了协作成本,加速了 onboarding 流程。

对于copaw_workspace_default_20260329_075700这样的镜像,其设计目标很可能就是为copaw项目提供这样一个标准化的开发环境。default后缀意味着可能还存在其他变体,比如copaw_workspace_gpu(包含GPU计算支持)或copaw_workspace_minimal(精简版)。时间戳则确保了环境的可追溯性,你可以精确知道某个Bug是在哪个基础环境版本下引入或发现的。

2.2 镜像内容深度解析:里面到底有什么?

要理解一个工作空间镜像,最直接的方式就是“打开看看”。虽然我们无法直接获取metagalaxy-crystal的私有镜像,但我们可以推断其典型内容构成,并学习如何分析一个已有的类似镜像。

一个完备的工作空间镜像,其Dockerfile通常会采用多阶段构建,并包含以下层次:

  1. 基础操作系统层:通常选择一个平衡了稳定性和软件包新鲜度的Linux发行版,如Ubuntu LTS、Debian或Alpine(如果对体积敏感)。这一层提供了最底层的系统库和包管理工具。
  2. 语言与运行时层:根据项目技术栈安装特定版本的语言环境。例如,对于Python项目,会通过pyenv或直接安装指定版本的Python、pip、virtualenv;对于Node.js项目,则会安装nvm和特定版本的Node、npm/yarn/pnpm。
  3. 系统依赖与工具层:安装编译工具(gcc, make, cmake)、版本控制工具(git)、网络工具(curl, wget)、数据库客户端(mysql-client, postgresql-client)、容器工具(Docker CLI, kubectl)等通用开发工具。
  4. 项目特定依赖层:这是核心。会拷贝项目的依赖声明文件(如requirements.txt,package.json,go.mod),并执行安装命令。这一步确保了所有第三方库的版本被锁定。
  5. 开发工具与配置层:安装代码编辑器(如VSCode Server)、语言服务器(如pylance, rust-analyzer)、代码格式化工具(black, prettier)、静态检查工具(flake8, eslint)。还会预置一些开发配置,如.bashrc别名、git配置模板、IDE的settings.json片段等。
  6. 入口点与健康检查层:定义容器启动时的默认行为。对于工作空间镜像,入口点可能是一个保持容器运行的脚本(如tail -f /dev/null),或者直接启动一个代码服务器(如code-server)的Web服务。

注意:一个常见的误区是把项目源代码也打包进工作空间镜像。这通常不是最佳实践。源代码应该通过卷挂载(docker run -v)的方式动态映射到容器内。这样做的好处是,容器外的代码编辑能实时反映在容器内,并且镜像本身不绑定具体的代码版本,更加通用。

2.3 实操:如何探查一个未知的工作空间镜像?

如果你拿到了一个类似copaw_workspace_default_20260329_075700的镜像,如何快速了解其内容?以下是几个关键命令:

# 1. 拉取镜像(如果尚未在本地) # docker pull metagalaxy-crystal/copaw_workspace_default_20260329_075700 # 2. 查看镜像历史(了解构建步骤) docker image history metagalaxy-crystal/copaw_workspace_default_20260329_075700 --no-trunc # 3. 以交互模式运行一个临时容器,并启动shell进行探索 docker run -it --rm --name workspace-explorer metagalaxy-crystal/copaw_workspace_default_20260329_075700 /bin/bash # 进入容器后,你可以执行以下命令: # 查看操作系统信息 cat /etc/os-release # 查看已安装的软件包(以Ubuntu/Debian为例) dpkg -l | head -30 # 查看Python环境(如果存在) python --version pip list # 查看环境变量 env | grep -i “copaw\|path” # 查看默认工作目录和可能存在的启动脚本 ls -la /workspace /app /entrypoint.sh # 退出容器 exit

通过以上探查,你可以快速了解这个工作空间预设了哪些工具、环境变量如何配置、以及它的默认启动行为,为后续使用或定制打下基础。

3. 构建你自己的标准化工作空间镜像

理解了工作空间镜像的价值和构成后,我们可以动手为自己或团队构建一个。这里以一个典型的Python数据科学开发环境为例,展示从Dockerfile编写到最佳实践的完整流程。

3.1 Dockerfile 编写详解

下面是一个比通常教程更详细、更贴近生产实践的Dockerfile示例,其中包含了大量注释说明“为什么”要这么做。

# 第一阶段:构建基础工具层 FROM ubuntu:22.04 AS builder # 设置非交互式前端以避免安装过程中的提示阻塞 ENV DEBIAN_FRONTEND=noninteractive # 更新源并安装系统级基础工具 # 使用apt-get update和install组合在一条RUN指令中,减少镜像层数 # clean参数在安装后清理缓存,减小镜像体积 RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ curl \ wget \ git \ gnupg \ lsb-release \ software-properties-common \ # 编译工具链 build-essential \ cmake \ pkg-config \ # Python编译依赖 libssl-dev \ zlib1g-dev \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ libncursesw5-dev \ libffi-dev \ liblzma-dev \ # 其他常用工具 vim \ htop \ net-tools \ && rm -rf /var/lib/apt/lists/* # 安装特定版本的Python(使用pyenv,提供灵活的版本管理) RUN curl https://pyenv.run | bash ENV PYENV_ROOT="/root/.pyenv" ENV PATH="$PYENV_ROOT/bin:$PATH" RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc && \ echo 'eval "$(pyenv init -)"' >> ~/.bashrc # 安装并设置全局Python版本 RUN pyenv install 3.11.9 && pyenv global 3.11.9 ENV PATH="$PYENV_ROOT/versions/3.11.9/bin:$PATH" # 第二阶段:构建最终的工作空间镜像 FROM ubuntu:22.04 # 从builder阶段拷贝已安装的工具和Python环境 COPY --from=builder /usr /usr COPY --from=builder /lib /lib COPY --from=builder /root/.pyenv /root/.pyenv # 设置环境变量 ENV PYENV_ROOT="/root/.pyenv" ENV PATH="$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH" ENV PYTHONPATH="/workspace:$PYTHONPATH" ENV DEBIAN_FRONTEND=noninteractive # 安装容器内专用的开发工具(不包含编译链等重型工具,它们已在上一阶段拷贝) RUN apt-get update && apt-get install -y --no-install-recommends \ git-lfs \ openssh-client \ # 数据库客户端 postgresql-client \ sqlite3 \ && rm -rf /var/lib/apt/lists/* # 配置pip使用国内镜像加速(根据团队位置调整) RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \ pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn # 安装核心Python数据科学套件(版本锁定,确保一致性) RUN pip install --no-cache-dir \ numpy==1.24.3 \ pandas==2.0.3 \ scikit-learn==1.3.0 \ matplotlib==3.7.1 \ jupyterlab==4.0.5 \ ipykernel==6.25.1 \ black==23.7.0 \ flake8==6.0.0 \ pytest==7.4.0 # 创建非root用户以提升安全性(最佳实践) RUN useradd -m -s /bin/bash developer && \ echo "developer:developer" | chpasswd && \ usermod -aG sudo developer # 将/workspace目录所有权赋予新用户 RUN mkdir -p /workspace && chown -R developer:developer /workspace # 切换到非root用户 USER developer WORKDIR /workspace # 配置git(容器内) RUN git config --global user.name "Container Developer" && \ git config --global user.email "developer@container.local" # 设置入口点:默认启动一个bash shell,保持容器运行 ENTRYPOINT ["/bin/bash"]

这个Dockerfile体现了几个关键设计思想:多阶段构建以减少最终镜像体积;版本锁定以确保环境绝对一致;创建非root用户以遵循安全原则;预置常用配置(如pip源、git配置)提升开箱即用体验。

3.2 构建、推送与版本管理

编写好Dockerfile后,下一步是构建和分发。

# 在Dockerfile所在目录执行构建 # -t 指定镜像标签,格式通常为:仓库/项目:标签 # 标签建议包含日期和版本信息,如 `myworkspace:py3.11-20240329` docker build -t mycompany/datascience-workspace:py3.11-20240329 . # 运行测试,确保环境正常工作 docker run -it --rm mycompany/datascience-workspace:py3.11-20240329 python -c "import numpy, pandas; print('OK')" # 如果使用私有仓库(如Harbor, AWS ECR, GCR),需要先登录 # docker login myregistry.example.com # 推送镜像到仓库 docker push mycompany/datascience-workspace:py3.11-20240329 # 同时,为这个版本打一个“latest”标签(谨慎使用,明确场景) docker tag mycompany/datascience-workspace:py3.11-20240329 mycompany/datascience-workspace:latest docker push mycompany/datascience-workspace:latest

版本管理策略:强烈建议使用有意义的标签,而不是过度依赖latest。可以结合语义化版本和日期,例如:

  • datascience-workspace:v1.2.0-20240329(功能版本+日期)
  • datascience-workspace:py3.11-base(运行时描述性标签)
  • datascience-workspace:experimental-cuda12.1(特殊变体)

3.3 高级技巧:利用docker-compose编排复杂工作空间

单一容器有时不足以满足复杂开发环境的需求,比如需要同时运行数据库、消息队列等依赖服务。这时,docker-compose是绝佳工具。创建一个docker-compose.yml文件:

version: '3.8' services: workspace: image: mycompany/datascience-workspace:py3.11-20240329 container_name: my-dev-workspace # 挂载代码目录、SSH密钥、Git配置等 volumes: - ./code:/workspace/code - ~/.ssh:/home/developer/.ssh:ro - ~/.gitconfig:/home/developer/.gitconfig:ro # 挂载Docker套接字,允许容器内使用Docker(用于构建镜像等,注意安全) - /var/run/docker.sock:/var/run/docker.sock # 映射端口,例如Jupyter Lab的8888端口 ports: - "8888:8888" # 设置环境变量 environment: - JUPYTER_TOKEN=mysecret_token # 以交互模式运行,并保持终端 stdin_open: true tty: true # 依赖服务 depends_on: - postgres - redis postgres: image: postgres:15-alpine environment: POSTGRES_PASSWORD: example POSTGRES_DB: myapp volumes: - postgres_data:/var/lib/postgresql/data redis: image: redis:7-alpine volumes: postgres_data:

使用docker-compose up -d启动整个环境,所有服务一键到位。开发人员只需关注./code目录下的代码,完全无需在本地安装PostgreSQL或Redis。

4. 工作空间镜像的实战应用场景与工作流

4.1 场景一:新成员快速入职与开发环境统一

这是工作空间镜像最直接的价值。新同事入职第一天,不再需要:

  1. 安装Python、Node.js等运行时。
  2. 处理令人头疼的系统依赖冲突(比如在Mac和Windows上不同的表现)。
  3. 逐个安装项目依赖,并祈祷版本完全一致。
  4. 配置IDE、代码格式化、Lint规则。

他只需要:

  1. 安装Docker Desktop。
  2. 拉取团队的工作空间镜像:docker pull mycompany/project-workspace:latest
  3. 运行一个脚本或使用预置的docker-compose.yml启动容器。
  4. 用VSCode的“Remote - Containers”扩展连接到这个容器。

几分钟内,他就获得了一个与团队完全同步的、包含所有工具和配置的开发环境,可以立即开始编码和调试。这节省的时间成本是巨大的。

4.2 场景二:CI/CD流水线中的构建与测试环境

在持续集成中,保证构建环境的一致性至关重要。工作空间镜像可以作为CI Runner的基础镜像。

# 一个GitLab CI的示例配置 .gitlab-ci.yml stages: - test - build unit-test: stage: test image: mycompany/project-workspace:py3.11-20240329 # 使用统一的工作空间镜像 script: - pip install -r requirements-dev.txt # 安装测试专用依赖 - pytest tests/ --cov=src --cov-report=xml artifacts: reports: junit: junit.xml coverage_report: coverage_format: cobertura path: coverage.xml build-docker: stage: build image: docker:latest # 使用Docker-in-Docker镜像 services: - docker:dind script: - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

这样做的好处是,本地开发环境和CI测试环境是二进制一致的,极大减少了“在本地通过,在CI上失败”的诡异问题。

4.3 场景三:复杂依赖项目的演示与交付

有些项目依赖复杂(比如特定的机器学习框架、特定的CUDA版本),让用户或客户在自己的机器上搭建环境困难重重。你可以将你的应用其完整的工作空间环境一起打包。

交付物可以是一个包含以下内容的包:

  1. 你的应用代码。
  2. 一个Dockerfile(基于你的工作空间镜像进行微调)。
  3. 一个docker-compose.yml(定义如何运行应用及其服务)。
  4. 一个简单的启动脚本run.sh

用户只需执行./run.sh,Docker就会拉取你的工作空间镜像,构建最终的应用镜像,并启动所有服务。这几乎实现了“零配置部署”,对于售前演示、教育培训、开源项目推广都极具价值。

4.4 与IDE的深度集成:VSCode Remote-Containers

现代IDE对容器开发的支持已经非常成熟。以VSCode为例,其“Remote - Containers”扩展允许你将一个容器作为功能齐全的开发环境。

你可以在项目根目录下创建.devcontainer文件夹,里面放置两个文件:

.devcontainer/devcontainer.json:

{ "name": "Copaw Project", "build": { "dockerfile": "Dockerfile", "context": "..", "args": { "VARIANT": "3.11" } }, "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], "mounts": [ "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/developer/.ssh,type=bind,readonly" ], "customizations": { "vscode": { "extensions": [ "ms-python.python", "ms-toolsai.jupyter", "eamodio.gitlens", "charliermarsh.ruff" ], "settings": { "python.defaultInterpreterPath": "/usr/local/bin/python", "python.linting.enabled": true } } }, "remoteUser": "developer", "workspaceFolder": "/workspace" }

.devcontainer/Dockerfile: 可以直接基于你已有的工作空间镜像进行扩展:

FROM mycompany/datascience-workspace:py3.11-20240329 # 安装VSCode Server可能需要的额外依赖(通常已包含) # RUN apt-get update && apt-get install -y curl ... # 可以在这里安装项目特定的、不希望在基础镜像中全局存在的依赖 # COPY requirements-dev.txt . # RUN pip install -r requirements-dev.txt USER developer

当用VSCode打开这个项目时,它会提示“在容器中重新打开”。点击后,VSCode会自动构建或拉取镜像,并在容器内启动一个完整的代码编辑环境,包括你预配置的所有扩展和设置。开发体验与本地几乎无异,但环境是绝对纯净和一致的。

5. 常见问题、排查技巧与最佳实践实录

5.1 镜像体积过大怎么办?

工作空间镜像因为工具齐全,体积容易膨胀。以下是一些减负策略:

  1. 多阶段构建:如上文Dockerfile所示,将编译等重型操作放在一个“构建器”阶段,只将必要的运行时文件复制到最终镜像。
  2. 使用Alpine等小型基础镜像:但要注意Alpine使用musl libc,可能与某些依赖glibc的二进制软件包不兼容,需测试。
  3. 清理APT/YUM缓存:在每个RUN apt-get install命令后加上&& rm -rf /var/lib/apt/lists/*
  4. 合并RUN指令:将多个RUN命令用&&连接成一个,减少镜像层数。
  5. 使用.dockerignore文件:防止将本地不必要的文件(如__pycache__,.git)拷贝进镜像上下文。
  6. 定期审视依赖:检查requirements.txtpackage.json,移除不再使用的库。

5.2 如何管理镜像的更新与迭代?

工作空间镜像不是一成不变的。操作系统需要安全更新,语言运行时和工具链需要升级。

  1. 建立定期重建流程:通过CI/CD流水线,每周或每月自动从最新的基础镜像(如ubuntu:22.04)触发一次重建,并运行完整的测试套件,确保更新不会破坏现有功能。新镜像打上新的日期标签。
  2. 分层次管理:建立基础层、语言层、工具层、项目层的镜像体系。下层镜像更新后,自动触发上层镜像的重建。这比一个庞大的单体镜像更容易管理。
  3. 清晰的变更日志(CHANGELOG):在镜像仓库的描述中或配套的文档里,记录每个版本镜像的变更内容(如:20240329: 升级Python至3.11.9, 新增redis-cli工具)。
  4. 提供迁移指南:如果新版本有破坏性变更(如Python从3.7升级到3.11),需要为开发者提供简单的步骤说明,指导他们如何适配。

5.3 权限与安全问题

  1. 不要以root身份运行:务必在Dockerfile中创建并使用非root用户(如developer)。这能限制容器被入侵后的影响范围。
  2. 谨慎挂载Docker Socket-v /var/run/docker.sock:/var/run/docker.sock赋予了容器内操控宿主机Docker守护进程的能力,存在安全风险。仅在对容器内构建镜像有严格需求的开发场景下使用,并确保镜像来源可信。
  3. 敏感信息不写入镜像:密码、API密钥、SSH私钥等绝对不要写在Dockerfile里。应通过环境变量(docker run -e)、Docker Secrets或挂载文件的方式在运行时传入。
  4. 扫描镜像漏洞:使用docker scan或集成Trivy、Grype等工具到CI流水线中,定期扫描工作空间镜像中的已知安全漏洞。

5.4 网络与性能调优

  1. 镜像拉取加速:在国内可以使用镜像加速器。在Docker Desktop配置中或/etc/docker/daemon.json里配置镜像仓库镜像。
  2. 卷挂载的性能:在Mac或Windows上使用Docker Desktop时,对挂载卷(-v)的文件系统访问可能有性能损耗。对于大型代码库,可以考虑:
    • 使用delegatedcached一致性模式(如-v $(pwd):/workspace:cached)。
    • node_modules__pycache__这类依赖或缓存目录排除在挂载之外,让它们在容器内生成。
  3. 资源限制:为开发容器分配足够的内存和CPU,避免卡顿。可以在docker run时使用-m 4g --cpus=2参数,或在docker-compose.yml中配置。

5.5 故障排查清单

当你的工作空间容器出现问题时,可以按以下顺序排查:

问题现象可能原因排查命令/步骤
容器启动后立即退出入口点(ENTRYPOINT/CMD)命令执行完毕docker logs <container_id>查看日志;检查Dockerfile中ENTRYPOINT是否为持久化命令(如tail -fcode-server
无法安装Python包(pip timeout)网络问题或pip源不可用进入容器docker exec -it <id> bash,手动curl -v https://pypi.org测试网络;检查pip配置pip config list
容器内命令找不到(command not found)PATH环境变量未设置正确,或软件未安装echo $PATHwhich python;`dpkg -l
挂载的代码在容器内看不到挂载路径错误或权限问题docker inspect <container_id>查看Mounts字段;容器内检查目录权限ls -la /workspace
VSCode无法连接到容器容器未暴露SSH端口或VSCode Server未运行确保容器在运行且具有合适的入口点;检查.devcontainer.json配置是否正确
容器性能极差资源限制过紧,或卷挂载模式导致docker stats查看资源使用;尝试调整挂载模式为cached

构建和维护一个像metagalaxy-crystal/copaw_workspace_default_20260329_075700这样的工作空间镜像,初看似乎增加了额外的工作量,但它是典型的“磨刀不误砍柴工”。它将环境配置这项繁琐、易错、重复的工作,转化为一次性的、可版本化、可共享的资产。对于任何超过两人的技术团队,或者任何依赖复杂环境的技术项目,投资这样一套环境标准化方案,从长期来看,在提升开发效率、保障交付质量、降低协作成本方面的回报是极其显著的。它让开发者能更专注于创造代码本身的价值,而不是在环境泥潭中挣扎。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 3:17:05

CircuitPython串口控制台与REPL调试及库管理实战指南

1. 项目概述如果你刚开始接触CircuitPython&#xff0c;或者是从Arduino这类更底层的平台转过来&#xff0c;可能会觉得有点无从下手。代码写好了&#xff0c;怎么知道它在板子上跑得对不对&#xff1f;传感器读出来的数据准不准&#xff1f;程序卡在哪儿了&#xff1f;这些问题…

作者头像 李华
网站建设 2026/5/16 3:13:04

5分钟掌握WebPlotDigitizer:从图表图片智能提取数据的完整指南

5分钟掌握WebPlotDigitizer&#xff1a;从图表图片智能提取数据的完整指南 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 还在为从科研…

作者头像 李华
网站建设 2026/5/16 3:12:06

AI驱动软件架构可视化:C4模型与生成式AI的融合实践

1. 项目概述&#xff1a;当企业架构图遇上生成式AI 最近在技术社区里&#xff0c;一个名为 codecentric/c4-genai-suite 的项目引起了我的注意。乍一看标题&#xff0c;它融合了两个看似不相关的领域&#xff1a;C4模型和生成式AI。C4模型&#xff0c;对于软件架构师和开发者…

作者头像 李华
网站建设 2026/5/16 3:12:03

AIGC面试指南:从Transformer到RAG与Agent的实战知识体系

1. 项目概述&#xff1a;一本面向AIGC求职者的实战指南最近几年&#xff0c;AI生成内容&#xff08;AIGC&#xff09;领域的热度可以说是席卷全球。从能写代码、写文章的ChatGPT&#xff0c;到能生成逼真图像的Stable Diffusion、Midjourney&#xff0c;再到Sora这样的视频生成…

作者头像 李华