Laravel
Laravel 是一个拥有富有表现力、优雅语法的 Web 应用程序框架。我们相信开发必须是一种愉快而有创造力的体验,才能真正令人满足。
使用 Nixpacks 部署
要求
环境变量
如果您的应用程序需要数据库或 Redis,您可以预先在 Coolify 仪表板中创建它们。
您将收到连接字符串,可以在应用程序中使用并将其设置为环境变量:
DB_CONNECTION=mysql
DB_HOST=<DB_HOST>
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
REDIS_HOST=<REDIS_HOST>
REDIS_PASSWORD=null
REDIS_PORT=6379一体化容器
如果您想在一个容器内启动队列工作器、调度器等(推荐),那么您可以在仓库中放置一个 nixpacks.toml,包含以下值。
[phases.setup]
nixPkgs = ["...", "python311Packages.supervisor"]
[phases.build]
cmds = [
"mkdir -p /etc/supervisor/conf.d/",
"cp /assets/worker-*.conf /etc/supervisor/conf.d/",
"cp /assets/supervisord.conf /etc/supervisord.conf",
"chmod +x /assets/start.sh",
"..."
]
[start]
cmd = '/assets/start.sh'
[staticAssets]
"start.sh" = '''
#!/bin/bash
# 转换 nginx 配置
node /assets/scripts/prestart.mjs /assets/nginx.template.conf /etc/nginx.conf
# 启动 supervisor
supervisord -c /etc/supervisord.conf -n
'''
"supervisord.conf" = '''
[unix_http_server]
file=/assets/supervisor.sock
[supervisord]
logfile=/var/log/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/assets/supervisord.pid
nodaemon=false
silent=false
minfds=1024
minprocs=200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///assets/supervisor.sock
[include]
files = /etc/supervisor/conf.d/*.conf
'''
"worker-nginx.conf" = '''
[program:worker-nginx]
process_name=%(program_name)s_%(process_num)02d
command=nginx -c /etc/nginx.conf
autostart=true
autorestart=true
stdout_logfile=/var/log/worker-nginx.log
stderr_logfile=/var/log/worker-nginx.log
'''
"worker-phpfpm.conf" = '''
[program:worker-phpfpm]
process_name=%(program_name)s_%(process_num)02d
command=php-fpm -y /assets/php-fpm.conf -F
autostart=true
autorestart=true
stdout_logfile=/var/log/worker-phpfpm.log
stderr_logfile=/var/log/worker-phpfpm.log
'''
"worker-laravel.conf" = '''
[program:worker-laravel]
process_name=%(program_name)s_%(process_num)02d
command=bash -c 'exec php /app/artisan queue:work --sleep=3 --tries=3 --max-time=3600'
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=12 # 要减少内存/CPU 使用,更改为 2
startsecs=0
stopwaitsecs=3600
stdout_logfile=/var/log/worker-laravel.log
stderr_logfile=/var/log/worker-laravel.log
'''
"php-fpm.conf" = '''
[www]
listen = 127.0.0.1:9000
user = www-data
group = www-data
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.min_spare_servers = 4
pm.max_spare_servers = 32
pm.start_servers = 18
clear_env = no
php_admin_value[post_max_size] = 35M
php_admin_value[upload_max_filesize] = 30M
'''
"nginx.template.conf" = '''
user www-data www-data;
worker_processes 5;
daemon off;
worker_rlimit_nofile 8192;
events {
worker_connections 4096; # 默认值: 1024
}
http {
include $!{nginx}/conf/mime.types;
index index.html index.htm index.php;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx-access.log;
error_log /var/log/nginx-error.log;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # 这似乎是某些虚拟主机所必需的
server {
listen ${PORT};
listen [::]:${PORT};
server_name localhost;
$if(NIXPACKS_PHP_ROOT_DIR) (
root ${NIXPACKS_PHP_ROOT_DIR};
) else (
root /app;
)
add_header X-Content-Type-Options "nosniff";
client_max_body_size 35M;
index index.php;
charset utf-8;
$if(NIXPACKS_PHP_FALLBACK_PATH) (
location / {
try_files $uri $uri/ ${NIXPACKS_PHP_FALLBACK_PATH}?$query_string;
}
) else (
location / {
try_files $uri $uri/ /index.php?$query_string;
}
)
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
$if(IS_LARAVEL) (
error_page 404 /index.php;
) else ()
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include $!{nginx}/conf/fastcgi_params;
include $!{nginx}/conf/fastcgi.conf;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
}
'''与 Inertia.js 一起使用
当使用 Laravel 和 Inertia.js 时,您可能需要在 nixpacks.toml 文件中指定一些额外的配置。
增加 NGINX 缓冲区大小以处理 Inertia 请求
由于 Inertia.js 和默认 NGINX 配置存在已知问题,您可能需要增加 NGINX 的缓冲区大小以处理 Inertia 请求。
"nginx.template.conf" = '''
# ...
http {
# ...
server {
# ...
location ~ \.php$ {
+ fastcgi_buffer_size 8k;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include $!{nginx}/conf/fastcgi_params;
include $!{nginx}/conf/fastcgi.conf;
# ...
}
}
}Inertia SSR
如果您正在使用 Inertia.js 的服务器端渲染功能,您应该在 nixpacks.toml 文件中添加另一个工作器来自动启动 SSR 服务器。
"worker-inertia-ssr.conf" = '''
[program:inertia-ssr]
process_name=%(program_name)s_%(process_num)02d
command=bash -c 'exec php /app/artisan inertia:start-ssr'
autostart=true
autorestart=true
stderr_logfile=/var/log/worker-inertia-ssr.log
stdout_logfile=/var/log/worker-inertia-ssr.log
'''NOTE
默认情况下,Nixpacks 在部署期间运行命令 npm run build 来构建您的应用程序。确保您的 package.json 中的 build 脚本包含服务器端渲染所需的构建命令。如果您使用包含 Inertia.js 的官方入门套件,请这样更改您的脚本:
"scripts": {
- "build": "vite build",
+ "build": "vite build && vite build --ssr",
"build:ssr": "vite build && vite build --ssr",
}或者,如果您不想修改 package.json 中的默认 build 脚本,您可以直接在 nixpacks.toml 配置文件中添加服务器端渲染的正确构建命令。
[phases.build]
cmds = [
+ "npm run build:ssr",
"mkdir -p /etc/supervisor/conf.d/",
"cp /assets/worker-*.conf /etc/supervisor/conf.d/",
"cp /assets/supervisord.conf /etc/supervisord.conf",
"chmod +x /assets/start.sh",
"..."
]持久化 php.ini 自定义
如果您想自定义 php.ini 文件的设置,您可以通过使用 php_admin_value 指令并将它们附加到 php-fpm.conf 文件来轻松实现:
"php-fpm.conf" = '''
[www]
listen = 127.0.0.1:9000
user = www-data
group = www-data
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.min_spare_servers = 4
pm.max_spare_servers = 32
pm.start_servers = 18
clear_env = no
php_admin_value[memory_limit] = 512M
php_admin_value[max_execution_time] = 60
php_admin_value[max_input_time] = 60
php_admin_value[post_max_size] = 256M
'''使用 Dockerfile 和 Nginx Unit 部署
前提条件
- 从私有或公共仓库创建新资源。
- 将
端口暴露字段设置为8000(例如)。 - 在
环境变量的开发者视图中设置默认环境变量:
APP_DEBUG=false
APP_ENV=staging
APP_KEY= #YourAppKey
APP_MAINTENANCE_DRIVER=file
APP_NAME=Laravel
CACHE_STORE=file
DB_CONNECTION= #YourDbConnection
DB_DATABASE= #YourDb
DB_HOST= #YourDbHost
DB_PASSWORD= #YourDbPassword
DB_PORT= #YourDbPort
DB_USERNAME= #YourDbUsername
FILESYSTEM_DISK=public
MAIL_MAILER=log
SESSION_DRIVER=file- 在项目根目录中创建一个
Dockerfile,内容如下:
FROM unit:1.34.1-php8.3
RUN apt update && apt install -y \
curl unzip git libicu-dev libzip-dev libpng-dev libjpeg-dev libfreetype6-dev libssl-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) pcntl opcache pdo pdo_mysql intl zip gd exif ftp bcmath \
&& pecl install redis \
&& docker-php-ext-enable redis
RUN echo "opcache.enable=1" > /usr/local/etc/php/conf.d/custom.ini \
&& echo "opcache.jit=tracing" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "opcache.jit_buffer_size=256M" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "memory_limit=512M" > /usr/local/etc/php/conf.d/custom.ini \
&& echo "upload_max_filesize=64M" >> /usr/local/etc/php/conf.d/custom.ini \
&& echo "post_max_size=64M" >> /usr/local/etc/php/conf.d/custom.ini
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
WORKDIR /var/www/html
RUN mkdir -p /var/www/html/storage /var/www/html/bootstrap/cache
RUN chown -R unit:unit /var/www/html/storage bootstrap/cache && chmod -R 775 /var/www/html/storage
COPY . .
RUN chown -R unit:unit storage bootstrap/cache && chmod -R 775 storage bootstrap/cache
RUN composer install --prefer-dist --optimize-autoloader --no-interaction
COPY unit.json /docker-entrypoint.d/unit.json
EXPOSE 8000
CMD ["unitd", "--no-daemon"]- 在项目根目录创建一个
unit.json文件(小写),内容如下。
{
"listeners": {
"*:8000": {
"pass": "routes",
"forwarded": {
"protocol": "X-Forwarded-Proto",
"source": ["<Load balancer IP, Subnet etc.>"]
}
}
},
"routes": [
{
"match": {
"uri": "!/index.php"
},
"action": {
"share": "/var/www/html/public$uri",
"fallback": {
"pass": "applications/laravel"
}
}
}
],
"applications": {
"laravel": {
"type": "php",
"root": "/var/www/html/public/",
"script": "index.php"
}
}
}NOTE
当使用 docker-compose 进行部署时,可能会出现 混合内容错误,当一些资源通过 http:// 而不是 https:// 请求时。为避免这种情况,请找到您的负载均衡器/代理子网或 IP 地址,并将其添加到 unit.config 中,明确告诉 unit 将正确的标头转发给 Laravel。Laravel 也必须配置信任代理。更多信息点击这里。
"listeners": {
"*:8000": {
"pass": "routes",
"forwarded": {
"protocol": "X-Forwarded-Proto",
"source": ["<Load balancer IP, Subnet etc.>"]
}
}
},- 设置部署后命令为:
php artisan optimize:clear && php artisan config:clear && php artisan route:clear && php artisan view:clear && php artisan optimize