在CentOS上使用Docker设置PHP-FPM、Nginx和Mariadb

10
我正在尝试从使用VirtualBox作为开发环境转移到Docker。 在VirtualBox中,我主要安装PHP-FPM、Nginx和Mariadb,但在Docker中,尽管尝试了几天,我仍无法复制相同的堆栈。在所有LEMP/LAMP stack docker指南中,只有这个chentex/docker-nginx-centos是适用于我的:以下是来自Dockerfile的代码:
FROM centos:centos7
LABEL maintainer="Vicente Zepeda <chente.z.m@gmail.com>"

ENV nginxversion="1.12.2-1" \
    os="centos" \
    osversion="7" \
    elversion="7_4"

RUN yum install -y wget openssl sed &&\
    yum -y autoremove &&\
    yum clean all &&\
    wget http://nginx.org/packages/$os/$osversion/x86_64/RPMS/nginx-$nginxversion.el$elversion.ngx.x86_64.rpm &&\
    rpm -iv nginx-$nginxversion.el$elversion.ngx.x86_64.rpm &&\
    sed -i '1i\
    daemon off;\
    ' /etc/nginx/nginx.conf

CMD ["nginx"]

这个可以直接使用,我可以在http://localhost看到默认页面。

唯一的问题是它不包含PHP-FPM和Mariadb。

我试图修改文件并添加PHP-FPM和Mariadb,但我在Reddit上发现每个容器应该只有一个服务,比如一个容器用于nginx,另一个用于php...而我不知道如何做到这一点。


[so] 是用于编程问题的,而不是关于使用或配置Linux及其应用程序的问题。[sf] 或 [unix.se] 将是更好的地方,用于此类问题的提问。 - Barmar
4个回答

10

Docker容器旨在只运行单个服务,而不是整个虚拟系统(如您可能在虚拟机中看到的)。

这意味着理想情况下,每个服务应该有一个单独的容器:

  • Nginx
  • PHP
  • Mariadb

此外,Centos Docker镜像是为其他镜像继承或执行特定于操作系统的任务(例如cURL调用或shell)而设计的,这并不是您所需要的。

我建议您使用docker-compose,在其中设置中间容器并将它们全部作为一个项目进行管理。

我建议您设置一个名为docker-compose.yml的文件,内容如下:

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./src:/(nginx config root folder)
      - ./config/site.conf:/etc/nginx/conf.d/site.conf
    links:
      - php
      - mariadb

  php:
      image: php:7-fpm
  mariadb:
      image: mariadb
      restart: always
      environment:
        MYSQL_ROOT_PASSWORD: example

您的项目文件夹中将会有一个名为/config/的文件夹,您需要在其中添加一个site.conf文件以进行nginx设置。
您还需要在项目文件夹中添加一个名为/src/的文件夹,其中包含了您的项目所有的php/web代码。
docker-compose.yml文件中进行卷载入,这些代码将被加载到容器中。卷载入通过映射host文件夹路径:container文件夹路径来工作。当一个文件夹中的内容发生改变时,另一个文件夹中的内容也会进行更新,就像复制和粘贴一样。请注意,您可能需要更新文件权限。
对于Mariadb,您可以添加另一个volume来将容器中的数据文件映射到您的主机文件夹中。此外,您可以通过添加端口3306ports部分(如web部分所示)来打开mysql端口,以便使用mysql workbench等工具查询数据库。您设置的mysql_root_password值将设置root用户密码。
您可以从项目目录中运行命令docker-compose up来启动它。
如果您需要手动重启nginx(或其他服务),您需要停止并重新启动容器。您可以使用以下命令完成此操作:
  • docker-compose up - 启动容器
  • docker-compose down - 停止容器
如果您希望将正在运行的容器发送到后台(这样它就不会占用终端窗口),则可以使用docker-compose up -d命令。
如果您有任何问题或不明白某些内容,请随时告诉我,我很乐意更新我的回答!

谢谢你的回答。我会在这个问题上放一个200的赏金,因为我已经两周没有办法继续我的项目了,以便拥有完美的设置。我听说过docker compose,但不知道它是我的解决方案。你能详细解释一下吗?比如如何在docker和Windows之间共享文件夹,以及如何访问bash,以便我可以重新启动/停止php、nginx mariadb或进行数据库转储?或者构建镜像?我不知道docker compose是如何做到的,但一旦我在本地成功设置好了,我还需要将我的项目上传到生产环境。如果你愿意,你可以等待赏金增加后再扩展你的回答。 - samayo
1
我并不关心赏金的时间,而更在于提供有用、有帮助的答案。我会更新我的回答,详细说明如何使用“卷”来分享文件,我还会详细介绍docker compose命令的启动/停止以及一些有用的数据库技巧和提示! - Danoweb
谢谢兄弟,我迫不及待要试试。 - samayo
嘿,我之前发布了一个错误,但我找到了解决方法。有没有办法访问日志?像nginx、php或mariadb的错误/访问日志?我无法在退出docker之前进入虚拟机,如果您能添加一种在生产服务器上复制我的设置的方法,我将不胜感激。我只需上传docker-compose文件并运行相同的命令,还是需要创建一个镜像并将其上传到我的VPS中? - samayo
这份文档是最佳实践(以及部署到生产环境)的指南:https://docs.docker.com/develop/dev-best-practices/ 如果你运行容器并将其发送到后台 docker-compose up -d,只要它在运行中,你就可以通过 docker exec -it (container_name) /bin/bash 在容器中获取 shell。你还可以使用命令 docker logs 查看该容器正在写入的日志。 - Danoweb
显示剩余6条评论

8
你可以使用我的docker-compose文件(mariadb,php-fpm,nginx)
https://github.com/matchish/skeleton

只需运行

docker-compose up -d

http://localhost上,您将看到“Hello world”

您可以在.env文件中编辑环境变量

此外,我推荐https://laradock.io/

您可以在任何服务中运行终端

docker-compose exec db bash
docker-compose exec php-fpm bash
docker-compose exec nginx bash 

另外,您可以添加数据库初始化文件。请在此文件中阅读手册 https://github.com/matchish/skeleton/blob/master/mariadb/docker-entrypoint-initdb.d/createdb.sql.example

要重新启动服务,请停止容器,然后再次启动它。

docker-compose stop nginx 
docker-compose up -d nginx

如果您需要编辑Nginx配置,您需要重建镜像。

docker-compose build nginx 
docker-compose up -d

如果您需要使用phpmyadmin,可以将其添加到compose文件中。
phpmyadmin:
  image: phpmyadmin/phpmyadmin
  environment:
    PMA_HOST: db
    PMA_PORT: 3306
  ports:
    - '8181:80'

现在您可以通过http://localhost:8181访问它。
在生产环境中使用compose最简单的方法是将项目目录复制到生产服务器并运行docker-compose up -d。您可以排除logs目录。最好有多个compose文件(https://docs.docker.com/compose/production/)。
在部署到生产环境时,请记得保留文件权限。

3
Docker-compose很好用但不是最易于使用的。你应该真正了解Lando,因为它使开发环境设置变得非常简单。它基本上是在Docker之上的可用性层,非常流畅。
在我继续之前,我需要提到Lando实际上不能与Windows 10 Home配合使用,因为Windows版本的Docker使用Hyper-V,而Hyper-V仅适用于Win10 Pro。不过,通过WSL和特别是WSL2的出现,这一切都可以在没有Hyper-V的Windows版本上完成。Mac和Linux可以正常工作。
Lando有“recipes”,这些是减少您需要编写的配置量的起点。如果您正在开发Drupal或WordPress网站,则有相应的recipes。或者如果您从头开始编写某些东西,则还有LAMP和LEMP recipes。
安装Lando后,您只需为您的应用程序创建一个配置文件并启动即可。有一个lando init命令,通过询问您一些问题来生成配置文件,但我更喜欢手动编写.lando.yml配置文件,因为它并不难。
如果你想要一个LEMP设置,你的配置应该类似于这样:
name: put-your-site-name-here
recipe: lemp
config:
  php: '7.1'        # optional; defaults to the latest version
  webroot: web      # optional; defaults to the same directory as this file
  database: mariadb # technically optional but you did say you wanted this
  xdebug: true      # optional
  conf:             # optional; specify your own configs for nginx and/or php as follows
    server: my-config-path/nginx.conf
    php: my-config-path/php.ini

就是这样!将其放入.lando.yml文件中,运行lando start,您将很快拥有一个正在运行的应用程序。

目前最新的 beta 版本是最稳定的版本,但不用担心。我每天在工作中都使用它。 在 GitHub 上浏览发布版本。


谢谢你的回答,我希望这个可以解决我的问题,lando看起来很不错,但它是一个第三方应用程序,你不知道它会存在多久。与此同时,使用另一个库来代替一些你可以花更多时间学习Docker的东西并不明智,除此之外,我也使用Windows 10,所以这个解决方案对我来说不适用。 - samayo
如果第三方应用程序能帮助您实现目标,那么它就不足为惧。此外,如果您已经在Windows 10上使用Docker,则可能会起作用。这取决于Docker的安装方式。使用纯Docker不仅涉及学习所需的时间 - 还涉及使用它所需的时间。这就是Lando加速事情的地方。 - Garrett W.

0

这里有几个答案建议两件非常准确的事情:

  1. 每个服务都应该有自己的Docker容器(正如您已经发现的那样)
  2. 流行的方法包括自定义docker-compose文件,或者通过像Vagrant、Laravel、Lando、LaraDock等工具将另一个层添加到您的堆栈中...

但更重要的是,如果您尝试为如此简单的LEMP堆栈服务器设置多个Docker容器时遇到了如此多的困难和挫折(无论您采取何种方法),也许考虑放弃整个容器方法。

假设您正在设置WordPress服务器,则有一些选项,例如支持PHP Composer的Roots Trellis,或者EasyEngine v4已经集成了Docker。

甚至更轻的选择是我们团队的SlickStack,它没有任何容器,只需要基本的Bash命令知识来部署LEMP堆栈服务器。

您提到对依赖过多第三方应用程序的警惕,因此这些应用程序会消除这些问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接