尝试使用 docker 部署 Laravel 项目

环境: ubnutu18.04 虚拟机上通过docker部署,首先需要安装好docker环境
安装docker

docker 镜像要求

  • 基于Alpine Linux的容器。
  • Nginx Web服务器。
  • PHP 7.0或更高版本。
  • OpenSSL PHP扩展。
  • PDO PHP扩展。
  • Mbstring PHP扩展。
  • Tokenizer PHP扩展。
  • XML PHP扩展。

1. 创建laradocker目录

mkdir laradocker

2. 进入目录cd laradocker 创建 Dockerfile 文件 vim Dockerfile

FROM nginx:mainline-alpine
LABEL maintainer="Jaak zhang <xxxx@163.come>" 

COPY start.sh /start.sh
COPY nginx.conf /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf
COPY site.conf /etc/nginx/sites-available/default.conf

RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/community/" >> /etc/apk/repositories
RUN apk update

RUN apk add --update curl  php7-fpm php7  php7-dev  php7-apcu  php7-bcmath  php7-xmlwriter  php7-ctype  php7-curl  php7-exif  php7-iconv  php7-intl  php7-json  php7-mbstring php7-opcache  php7-openssl  php7-pcntl  php7-pdo  php7-mysqlnd  php7-mysqli  php7-pdo_mysql  php7-pdo_pgsql  php7-phar  php7-posix  php7-session  php7-xml  php7-simplexml  php7-mcrypt  php7-xsl  php7-zip  php7-zlib  php7-dom  php7-redis php7-tokenizer  php7-gd  php7-fileinfo  php7-zmq  php7-memcached  php7-xmlreader 

RUN curl -sS https://getcomposer.org/installer | \
php -- --install-dir=/usr/bin/ --filename=composer

RUN apk add --update bash vim openssh-client supervisor

RUN mkdir -p /etc/nginx && \
mkdir -p /etc/nginx/sites-available && \
mkdir -p /etc/nginx/sites-enabled && \
mkdir -p /run/nginx && \
ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/default.conf && \
mkdir -p /var/log/supervisor && \
rm -Rf /var/www/* && \
chmod 755 /start.sh

RUN sed -i -e "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" \
-e "s/variables_order = \"GPCS\"/variables_order = \"EGPCS\"/g" \
/etc/php7/php.ini && \
sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" \
-e "s/;catch_workers_output\s*=\s*yes/catch_workers_output = yes/g" \
-e "s/user = nobody/user = nginx/g" \
-e "s/group = nobody/group = nginx/g" \
-e "s/;listen.mode = 0660/listen.mode = 0666/g" \
-e "s/;listen.owner = nobody/listen.owner = nginx/g" \
-e "s/;listen.group = nobody/listen.group = nginx/g" \
-e "s/listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm.sock/g" \
-e "s/^;clear_env = no$/clear_env = no/" \
/etc/php7/php-fpm.d/www.conf

EXPOSE 443 80
WORKDIR /var/www

CMD ["/start.sh"]

3. laradocker目录下创建start.sh 文件; vim start.sh

#!/bin/bash

# ----------------------------------------------------------------------
# Create the .env file if it does not exist.
# ----------------------------------------------------------------------
if [[ ! -f "/var/www/.env" ]] && [[ -f "/var/www/.env.example" ]];
then
    cp /var/www/.env.example /var/www/.env
fi

# ----------------------------------------------------------------------
# Run Composer
# ----------------------------------------------------------------------
if [[ ! -d "/var/www/vendor" ]];
then
    cd /var/www
    composer update
    composer dump-autoload -o
fi

# ----------------------------------------------------------------------
# Start supervisord
# ----------------------------------------------------------------------
exec /usr/bin/supervisord -n -c /etc/supervisord.conf

4. laradocker目录下创建nginx.conf 文件; vim 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;
    access_log off;
    sendfile on;
    #tcp_nopush on;
    keepalive_timeout 65;
    #gzip on;
    include /etc/nginx/sites-enabled/*.conf;
}

5. 同样创建site.conf文件 vim site.conf

server {
    listen 80;

    root /var/www/public;
    index index.php index.html;

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

    location ~ /\. {
        deny all;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

6.创建supervisord.conf文件


[unix_http_server]
file=/dev/shm/supervisor.sock

[supervisord]
logfile=/tmp/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=warn
pidfile=/tmp/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200
user=root

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock

[program:php-fpm7]
command = /usr/sbin/php-fpm7 --nodaemonize --fpm-config /etc/php7/php-fpm.d/www.conf
autostart=true
autorestart=true
priority=5
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

7. laradocker目录下创建src文件夹 把你的laravel项目代码git clone下来 或者cpoy进去; laradocker 执行ls应该是下面几个目录文件

root@localhost:~/laraDocker# ls
Dockerfile  nginx.conf  site.conf  src  start.sh  supervisord.conf
root@localhost:~/laraDocker# cd src/
root@localhost:~/laraDocker/src# ls
blog
# 这里我clone下来的是个blog项目

8. 构建docker镜像

$ docker build -t  my-image .

9.容器运行, 终端上运行以下命令:

# 将`$PWD/src`目录挂载到`/var/www`容器中。`$PWD`将返回到当前工作目录的路径。
$ docker run -d -p 8000:80 -v $PWD/src/blog:/var/www --name="container-lara" my-image

10. 访问你的虚拟机IP+端口号8000, 我的是http://192.168.8.225:8000

出现错误 是laravel项目的key没有,执行命令 docker exec -it container-lara bash进入容器
这里其实也可以在start.sh文件中先加入php artisan key:generate命令

root@localhost:~/laraDocker# docker exec -it container-lara bash
bash-5.0# ls
LICENSE            bootstrap          database           phpcs.sh           routes             vendor
README.md          composer.json      frontend           phpunit.xml        server.php         webpack.mix.js
app                composer.lock      package-lock.json  public             storage
artisan            config             package.json       resources          tests
bash-5.0# pwd
/var/www
bash-5.0# php artisan key:generate
Application key [base64:Br4OjMwsByCHcL797l/eyTu9V+gYTWnL+YgShopHTzI=] set successfully.
bash-5.0# 

依然报错是因为mysql问题 没有安装mysql
使用docker拉取mysql镜像

  • 执行命令docker pull mysql:5.7
  • 运行mysql容器 执行命令
    docker run -d -p 3306:3306 --name db-mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=blog -d mysql:5.7
  • 修改src目录下blog项目目录下.env文件中mysql相关配置即可

项目有用到redis,docker拉取redis镜像

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
jaak
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 19

RUN 部分可以合并、可以减小构建镜像的大小,对指令会将镜像分层增加从而增加镜像的大小。构建开发可以分多个,这样的话、推荐构建基础镜像。

4年前 评论
jaak (楼主) 4年前

有没有用过laradock,怎么让同一个局域网的同事访问我的项目

4年前 评论
Tricker 4年前
Tricker 4年前
walt-white (作者) 4年前
walt-white (作者) 4年前
jaak

@walt-white 没有用过,我觉得你可以试试在你同事的电脑上修改host文件 添加上你的项目ip 域名,然后域名访问

4年前 评论
walt-white 4年前

请问大佬,我按照流程跑了一遍之后,发现我的工程不能连接 mysql,报错为

SQLSTATE[HY000] [2002] No such file or directory

是不是因为我 mysql 的 docker 没有把 mysql.sock 映射出来,从而我的 Laradocker 不能访问我的 mysql docker

4年前 评论
jaak (楼主) 4年前
walt-white 4年前
php8 4年前
ShibaPipi (作者) 4年前

感觉好难啊,像黑客在秀操作。

4年前 评论
jaak (楼主) 4年前

:+1: 非常好的文章,学习了,谢谢!

3年前 评论

非常感谢楼主大佬的文章!根据楼主老哥大佬的修改的laravel6.x+php7.4+项目代码+laravel计划任务,k8s部署,容器不能连外网,所以没装composer,取而代之的是把代码整个放入容器内,日志、文件目录映射到宿主机,供参考
Dockerfile:

FROM nginx:mainline-alpine

COPY start.sh /start.sh
COPY nginx.conf /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf
COPY site.conf /etc/nginx/sites-available/default.conf
COPY src/feedback /var/www

RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.13/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.13/community/" >> /etc/apk/repositories
RUN apk update

RUN apk add --update curl  php7-fpm php7  php7-dev  php7-apcu  php7-bcmath  php7-xmlwriter  php7-ctype  php7-curl  php7-exif  php7-iconv  php7-intl  php7-json  php7-mbstring php7-opcache  php7-openssl  php7-pcntl  php7-pdo  php7-mysqlnd  php7-mysqli  php7-pdo_mysql  php7-pdo_pgsql  php7-phar  php7-posix  php7-session  php7-xml  php7-simplexml  php7-mcrypt  php7-xsl  php7-zip  php7-zlib  php7-dom  php7-redis php7-tokenizer  php7-gd  php7-fileinfo  php7-zmq  php7-memcached  php7-xmlreader 

RUN apk add --update bash vim openssh-client supervisor

RUN mkdir -p /etc/nginx && \
mkdir -p /etc/nginx/sites-available && \
mkdir -p /etc/nginx/sites-enabled && \
mkdir -p /run/nginx && \
ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/default.conf && \
mkdir -p /var/log/supervisor && \
chmod 755 /start.sh  && \
chmod -R 777 /var/www

RUN sed -i -e "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" \
-e "s/variables_order = \"GPCS\"/variables_order = \"EGPCS\"/g" \
/etc/php7/php.ini && \
sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" \
-e "s/;catch_workers_output\s*=\s*yes/catch_workers_output = yes/g" \
-e "s/user = nobody/user = nginx/g" \
-e "s/group = nobody/group = nginx/g" \
-e "s/;listen.mode = 0660/listen.mode = 0666/g" \
-e "s/;listen.owner = nobody/listen.owner = nginx/g" \
-e "s/;listen.group = nobody/listen.group = nginx/g" \
-e "s/listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm.sock/g" \
-e "s/^;clear_env = no$/clear_env = no/" \
/etc/php7/php-fpm.d/www.conf

EXPOSE 443 80
WORKDIR /var/www

CMD ["/start.sh"]

start.sh

#!/bin/bash

# ----------------------------------------------------------------------
# Create the .env file if it does not exist.
# ----------------------------------------------------------------------
if [[ ! -f "/var/www/.env" ]] && [[ -f "/var/www/.env.example" ]];
then
    cp /var/www/.env.example /var/www/.env
fi

# laravel定时任务,App\Console\Kernel.php中编写,见laravel文档
sed -i '$d' /etc/crontabs/root
echo '*       *       *       *       *       cd /var/www && php artisan schedule:run >> /dev/null 2>&1' >> /etc/crontabs/root
echo '' >> /etc/crontabs/root
crond

# ----------------------------------------------------------------------
# Start supervisord
# ----------------------------------------------------------------------
exec /usr/bin/supervisord -n -c /etc/supervisord.conf

(可选)进入容器验证计划任务是否正常运行:

ps # 查看是否有crond
cat /etc/crontabs/root # 查看laravel计划任务是否正常添加

容器⇌宿主机 映射:
/var/www/public/storage
/var/www/storage/app/public
k8s容器貌似不能link操作,我取而代之的是上面这两个映射到宿主机的同一个目录
/var/log
/var/www/storage/logs
/var/www/.env

3年前 评论

请问如何用dockerfile安装php8呢?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!