我在通过 dockerfile 安装 laravel 时遇到问题。我正在使用 docker-compose 来拉取一个 docker文件,我基本上有这个:
FROM php:7.3-apache-stretch
*some apt-get and install composer*
WORKDIR /var/www
RUN composer create-project --prefer-dist laravel/laravel app
CMD apachectl -D FOREGROUND
但是当我访问容器并且我会看到应该使用作曲家创建的文件时,即使我看到了在容器构建中执行的命令,我也看到它是空的。
容器运行良好,甚至我也可以访问它......只有甚至不出现的文件。
如果我在创建容器后手动运行 composer 命令,则会显示文件。
在你的 Dockerfile 中,你使用了WORKDIR /var/www
然后RUN composer create-project ...
这使得作曲家在容器文件系统上的/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
上的任何内容。
我建议您仔细阅读有关 docker 卷的文档,更具体地说,标题为"使用容器填充卷"的部分。
现在继续前进,问问自己为什么首先需要这个卷。是否需要在运行时更改文件?
如果没有,只需在构建时添加文件:
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 容器测试 Web 服务器提供的应用程序来频繁测试结果。
每次需要测试应用程序时都必须重新构建 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 注册表)。您可以使用官方注册表映像将自己的注册表部署为 Docker 容器,也可以使用公司提供的注册表:
- Gitlab.com - Gitlab Registry(免费)
- Docker.com - hub.docker.com(1 个私有镜像免费)
- Google.com - 谷歌容器注册表
- 。
因此,您需要构建一个 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 映像(该映像之前已在过渡环境中部署以进行验证)。