在您的 Dockerfile 中,您使用了 WORKDIR /var/www,然后使用了 RUN composer create-project ...,这使得 composer 在 容器文件系统 上的 /var/www 下创建文件。
在您用于启动容器的 docker-compose.yml 文件中:
version: '3.7'
services:
app:
container_name: "app"
build:
context: ./docker
dockerfile: Dockerfile-app
ports:
- "80"
- "443"
restart: always
depends_on:
- db
volumes:
- ".:/var/www"
您正在声明一个卷,该卷将安装在容器中的同一位置 /var/www。
发生的情况是卷内容将取代容器文件系统中 /var/www 上的任何内容。
我建议您仔细阅读documentation regarding docker volumes,尤其是标题为Populate a volume using a container 的部分。
现在继续前进,问问自己为什么首先需要这本书。是否需要在运行时更改文件?
如果没有,只需在构建时添加文件:
FROM php:7.3-apache-stretch
*some apt-get and install composer*
WORKDIR /var/www
RUN composer create-project --prefer-dist laravel/laravel app
COPY . /var/www
CMD apachectl -D FOREGROUND
并删除/var/www 的卷。
编辑
借助 Docker 容器进行开发
在开发过程中,您更改了 docker 主机(假设是您的开发计算机)上的 php 文件,并且需要通过测试 docker 容器中的网络服务器提供的应用程序来经常测试结果。
每次需要测试应用时都必须重新构建 Docker 映像会很麻烦。解决方案是挂载一个卷,以便容器可以从您的开发计算机提供文件:
FROM php:7.3-apache-stretch
*some apt-get and install composer*
WORKDIR /var/www
CMD apachectl -D FOREGROUND
然后开始:
version: '3.7'
services:
app:
container_name: "app"
build:
context: ./docker
dockerfile: Dockerfile-app
ports:
- "80"
- "443"
restart: always
depends_on:
- db
volumes:
- ".:/var/www"
...
当您需要在该容器中运行某些命令时,只需使用docker exec:
docker-compose exec app composer create-project --prefer-dist laravel/laravel app
制作项目工件
由于您要部署的不是包含源代码和配置的 zip/tar 存档,而是 docker 映像,因此您需要构建将在部署时使用的 docker 映像。
用于生产的 Dockerfile
对于生产用途,您希望拥有一个 Docker 映像,它包含所有必需的文件,并且不需要任何 docker 卷,除了保存用户生成的数据(上传的文件、数据库文件等)
FROM php:7.3-apache-stretch
*some apt-get and install composer*
WORKDIR /var/www
COPY . /var/www
CMD apachectl -D FOREGROUND
请注意,此 Dockerfile 中没有 RUN composer create-project --prefer-dist laravel/laravel app。这是因为此命令用于初始化您的项目,这是一个开发时间任务,而不是部署时间任务。
您还需要一个地方来托管您的 docker 镜像(Docker registry)。您可以使用 official registry image 将自己的注册表部署为 Docker 容器,或使用公司提供的:
所以您需要构建一个 docker 镜像,然后将该镜像推送到您的注册表中。最佳实践是借助Jenkins、Gitlab CI、Travis CI、Circle CI、Google Cloud Build 等持续集成工具自动执行这些任务...
您的 CI 作业将运行以下命令:
git clone <url of you git repo> my_app
cd my_app
git checkout <some git tag>
docker build -t <registry>/<my_app>:<version>
docker login <registry> --user=<registry user> --password=<registry password>
docker push <registry>/<my_app>:<version>
部署您的 Docker 映像
启动容器:
version: '3.7'
services:
app:
container_name: "app"
image: <registry>/<my_app>:<version>
ports:
- "80"
- "443"
restart: always
depends_on:
- db
...
请注意,docker-compose 文件不会构建任何镜像。对于生产,最好参考已经构建的 docker 镜像(之前已在暂存环境中部署以进行验证)。