- 后端
- 开发工具
- DevOps
【免费下载链接】laradock
Full PHP development environment for Docker. Run Laravel, Symfony, CodeIgniter, Phalcon, WordPress, Drupal, Magento, Moodle, or any PHP project with 70+ pre-configured services: Nginx, Apache, PHP-FPM, MySQL, PostgreSQL, MongoDB, Redis, Elasticsearch & more.
Laradock 将宿主机与容器之间需要共享的内容精确地划分为两类:通过 bind mount 实时映射的项目代码,以及存放在宿主机固定目录DATA_PATH_HOST下的服务数据(数据库、缓存、上传文件等)。本文以 DOCUMENTATION/docs/volumes.md 为主线,结合仓库中的.env.example、各服务的compose.yml与 Laradock CLI 命令,完整讲解 Laradock 的数据存放位置、为何重建容器后数据仍在、如何备份与重置单个服务的数据,以及多项目并存时的数据隔离方案。读完本文,你将能安全地对 MySQL、PostgreSQL、Redis 等任一服务的数据进行备份、迁移与清理,并理解数据在 Laradock 体系中的完整生命周期。
两类存储:代码与数据
Laradock 从宿主机挂载进容器的内容只有两类,这是理解整个数据模型的基础:
- 项目代码:以 live bind mount 方式挂载。宿主机路径
APP_CODE_PATH_HOST(默认../,即存放 Laradock 的上层目录)被挂载到容器内的APP_CODE_PATH_CONTAINER(默认/var/www)。宿主机上修改文件,容器内立即可见,因此不存在"把代码拷贝进容器"这一步——这正是 Laradock 开发体验的核心。 - 服务数据(数据库、缓存、上传文件):统一存放在
DATA_PATH_HOST(默认~/.laradock/data)下。每个服务拥有自己的子目录:MySQL 在~/.laradock/data/mysql,PostgreSQL 在~/.laradock/data/postgres,Redis 在~/.laradock/data/redis,依此类推。
因为两者都位于宿主机而非容器内部,所以停止、删除甚至重建容器都不会丢失数据。
源码中的路径配置
这些路径在仓库根目录的 .env.example 中集中定义,是 Laradock 数据模型的源头:
### Paths ################################################# # Point to the path of your applications code on your host APP_CODE_PATH_HOST=../ # Point to where the `APP_CODE_PATH_HOST` should be in the container APP_CODE_PATH_CONTAINER=/var/www # You may add flags to the path `:cached`, `:delegated`. APP_CODE_CONTAINER_FLAG=:cached # Choose storage path on your machine. For all storage systems DATA_PATH_HOST=~/.laradock/data # NOTE: each database engine keeps its data in a sub-folder here (mysql/, postgres/, ...). # A server will NOT start against data created by a newer major version (databases do not # downgrade). If a DB container keeps restarting after you change its *_VERSION below, # either set the version back to match the existing data, or remove that engine's # sub-folder inside DATA_PATH_HOST to start fresh (this deletes that database's local data).从注释可以读出两个关键信息:其一,APP_CODE_CONTAINER_FLAG默认为:cached,这是 macOS 上优化文件共享性能的挂载标志(详见 DOCUMENTATION/docs/environment.md 中的 macOS 性能优化一节,可改为:delegated);其二,数据库引擎的数据都按子目录存放,且数据库无法向低版本降级——若你改了MYSQL_VERSION之类的版本变量导致容器反复重启,要么把版本改回去匹配已有数据,要么删除该引擎在DATA_PATH_HOST下的子目录以全新启动。
compose 文件中如何落地
以 MySQL 为例,mysql/compose.yml 将宿主机数据目录 bind mount 到容器内的数据路径:
volumes: - ${DATA_PATH_HOST}/mysql:/var/lib/mysql - ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.dPostgreSQL 同样如此,见 postgres/compose.yml:
volumes: - ${DATA_PATH_HOST}/postgres:/var/lib/postgresql/data而代码挂载在 workspace/compose.yml 中体现为:
volumes: - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG}即${APP_CODE_PATH_HOST}挂载到${APP_CODE_PATH_CONTAINER},并附加${APP_CODE_CONTAINER_FLAG}标志,最终效果等价于../:/var/www:cached。除此之外,主 docker-compose.yml 还声明了少量 named volume(如arangodb、elasticsearch、mssql、prometheus、ollama等),用于存放镜像自身或工具产生的数据,但绝大多数有状态服务的持久化数据都走DATA_PATH_HOST的 bind mount,这是 Laradock 数据管理的重心。
为什么重建容器后数据依然存在
停止或删除容器永远不会触碰你的数据。无论是使用 Laradock CLI 还是原生 Docker Compose,效果一致:
# Laradock CLI ./laradock remove # 或 Docker Compose docker compose down两条命令都会移除运行中的容器,但DATA_PATH_HOST下的所有内容原封不动地留在磁盘上。重新启动服务后,数据库会回到你离开时的状态,分毫不差。
真正会抹掉数据的操作只有两种:
- 手动删除该服务的数据目录(下文"重置或清除单个服务")。
- 带
--no-cache的重建,它会重新初始化一个卷。需要特别注意的是,这一条针对的是 Docker named volume 的重建行为——对于走DATA_PATH_HOSTbind mount 的服务,--no-cache重建镜像不会清空宿主机上的数据目录,但会重新执行镜像入口脚本(如 MySQL 的docker-entrypoint-initdb.d初始化逻辑),因此把--no-cache视为可能触发数据初始化的危险操作是稳妥的。
Laradock CLI 的命令语义也印证了这一点:在 DOCUMENTATION/docs/cli.md 的命令表中,./laradock stop明确标注"Your data is kept"(数据保留),./laradock remove明确标注"Delete the containers. Your data on disk is kept"(删除容器,磁盘数据保留)。这是 Laradock 设计上的承诺:容器是无状态的,数据只属于宿主机目录。
备份某个服务的数据
由于数据只是宿主机上的普通文件,备份的本质就是复制目录。为保证文件一致性,建议先停止该服务再复制:
./laradock stop mysql # 或: docker compose stop mysql cp -r ~/.laradock/data/mysql ~/mysql-backup对于数据库而言,逻辑导出(logical dump)比直接复制原始文件更具可移植性——原始数据文件与数据库引擎的版本强绑定,换一个版本就可能无法读取,而 SQL dump 是跨版本的通用格式。在容器内执行逻辑导出:
./laradock exec mysql mysqldump -udefault -psecret mydatabase > backup.sql这里的./laradock exec等价于docker compose exec,是在不进入容器的情况下执行单条命令。default/secret是 Laradock 的默认数据库账号密码,可在.env或对应服务的defaults.env中修改(见 mysql/defaults.env,其中MYSQL_USER=default、MYSQL_PASSWORD=secret)。
仓库中各服务的文档也采用了完全一致的备份套路。例如 DOCUMENTATION/docs/services/caching-queues/redis.md 备份 Redis 的 RDB 快照文件:
cp "${DATA_PATH_HOST:-~/.laradock/data}/redis/dump.rdb" backup.rdb而 DOCUMENTATION/docs/services/caching-queues/aerospike.md 甚至给出了带时间戳的备份命名惯例:
cp -r "${DATA_PATH_HOST:-~/.laradock/data}/aerospike" ./aerospike-backup-$(date +%Y%m%d)注意这些服务文档中的${DATA_PATH_HOST:-~/.laradock/data}写法:如果.env中未设置DATA_PATH_HOST,shell 会自动回退到默认值~/.laradock/data,保证命令在任何环境都能直接运行——这也是你在脚本中引用该路径时的推荐写法。
重置或清除单个服务
有时你需要让某个服务从干净状态重新开始,例如:
- 应用新的数据库密码:凭据只在首次启动时写入初始化(见下方解释);
- 清除损坏的数据库:让引擎重建全新的数据文件。
做法是删除该服务的数据目录:
./laradock stop mysql # 或: docker compose stop mysql rm -rf ~/.laradock/data/mysql ./laradock start mysql # 或: docker compose up -d mysql下次启动时服务会以全新状态重新初始化。这一操作只影响你删除目录的那个服务,其余服务的数据不受任何影响。
关于"凭据只在首次启动时写入",仓库的配置结构可以佐证:MySQL 的账号密码通过 mysql/compose.yml 中的MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD、MYSQL_ROOT_PASSWORD环境变量传入,而 MySQL 官方镜像的入口脚本只会在数据目录为空(首次初始化)时执行docker-entrypoint-initdb.d并创建这些账号;数据目录已存在时,环境变量不会再次生效。因此修改密码后必须删除~/.laradock/data/mysql才能让新密码生效。同理,MYSQL_ENTRYPOINT_INITDB(默认./mysql/docker-entrypoint-initdb.d,见 mysql/defaults.env)目录下的初始化 SQL 也只会在首次启动时执行。
:::warning 警告 删除数据目录是永久性操作。只要有任何可能还需要这些数据,请务必先备份(见上一节)。 :::
各服务数据子目录速查
仓库中每个有状态服务的compose.yml都遵循${DATA_PATH_HOST}/<服务名>的约定,重置方法与 MySQL 完全相同。部分示例:
| 服务 | 数据子目录 | 对应容器内路径 |
|---|---|---|
| MySQL | ~/.laradock/data/mysql | /var/lib/mysql |
| PostgreSQL | ~/.laradock/data/postgres | /var/lib/postgresql/data |
| Redis | ~/.laradock/data/redis | /data(RDB 快照dump.rdb) |
| Kafka / Zookeeper | ~/.laradock/data/kafka、~/.laradock/data/zookeeper | — |
| RabbitMQ | ~/.laradock/data/rabbitmq | — |
| Mosquitto | ~/.laradock/data/mosquitto/data | — |
例如重置 Redis:DOCUMENTATION/docs/services/caching-queues/redis.md 中即为rm -rf "${DATA_PATH_HOST:-~/.laradock/data}/redis";Kafka 则需要同时清掉 Kafka 与 Zookeeper 两处目录(见 DOCUMENTATION/docs/services/caching-queues/kafka.md)。如果你不确定某服务的数据目录,直接查看对应目录下的compose.yml中volumes段的${DATA_PATH_HOST}/...挂载行即可。
按项目隔离数据
当同一台机器上同时运行多个 Laradock 实例时,必须为每个项目设置独立的DATA_PATH_HOST(以及COMPOSE_PROJECT_NAME),否则多个项目会共享同一份磁盘上的数据库,造成数据串扰:
COMPOSE_PROJECT_NAME=myproject DATA_PATH_HOST=~/.laradock/data-myprojectCOMPOSE_PROJECT_NAME用于隔离容器——它决定容器名称前缀(默认是目录名,例如laradock_workspace_1),避免两个项目生成同名容器而冲突。默认值见 .env.example(COMPOSE_PROJECT_NAME=laradock)。DATA_PATH_HOST用于隔离数据——每个项目把数据写到各自的目录(如~/.laradock/data-myproject/mysql),互不相干。
这两个变量必须同时设置,缺一不可:只改COMPOSE_PROJECT_NAME而忘记改DATA_PATH_HOST,两个项目仍会读写同一份数据库文件。
完整的多项目配置方案见 DOCUMENTATION/docs/multiple-projects.md,其中还包含另一种思路:如果多个站点愿意共享同一个 Laradock 实例,可以将APP_CODE_PATH_HOST指向父目录(APP_CODE_PATH_HOST=../),再在nginx/sites或apache2/sites下为每个站点添加一份虚拟主机配置,实现"一套栈服务多个项目"。两种模式的选择标准是:项目之间是否需要完全隔离(各自独立的 PHP 版本、服务与数据),还是可以共享同一套容器栈。
数据相关注意事项小结
- 永远不要直接在容器内"拷贝代码":代码是 bind mount 的,宿主机的修改即时生效,容器内没有独立的代码副本。
DATA_PATH_HOST目录既是备份的源,也是重置的目标:cp -r即可备份,rm -rf子目录即可重置,这也是"数据即文件"模型的最大便利。- 数据库版本升级是数据安全的高危操作:数据库不向下兼容。从 .env.example 的注释和 mysql/defaults.env 的提示(
MYSQL_VERSION可选 5.7 / 8.0 / 8.4 / 9.0,且明确注明"changing the major version? see the DATA_PATH_HOST note above")可以确认:变更大版本前,要么接受旧数据不可用并清空对应子目录,要么先完整备份再升级。 ./laradock系列命令是数据操作的统一入口:stop(停止并保留数据)、remove(删容器保留数据)、exec(在容器内执行备份/导出命令)、start(重新拉起)。在脚本中引用数据路径时,推荐使用${DATA_PATH_HOST:-~/.laradock/data}的写法以获得默认值回退。
掌握"数据在宿主机、容器可随意重建"这一核心心智模型后,无论是日常备份、迁移环境还是修复损坏的服务,你都可以用最朴素的文件操作安全完成,而不必担心 Docker 层的任何重建动作会带走你的数据。
- 后端
- 开发工具
- DevOps
【免费下载链接】laradock
Full PHP development environment for Docker. Run Laravel, Symfony, CodeIgniter, Phalcon, WordPress, Drupal, Magento, Moodle, or any PHP project with 70+ pre-configured services: Nginx, Apache, PHP-FPM, MySQL, PostgreSQL, MongoDB, Redis, Elasticsearch & more.
相关推荐
Nuclide容器数据卷管理:持久化存储与备份
Nuclide容器数据卷管理:持久化存储与备份 Nuclide作为基于Atom构建的开源IDE,提供了丰富的容器开发支持。本文将详细介绍如何在Nuclide中管
开发工具DockerUI卷管理终极指南:5步实现数据持久化与安全备份
DockerUI卷管理终极指南:5步实现数据持久化与安全备份 想要确保Docker容器数据永不丢失?DockerUI提供了简单直观的卷管理界面,让数据持久化和备
云原生运维PyGWalker 可视化安装部署完整指南
PyGWalker 可视化安装部署完整指南 新同事入职第一天,任务是:在一台干净机器上把 PyGWalker 跑起来。PyGWalker 安装完成后,把一个 p
数据分析数据可视化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考