使用 docker 部署你的 Laravel 项目

使 docker 部署 laravel 项目#

一。安装 docker#

  • 一。安装 docker
  • 二。下载镜像
  • 三。自定义 php 镜像
  • 四。运行自己的应用环境

    我使用的是 centos 7.2,在 centos 下安装 docker 是件非常容易的事情,在命令行执行:

yum install docker

完成安装之后开启 docker 和加人开机自启动,可以使用 命令:

service docker start
chkconfig docker on

此处采用了旧式的 sysv 语法,如采用 CentOS 7 中支持的新式 systemd 语法,如下:

systemctl  start docker.service
systemctl  enable docker.service

看看你的 docker 安装结果,运行命令:

docker —version

显示以下提示,那么就恭喜你安装成功

Docker version 1.10.3, build cb079f6-unsupported

二。下载镜像#

docker 官方有 dockerhub 提供安全切完善的镜像下载,而且 docker 提供了很方便的方式可以在 docker 客户端执命令即可。首先分析我们需要哪些 docker 镜像才能完成项目的部署。我们需要一个提供 http 服务的 container,一个 mysqlcontainer,一个 rediscontainer,一个 php-fpmcontainer,最后还有一个数据卷 container,那么我们就需要去下载这些镜像,在命令行下可以使用 docker search Images_name 去搜索你想要的镜像

首先 pull 基础镜像 Ubuntu 的

docker pull docker.io/ubuntu

由于 laravel 框架使用 php 版本比较高,所以我建议大家都使用 php7 以上的版本,而且我这里使用了 redis,需要安装 redis 扩展,PDO 扩展,XML 扩展等等,所以我决定自己 build 一个 image。那么就开始吧

首先创建一个 Dockerfile 文件,输入以下内容

FROM ubuntu:latest

RUN apt-get update && apt-get install -y software-properties-common language-pack-en-base \
    && LC_ALL=en_US.UTF-8 add-apt-repository -y ppa:ondrej/php \
    && apt-get update \
    && apt-get install -y php-xml php7.0 php7.0-fpm php7.0-mysql mcrypt php7.0-gd curl \
       php7.0-curl php-redis php7.0-mbstring sendmail supervisor \
    && mkdir /run/php \
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

RUN sed -i -e 's/listen = \/run\/php\/php7.0-fpm.sock/listen = 0.0.0.0:9000/g' /etc/php/7.0/fpm/pool.d/www.conf \
    && sed -i -e 's/;daemonize = yes/daemonize = no/g' /etc/php/7.0/fpm/php-fpm.conf

WORKDIR /var/app

EXPOSE 9000

CMD ["/usr/bin/supervisord"]

除了 Dockerfile 以外,我们还需要一个 supervisor 文件,放在 Dockerfile 同级目录。

那么就创建一个 supervisor 文件吧。内容如下:

[supervisord]
nodaemon = true
logfile = /var/log/supervisord.log
logfile_maxbytes = 10MB
pidfile = /var/run/supervisord.pid

[program:php-fpm]
command = php-fpm7.0
user = root
autostart = true
autorestart = true

这里我们的 php-fpm 镜像还没有完成,还需要 build, 输入命令:

docker build -t php7-fpm -f Dockerfile

另外一个需要自定义的镜像就是 nginx,我就不废话那么多了,直接贴 Dockerfile, 另外我们需要加载一个 nginx 的配置和一个 nginx 网站的配置,玩过 nginx 的同学都懂啦。

FROM docker.io/nginx
RUN mkdir -p /var/app \
    && chown -R nginx:nginx /var/app
WORKDIR /var/app
COPY nginx.conf /etc/nginx/nginx.conf

接下来给你们分享一下我的 nginx 的配置和网站配置,nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    server_tokens off;
    include /etc/nginx/conf.d/*.conf;
}

请记住你上面设置的 user 因为 dockerfile 里面设置工作目录要讲 nginx 用户权限给它

继续给网站配置吧 default.conf

server {
    listen 80;

    # 用真实的域名替换 “_”
    server_name your_domain_name;

    charset utf-8;

    root   /var/app/public;
    index  index.php index.html index.htm;

    gzip on;
    gzip_disable "msie6";
    gzip_types text/plain text/css text/xml text/javascript application/json
        application/x-javascript application/xml application/xml+rss application/javascript;

    error_page 404 = /index.php;

    access_log off;
    error_log /var/log/nginx/error.log crit;

    client_max_body_size 64m;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location /. {
        return 404;
    }

    location ~ \.php$ {
         include fastcgi_params;
         try_files $uri =404;

         fastcgi_pass php:9000;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_read_timeout 300;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_index index.php;
    }

    location ~ /\.ht {
        deny  all;
    }
}

请注意,fastcgi_pass php:9000 ,这里不再是 127.0.0.1:9000,因为你的 php 解析交给 php-fpmcontainer 处理,所以这里的 php 就是 php-fpm 的别名

OK,需要自定义的两个 container 已经完成,下面另外两个,redismysql 就直接使用 docker 官方提供的镜像。

直接使用命令拉下来吧:

docker pull docker.io/redis
docker pull docker.io/mysql

接下来比较重要,因为我们的 container 运行有依赖关系的,首先,php 运行需要 linkmysqlredis 的,nginx 启动是要 linkphp 上的,请允许我用依赖这个词来简单的说吧。所以首先要启动 redismysql 两个 container,再启动 php,等 php 启动之后最后才能启动 nginx

接下来我就用我学到的基础知识,来让你们把 laravel 运行到 docker 上吧

首先我们启动 redismysql,这里我必须说一下的是,这就是使用 docker 的好处,如果你的 mysqlredis 突然崩溃,你可以不用担心数据有任何闪失,因为我们再 container 外挂在了一个数据卷,什么事数据卷可以自己度娘,不多废话,直接上运行命令吧。

那就先启动 mysql, 我将 mysql 的 data 文件挂载到了宿主机上,这样就实时同步备份了 container 的数据

docker run -d —name=testmysql  -v /var/data:/var/lib/mysql MYSQL_ROOT_PASSWORD=testpassword  -e MYSQL_DATABASE=test_database docker.io/mysql

这里说明一下命令和参数是干嘛的,-d 是后台运行 --name=testmyql 是设置 container 名称,-v 是挂载宿主机到 container -e 设置环境变量传递 mysql 密码 -e 参数是可以多次使用
,例如:-v 前面是你宿主机的路径,冒号是你容器里的路径。

再启动 redis, 同样也挂载了 redis 的备份文件

docker run -d --name redis -v /var/www/mydoc/shares/dump.rdb:/data/dump.rdb docker.io/redis

有了 redismysql,我们就可以启动 php-fpm 了

docker run -d --name php -v /var/www/mydoc/shares/:/var/app --link mysql:mysql --link redis:redis php-fpm

这里除了上面加的参数以外,我们使用了 —link 这个是链接两个容器,使两个容器能够通信

最后我们运行 nginx 来提供 http 服务

docker run -d -p 80:80 -v /var/data/conf/:/etc/nginx/conf.d/ --volumes-from php —link php:php nginx

这里解释一下 --volume-from ,它的意思是数据来自 php 这个 container

OK ,至此,容器基本上都启动完毕。当然,如何将网站跑起来,需要你自己思考,学习嘛。必须自己动动脑子,当然我这个也是比较基础的。希望大神看到勿喷。

欢迎加 QQ:343125118 交流.

最后我也提供一下我已经构建好的镜像给大家使用,我已经放在 dockerhub 上了,不需要上面的 dockerfile 去构建,直接使用就可以:

docker pull docker.io/beandu/php7-fpm
docker pull docker.io/beandu/nginx
本帖已被设为精华帖!
本帖由系统于 7年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 20
superwen

在配上 docker-composer 就更好了。类似 php 的 composer,也很好用。

8年前 评论

@superwen 是的,下次的的分享会把 docker-compose 作为重点

8年前 评论
CMD [/usr/bin/supervisord"]

这里写错了,前面的引号是 ",不是 。害得我 build 了也不能运行 [:cry: ]

7年前 评论

没有责怪的意思 是希望楼主更新下

7年前 评论

@Ahri 非常感谢你帮我指出的错误

7年前 评论

@bean 这个镜像能部署到阿里云的容器服务上吗?

7年前 评论

可以的,只要你的服务器有 docker

7年前 评论

docker 已接在 centos 上运行了,没有必要在安装 ubuntu 了把

6年前 评论

那问题来了,laravel 队列呢

6年前 评论

@running-fly 这里的 Ubuntu 事指我的基础镜像

4年前 评论

@AlicFeng 不好意思,我已经转 go 语言很久了,没有研究过 laravel 自带的队列了,如果你使用 kafka 或者 nsq 什么的,也可以直接在 dockerhub 上找到对应的镜像,在你的代码里面配置就可以了

4年前 评论

QQ 不存在啊

4年前 评论
bean (楼主) 4年前
HiDaddy (作者) 4年前

问一个小白问题大佬,为什么我的 storage,我设置了 chmod 权限,但是每天有新的日志的时候,还是给我报错 failed to open stream: Permission denied 我得每天进行 chmod。你 QQ 号加不上,希望得到大佬的帮助,救救孩子吧:1217215022

4年前 评论
kai_wang 3年前

FROM webdevops/php-nginx

设置工作目录

WORKDIR /var/www

将当前目录下的文件拷贝到工作目录

COPY . . COPY .env .

安装 Laravel 的依赖包

RUN composer install

Nginx 配置相关

RUN rm -rf /etc/nginx/conf.d/* COPY nginx.conf /etc/nginx/conf.d RUN chmod -R 777 /var/www/*

CMD ["php", "artisan", "serve", "--host=127.0.0.1"]

EXPOSE 8081 这是我的 Dockerfile 文件

2年前 评论

server { listen 8081; index index.php index.html; root /var/www/public;

location / {
    proxy_pass http://host.docker.internal:8000;
}

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:8000;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

}
这是我的 nginx.conf 文件

2年前 评论

但是现在的问题是我使用 postman 访问该服务中的 API 接口报错 Error: connect ECONNREFUSED 192.168.18.3:8081

2年前 评论

有哪位大佬可以帮忙看看是什么原因?

2年前 评论