php artisan ( 루트 사용자 포함)을 사용하여 실행하는 스크립트가 있으며 때로는 apache www-data 사용자가 수행 하기 전에 일일 로그 파일이 생성 됩니다. 즉, 실제 사용자가 내 웹 응용 프로그램을 사용할 때 폴더 권한 오류 :
스트림을 열지 못했습니다. 권한이 거부되었습니다.
매번 권한을 www-data로 다시 변경 하지만 항상 올바른 권한으로 로그 파일을 생성하여이 문제를 해결하고 싶습니다.
파일을 생성하거나 매일 올바른 권한이 있는지 확인하기 위해 파일을 만지는 크론 작업을 만드는 것을 고려했지만 다른 스크립트에 의존하지 않는 더 나은 솔루션을 찾고 있습니다.
우리는 또한 php artisan을 다른 스크립트에 래핑하여 항상 www-data 자격 증명으로 실행되도록 하는 것을 고려했지만 우리가 원하는 것은 실제로 아파치가 허용해서는 안되는 루트 프로 시저입니다.
더 많은 제안이 있습니까?
답변
일정한 것부터 시작합시다.
에 php artisan
의해 실행되는 명령이 있습니다 root
.
이 명령이 매일 실행된다고 가정하는 것이 안전합니다.
솔루션 No 1 :
파일을 생성하는 사용자가 기본적으로 쓰기 권한이있는 사용자이므로 다음과 같이 사용자별로 로그를 분리 할 수 있습니다.
App/start/global.php
/*
|--------------------------------------------------------------------------
| Application Error Logger
|--------------------------------------------------------------------------
|
| Here we will configure the error logger setup for the application which
| is built on top of the wonderful Monolog library. By default we will
| build a basic log file setup which creates a single file for logs.
|
*/
Log::useDailyFiles(storage_path().'/logs/laravel-'.get_current_user().'.log');
귀하의 경우 www가 데이터 사용자가 오류 로그를 생성했다, 그것의 결과 다음과 같습니다 storage/logs/laravel-www-data-2015-4-27.log
.
귀하의 경우 루트 사용자가 오류 로그를 생성했다, 그것의 결과 다음과 같습니다 storage/logs/laravel-root-2015-4-27.log
.
해결 방법 2 :
PHP 스크립트에서 artisan 명령이 사용하는 로그를 변경하십시오.
당신의에서 run()
기능, 시작에이 줄을 추가합니다 :
Log::useFiles(storage_path().'/logs/laravel-'.__CLASS__.'-'.Carbon::now()->format('Y-m-d').'.log');
클래스 이름이 ArtisanRunner
인 경우 로그 파일은 다음과 같습니다.
storage/logs/laravel-ArtisanRunner-2015-4-27.log
.
결론 : 솔루션 번호 1은 사용자별로 로그를 설명하므로 오류가 발생하지 않기 때문에 더 좋습니다.
편집 : jason이 지적한대로 get_current_user()
스크립트의 소유자 이름을 반환합니다. 따라서 1 번 솔루션을 적용 chown
하려면 필요한 사용자 이름에 장인 클래스 파일을 입력해야합니다.
답변
Laravel 버전 5.6.10 이상 은 및 드라이버에 대한 permission
구성 ( config/logging.php
) 의 요소를 지원합니다 .single
daily
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 7,
'permission' => 0664,
],
부트 스트랩 스크립트에서 Monolog로 저글링 할 필요가 없습니다.
특히 https://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8에 지원이 추가되었습니다 .
답변
Laravel 5.1의 경우 bootstrap/app.php
( 문서 에서 언급했듯이) 하단에 다음을 사용합니다 .
/**
* Configure Monolog.
*/
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
$filename = storage_path('logs/laravel-'.php_sapi_name().'.log');
$handler = new Monolog\Handler\RotatingFileHandler($filename);
$monolog->pushHandler($handler);
});
물론 대신 사용할 수있는 다른 핸들러가 많이 있습니다.
답변
이러한 목적을 위해 파일 및 디렉토리에 고급 ACL을 사용해야합니다. setfacl
여기에 당신의 대답이 될 것입니다. www-data 사용자 에게 특정 디렉토리 의 루트 파일에 쓸 수있는 권한을 부여하려면 다음과 같이 할 수 있습니다.
setfacl -d -m default:www-data:you-chosen-group:rwx /my/folder
이것을 발행 한 후에는 누가 생성했는지에 관계없이 모든 파일에 rwx
대해 www-data 사용자에 대한 권한을 설정 /my/folder/
합니다. 을 참조하시기 바랍니다 이 와 이 질문에 참조 할 수 있습니다. 또한 문서에서setfacl
.
이것이 도움이되는지 알려주세요.
답변
나는 이것이 매우 간단한 방법으로 작동했습니다.
Laravel 5.6 에서 같은 문제가 발생했습니다.
에서 config/logging.php
그냥 매일 채널의 경로 값을 업데이트php_sapi_name()
했습니다.
이렇게하면 다른 php_sapi_name에 대해 별도의 내구성이 생성되고 타임 스탬프가있는 로그 파일이 해당 디렉토리에 저장됩니다.
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/' . php_sapi_name() . '/laravel.log'),
'level' => 'debug',
'days' => 7,
]
그래서 저는
- 로그 파일은 다음
fpm-fcgi
디렉토리 에 생성됩니다 . 웹 사이트의 로그,owner: www-data
- 로그 파일은
cli
artisan 명령 (cronjob)에서 디렉토리 아래에 생성됩니다 .owner: root
Laravel 5.6 로깅에 대한 추가 정보 : https://laravel.com/docs/5.6/logging
내 config/logging.php
파일 은 다음과 같습니다 .
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/' . php_sapi_name() . '/laravel.log'),
'level' => 'debug',
'days' => 7,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'level' => 'critical',
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];
답변
나 에게이 문제는 로그 권한 이상이었습니다 … 한 사용자가 파일 / 폴더를 만들고 다른 사용자가 표준으로 인해 편집 / 삭제할 수없는 부트 스트랩 / 캐시 및 저장소 폴더와 관련된 문제가있었습니다. 644 및 755 권한.
일반적인 시나리오는 다음과 같습니다.
-
apache 사용자가 생성하지만 composer 설치 명령을 수행 할 때 composer 사용자가 편집 할 수없는 bootstrap / cache / compiled.php 파일
-
composer 사용자를 사용하여 지울 수없는 캐시를 생성하는 Apache 사용자
- 위에서 설명한 두려운 로그 경쟁 조건.
꿈은 어떤 사용자가 파일 / 폴더를 생성하든 관계없이 액세스해야하는 다른 사용자가 원래 작성자와 동일한 권한을 갖는 것입니다.
TL; DR?
방법은 다음과 같습니다.
laravel이라는 공유 사용자 그룹을 만들어야합니다.이 그룹은 스토리지 및 부트 스트랩 / 캐시 디렉토리에 액세스해야하는 모든 사용자로 구성됩니다. 다음으로 새로 생성 된 파일과 폴더에 각각 laravel 그룹과 664 및 775 권한이 있는지 확인해야합니다.
기존 파일 / 디렉터리에 대해이 작업을 수행하는 것은 쉽지만 기본 파일 / 폴더 생성 규칙을 조정하려면 약간의 마법이 필요합니다.
## create user group
sudo groupadd laravel
## add composer user to group
sudo gpasswd -a composer-user laravel
## add web server to group
sudo gpasswd -a apache laravel
## jump to laravel path
sudo cd /path/to/your/beautiful/laravel-application
## optional: temporary disable any daemons that may read/write files/folders
## For example Apache & Queues
## optional: if you've been playing around with permissions
## consider resetting all files and directories to the default
sudo find ./ -type d -exec chmod 755 {} \;
sudo find ./ -type f -exec chmod 644 {} \;
## give users part of the laravel group the standard RW and RWX
## permissions for the existing files and folders respectively
sudo chown -R :laravel ./storage
sudo chown -R :laravel ./bootstrap/cache
sudo find ./storage -type d -exec chmod 775 {} \;
sudo find ./bootstrap/cache -type d -exec chmod 775 {} \;
sudo find ./storage -type f -exec chmod 664 {} \;
sudo find ./bootstrap/cache -type f -exec chmod 664 {} \;
## give the newly created files/directories the group of the parent directory
## e.g. the laravel group
sudo find ./bootstrap/cache -type d -exec chmod g+s {} \;
sudo find ./storage -type d -exec chmod g+s {} \;
## let newly created files/directories inherit the default owner
## permissions up to maximum permission of rwx e.g. new files get 664,
## folders get 775
sudo setfacl -R -d -m g::rwx ./storage
sudo setfacl -R -d -m g::rwx ./bootstrap/cache
## Reboot so group file permissions refresh (required on Debian and Centos)
sudo shutdown now -r
## optional: enable any daemons we disabled like Apache & Queues
순전히 디버깅 목적으로 로그 아웃을 cli / web + 사용자로 분할하는 것이 유익하다는 것을 알았으므로 Sam Wilson의 답변을 약간 수정했습니다. 내 사용 사례는 대기열이 자체 사용자로 실행되었으므로 cli (예 : 단위 테스트)를 사용하는 작곡가 사용자와 대기열 데몬을 구별하는 데 도움이되었습니다.
$app->configureMonologUsing(function(MonologLogger $monolog) {
$processUser = posix_getpwuid(posix_geteuid());
$processName= $processUser['name'];
$filename = storage_path('logs/laravel-'.php_sapi_name().'-'.$processName.'.log');
$handler = new MonologHandlerRotatingFileHandler($filename);
$monolog->pushHandler($handler);
});
답변
라 라벨 5.1
우리의 경우 deploy
그룹의 모든 항목 이 읽기 / 쓰기 권한을 갖도록 모든 로그 파일을 만들고 싶었습니다 . 따라서 우리는 0664
권한이있는 모든 새 파일을 만들어야 했습니다.0644
기본값이 .
또한 가독성을 높이기 위해 줄 바꿈을 추가하는 포맷터를 추가했습니다.
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
$filename = storage_path('/logs/laravel.log');
$handler = new Monolog\Handler\RotatingFileHandler($filename, 0, \Monolog\Logger::DEBUG, true, 0664);
$handler->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true));
$monolog->pushHandler($handler);
});
또한 이것을 받아 들인 대답과 결합하는 것이 가능합니다.
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
$filename = storage_path('/logs/laravel-' . php_sapi_name() . '.log');
$handler = new Monolog\Handler\RotatingFileHandler($filename, 0, \Monolog\Logger::DEBUG, true, 0664);
$handler->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true));
$monolog->pushHandler($handler);
});