详见本人之前写的另一篇文章:Docker操作命令小助手
确保你的终端已经安装了 PHP 和 Composer,然后执行以下命令创建一个新的 Laravel 项目。当应用程序创建完成后,你可以通过 Artisan CLI 的 serve
命令来启动 Laravel 的本地服务测试服务是否正常
composer create-project laravel/laravel example-app
cd example-app
php artisan serve
本次构建使用的镜像为:richarvey/nginx-php-fpm,更新版本请前往该项目的Github。
nginx.conf
,nginx-site.conf
,nginx-site-ssl.conf
,supervisord.conf
输入内容分别如下:nginx.conf
#user nobody;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
client_header_buffer_size 4k;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 2;
client_max_body_size 25m;
server_tokens off;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
nginx-site.conf
server {
listen 80;
server_name laravel.com;
root /var/www/html/public;
index index.php index.html index.htm;
error_log /var/log/nginx/error_laravel.log error;
access_log /var/log/nginx/access_laravel.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
include fastcgi_params;
}
location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$ {
expires 2d;
}
location ~ .*\.(?:js|css)$ {
expires 8h;
}
location ~ /\. {
log_not_found off;
deny all;
}
}
nginx-site-ssl.conf
server {
listen 443 ssl http2;
server_name _;
root /var/www/html/public;
index index.php index.html index.htm;
ssl_certificate /etc/nginx/ssl/_.pem;
sl_certificate_key /etc/nginx/ssl/_.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Make site accessible from http://localhost/
# Add stdout logging
error_log /var/log/nginx/error_laravel.log error;
access_log /var/log/nginx/access_laravel.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
# pass the PHP scripts to FastCGI server listening on socket
#
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|webp|tiff|ttf|svg)$ {
expires 5d;
}
# deny access to . files, for security
#
location ~ /\. {
log_not_found off;
deny all;
}
location ^~ /.well-known {
allow all;
auth_basic off;
}
}
supervisord.conf
[unix_http_server]
file=/dev/shm/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket
[program:php-fpm]
command = /usr/local/sbin/php-fpm --force-stderr --nodaemonize --fpm-config /usr/local/etc/php-fpm.d/www.conf
autostart=true
autorestart=true
priority=5
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT
[program:nginx]
command=/usr/sbin/nginx -g "daemon off; error_log /dev/stderr info;"
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT
[program:queue-work]
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --timeout=85 --daemon
autostart=true
autorestart=true
priority=5
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT
[include]
files = /etc/supervisor/conf.d/*.conf
Dockerfile
文件,输入以下内容FROM richarvey/nginx-php-fpm:1.10.4
RUN sed -i "s/pm.max_children = [0-9]\+/pm.max_children = 64/g" /usr/local/etc/php-fpm.d/www.conf \
&& sed -i "s/pm.start_servers = [0-9]\+/pm.start_servers = 8/g" /usr/local/etc/php-fpm.d/www.conf \
&& sed -i "s/pm.min_spare_servers = [0-9]\+/pm.min_spare_servers = 8/g" /usr/local/etc/php-fpm.d/www.conf \
&& sed -i "s/pm.max_spare_servers = [0-9]\+/pm.max_spare_servers = 32/g" /usr/local/etc/php-fpm.d/www.conf \
&& cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
&& sed -i 's/session.save_handler = files/session.save_handler = redis\nsession.save_path = "tcp:\/\/redis:6379"/g' /usr/local/etc/php/php.ini \
&& sed -i 's/session.gc_maxlifetime = 1440/session.gc_maxlifetime = 14400/g' /usr/local/etc/php/php.ini \
&& sed -i 's/memory_limit = 128M/memory_limit = 512M/g' /usr/local/etc/php/conf.d/docker-vars.ini \
&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache lua-resty-core nginx-mod-http-lua \
&& docker-php-ext-install sockets bcmath
# Copy our nginx config
RUN rm -Rf /etc/nginx/nginx.conf
COPY conf/nginx.conf /etc/nginx/nginx.conf
COPY conf/nginx-site.conf /etc/nginx/conf.d/default.conf
COPY conf/nginx-site-ssl.conf /etc/nginx/conf.d/default-ssl.conf
# Copy our nginx ssl
COPY conf/ssl /etc/nginx/ssl
# Copy our supervisord config
COPY conf/supervisord.conf /etc/supervisord.conf
# Copy our shell
COPY start.sh /start.sh
COPY . /var/www/html
RUN cd /var/www/html \
&& composer install -o --no-dev \
&& cp .env.local .env \
&& chown -Rf nginx.nginx /var/www/html \
&& chmod +x /start.sh
EXPOSE 443 80
WORKDIR /var/www/html
CMD ["/start.sh"]
#!/bin/bash
# Set custom webroot
if [ ! -z "$WEBROOT" ]; then
sed -i "s#root /var/www/html;#root ${WEBROOT};#g" /etc/nginx/conf.d/default.conf
else
webroot=/var/www/html
fi
# Enables 404 pages through php index
if [ ! -z "$PHP_CATCHALL" ]; then
sed -i 's#try_files $uri $uri/ =404;#try_files $uri $uri/ /index.php?$args;#g' /etc/nginx/conf.d/default.conf
fi
# Enable custom nginx config files if they exist
if [ -f /var/www/html/conf/nginx/nginx.conf ]; then
cp /var/www/html/conf/nginx/nginx.conf /etc/nginx/nginx.conf
fi
if [ -f /var/www/html/conf/nginx/nginx-site.conf ]; then
cp /var/www/html/conf/nginx/nginx-site.conf /etc/nginx/conf.d/default.conf
fi
if [ -f /var/www/html/conf/nginx/nginx-site-ssl.conf ]; then
cp /var/www/html/conf/nginx/nginx-site-ssl.conf /etc/nginx/conf.d/default-ssl.conf
fi
# Display PHP error's or not
if [[ "$ERRORS" != "1" ]] ; then
echo php_flag[display_errors] = off >> /usr/local/etc/php-fpm.d/www.conf
else
echo php_flag[display_errors] = on >> /usr/local/etc/php-fpm.d/www.conf
fi
# Display Version Details or not
if [[ "$HIDE_NGINX_HEADERS" == "0" ]] ; then
sed -i "s/server_tokens off;/server_tokens on;/g" /etc/nginx/nginx.conf
else
sed -i "s/expose_php = On/expose_php = Off/g" /usr/local/etc/php-fpm.conf
fi
# Pass real-ip to logs when behind ELB, etc
if [[ "$REAL_IP_HEADER" == "1" ]] ; then
sed -i "s/#real_ip_header X-Forwarded-For;/real_ip_header X-Forwarded-For;/" /etc/nginx/conf.d/default.conf
sed -i "s/#set_real_ip_from/set_real_ip_from/" /etc/nginx/conf.d/default.conf
if [ ! -z "$REAL_IP_FROM" ]; then
sed -i "s#172.16.0.0/12#$REAL_IP_FROM#" /etc/nginx/conf.d/default.conf
fi
fi
# Do the same for SSL sites
if [ -f /etc/nginx/conf.d/default-ssl.conf ]; then
if [[ "$REAL_IP_HEADER" == "1" ]] ; then
sed -i "s/#real_ip_header X-Forwarded-For;/real_ip_header X-Forwarded-For;/" /etc/nginx/conf.d/default-ssl.conf
sed -i "s/#set_real_ip_from/set_real_ip_from/" /etc/nginx/conf.d/default-ssl.conf
if [ ! -z "$REAL_IP_FROM" ]; then
sed -i "s#172.16.0.0/12#$REAL_IP_FROM#" /etc/nginx/conf.d/default-ssl.conf
fi
fi
fi
# Set the desired timezone
echo date.timezone=$(cat /etc/TZ) > /usr/local/etc/php/conf.d/timezone.ini
# Display errors in docker logs
if [ ! -z "$PHP_ERRORS_STDERR" ]; then
echo "log_errors = On" >> /usr/local/etc/php/conf.d/docker-vars.ini
echo "error_log = /dev/stderr" >> /usr/local/etc/php/conf.d/docker-vars.ini
fi
# Increase the memory_limit
if [ ! -z "$PHP_MEM_LIMIT" ]; then
sed -i "s/memory_limit = 128M/memory_limit = ${PHP_MEM_LIMIT}M/g" /usr/local/etc/php/conf.d/docker-vars.ini
fi
# Increase the post_max_size
if [ ! -z "$PHP_POST_MAX_SIZE" ]; then
sed -i "s/post_max_size = 100M/post_max_size = ${PHP_POST_MAX_SIZE}M/g" /usr/local/etc/php/conf.d/docker-vars.ini
fi
# Increase the upload_max_filesize
if [ ! -z "$PHP_UPLOAD_MAX_FILESIZE" ]; then
sed -i "s/upload_max_filesize = 100M/upload_max_filesize= ${PHP_UPLOAD_MAX_FILESIZE}M/g" /usr/local/etc/php/conf.d/docker-vars.ini
fi
# Enable xdebug
XdebugFile='/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini'
if [[ "$ENABLE_XDEBUG" == "1" ]] ; then
if [ -f $XdebugFile ]; then
echo "Xdebug enabled"
else
echo "Enabling xdebug"
echo "If you get this error, you can safely ignore it: /usr/local/bin/docker-php-ext-enable: line 83: nm: not found"
# see https://github.com/docker-library/php/pull/420
docker-php-ext-enable xdebug
# see if file exists
if [ -f $XdebugFile ]; then
# See if file contains xdebug text.
if grep -q xdebug.remote_enable "$XdebugFile"; then
echo "Xdebug already enabled... skipping"
else
echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > $XdebugFile # Note, single arrow to overwrite file.
echo "xdebug.remote_enable=1 " >> $XdebugFile
echo "xdebug.remote_host=host.docker.internal" >> $XdebugFile
echo "xdebug.remote_log=/tmp/xdebug.log" >> $XdebugFile
echo "xdebug.remote_autostart=false " >> $XdebugFile # I use the xdebug chrome extension instead of using autostart
# NOTE: xdebug.remote_host is not needed here if you set an environment variable in docker-compose like so `- XDEBUG_CONFIG=remote_host=192.168.111.27`.
# you also need to set an env var `- PHP_IDE_CONFIG=serverName=docker`
fi
fi
fi
else
if [ -f $XdebugFile ]; then
echo "Disabling Xdebug"
rm $XdebugFile
fi
fi
if [ ! -z "$PUID" ]; then
if [ -z "$PGID" ]; then
PGID=${PUID}
fi
deluser nginx
addgroup -g ${PGID} nginx
adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx -u ${PUID} nginx
else
if [ -z "$SKIP_CHOWN" ]; then
chown -Rf nginx.nginx /var/www/html
fi
fi
# Run custom scripts
if [[ "$RUN_SCRIPTS" == "1" ]] ; then
if [ -d "/var/www/html/scripts/" ]; then
# make scripts executable incase they aren't
chmod -Rf 750 /var/www/html/scripts/*; sync;
# run scripts in number order
for i in `ls /var/www/html/scripts/`; do /var/www/html/scripts/$i ; done
else
echo "Can't find script directory"
fi
fi
if [ -z "$SKIP_COMPOSER" ]; then
# Allow nginx user to call composer closes #169
# Try auto install for composer
if [ -f "/var/www/html/composer.lock" ]; then
if [ "$APPLICATION_ENV" == "development" ]; then
su - nginx -c 'composer global require hirak/prestissimo'
su - nginx -c 'composer install --working-dir=/var/www/html'
else
su - nginx -c 'composer global require hirak/prestissimo'
su - nginx -c 'composer install --no-dev --working-dir=/var/www/html'
fi
fi
fi
# Start supervisord and services
exec /usr/bin/supervisord -n -c /etc/supervisord.conf
version: '3'
services:
web:
build:
context: ./
dockerfile: Dockerfile
image: "xxx/laravelapp:8" #该处为了举例配置,是一个错误的镜像仓库,可自行将镜像上传仓库后配置
container_name: "laravel_app"
ports:
- "80:80"
- "443:443"
depends_on:
- redis
- mysql
links:
- redis
- mysql
volumes:
- "/home/web/storage:/var/www/html/storage"
- "/etc/localtime:/etc/localtime"
redis:
image: "redis:alpine"
container_name: "laravel_redis"
restart: unless-stopped
volumes:
- "/home/web/redis:/data"
- "/etc/localtime:/etc/localtime"
mysql:
image: mysql:8
container_name: "laravel_mysql"
security_opt:
- seccomp:unconfined
restart: unless-stopped
volumes:
- "/home/web/mysql/data/:/var/lib/mysql"
- "/etc/localtime:/etc/localtime"
environment:
MYSQL_ROOT_PASSWORD: Pc4hzz.sf
ports:
- "3306:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: "laravel_phpmyadmin"
restart: unless-stopped
volumes:
- "/etc/localtime:/etc/localtime"
environment:
- PMA_HOST=mysql
depends_on:
- mysql
ports:
- "8008:80"
直接运行
docker-compose up -d
上传至 hub.docker.com
仓库
# 打包镜像
docker build -t 你的仓库用户名/laravelapp:8 .
# 登录
docker login
# 上传刚才打包的镜像
docker push 你的仓库用户名/laravelapp:8
# 通过docker-compose拉取镜像
docker-compose -f docker-compose.yml pull
# 启动
docker-compose up -d
#重启
docker-compose restart
http://127.0.0.1:80 or http://127.0.0.1:443