Dziennik Laravel został utworzony z niewłaściwymi uprawnieniami

112

Mam skrypt, który uruchamiam za pomocą php artisan (z użytkownikiem root ) i czasami powoduje on utworzenie dziennego pliku dziennika, zanim zrobi to użytkownik apache www-data - co oznacza, że ​​gdy prawdziwy użytkownik korzysta z mojej aplikacji internetowej, otrzymuję błąd uprawnień do folderu:

Nie udało się otworzyć strumienia: odmowa uprawnień

Za każdym razem zmieniam uprawnienia z powrotem na dane www, ale chcę rozwiązać ten problem, aby plik dziennika był zawsze tworzony z odpowiednimi uprawnieniami.

Rozważałem utworzenie zadania cron, które tworzy plik lub dotyka go, aby codziennie mieć pewność, że ma odpowiednie uprawnienia, ale szukam lepszego rozwiązania, które nie będzie polegać na innym skrypcie.

Rozważaliśmy również zawinięcie rzemieślnika php w innym skrypcie, aby upewnić się, że zawsze jest uruchamiany z poświadczeniami danych www , ale niektóre rzeczy, które chcemy zrobić, to w rzeczywistości root procedury, które powinny być apache nie wolno robić.

Masz więcej sugestii?

NiRR
źródło
Skonfiguruj cronzadanie do touchnowego pliku dziennika codziennie o północy (oczywiście pod odpowiednim użytkownikiem).
Ben Harold
@BenHarold Dzięki, rozważaliśmy to, ale wolałbym nie angażować więcej skryptów.
NiRR
2
W takim przypadku musisz działać php artisanjako użytkownik, dla którego chcesz utworzyć plik dziennika.
Ben Harold
@BenHarold Jeszcze raz dziękuję, również to rozważaliśmy, co jest prawdopodobnie najlepszym rozwiązaniem, ale zaktualizowałem pytanie, aby wyjaśnić, dlaczego to również nie jest idealne.
NiRR
2
To, co zadziałało, to wykonanie crona jako użytkownika danych www zsudo crontab -u www-data -e
Nil Llisterri

Odpowiedzi:

67

Zacznijmy od tego, co jest stałe.

Masz php artisanpolecenie, biegnijroot .

Można bezpiecznie założyć, że to polecenie jest wykonywane codziennie.

Rozwiązanie nr 1:

Biorąc pod uwagę, że użytkownik, który tworzy pliki, jest tym, który ma uprawnienia do zapisu w nich domyślnie, możemy oddzielić logi według użytkownika jako takiego:

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');

Gdyby użytkownik danych www utworzył dziennik błędów, skutkowałoby to:storage/logs/laravel-www-data-2015-4-27.log .

Gdyby użytkownik root utworzył dziennik błędów, skutkowałoby to:storage/logs/laravel-root-2015-4-27.log .

Rozwiązanie nr 2:

Zmień dziennik używany przez polecenie rzemieślnika w skrypcie php.

W swojej run()funkcji dodaj tę linię na początku:

Log::useFiles(storage_path().'/logs/laravel-'.__CLASS__.'-'.Carbon::now()->format('Y-m-d').'.log');

Jeśli nazwa Twojej klasy to ArtisanRunner, plik dziennika będzie wyglądał następująco:

storage/logs/laravel-ArtisanRunner-2015-4-27.log.

Wniosek: Rozwiązanie numer 1 jest lepsze, biorąc pod uwagę, że określa ono twoje dzienniki według użytkownika, a zatem nie wystąpią żadne błędy.

EDYCJA: Jak wskazał jason, get_current_user()zwraca nazwę właściciela skryptu. W związku z tym, aby zastosować rozwiązanie nr 1, chownpliki klas rzemieślników pod wymaganą nazwą użytkownika.

Mysteryos
źródło
12
Zwróć uwagę, że get_current_user()zwraca właściciela bieżącego skryptu PHP (według php.net), a nie użytkownika, który aktualnie uruchamia skrypt. php_sapi_name()Zamiast tego używam , co podaje nazwę programu obsługi php (na przykład apache lub cli), który będzie zwykle uruchamiany jako różni użytkownicy.
Jason
1
Czy mogę zasugerować użycie zarówno nazwy użytkownika wykonującego skrypt, jak i nazwy php_sapi_name w połączeniu, ponieważ wielu użytkowników może wykonać Laravel z CLI, np. Kilku DBA uzyskuje dostęp do twojego serwera lub możesz chcieć, aby Laravel CRON działał jako apache. pobierz nazwę procesu wykonującego ten skrypt za pomocą posix_getpwuid (posix_geteuid ()) ['nazwa']; Zobacz mój pełny post poniżej.
Andrew
To musi zostać zaktualizowane dla najnowszych wersji Laravel: v5 +
Andrew
107

Laravel wersja 5.6.10 i ma później poparcie dla permissionelementu konfiguracji ( config/logging.php) do singlei z dailykierowcą:

    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
        'days' => 7,
        'permission' => 0664,
    ],

Nie ma potrzeby żonglowania Monologiem w skrypcie bootstrap.

W szczególności dodano wsparcie w https://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8 .

crishoj
źródło
9
to powinno być w oficjalnym dokumencie!
odupont
3
w tej odpowiedzi brakuje apostrofów. Powinno to być „pozwolenie” => „0664”. Zatem ta odpowiedź jest w porządku!
Phil,
2
@Phil Nope - to jest tylko opakowanie dla modułu obsługi strumienia Monologs, które akceptuje int dla uprawnień. Monolog otacza php.net/manual/en/function.chmod.php - zauważ, że początkowe 0 jest wymagane, aby upewnić się, że jest to wartość ósemkowa
Chris
7
'permission' => 0664działa dla mnie (bez cudzysłowów)
Syclone
2
@Friedrich, jeśli tworzony jest plik dziennika z `` rootem '' jako właścicielem pliku, prawdopodobnie oznacza to, że masz większe problemy z konfiguracją serwera internetowego
kjones
62

W przypadku Laravel 5.1 używam następującego u dołu strony bootstrap/app.php(jak wspomniano w dokumentach ):

/**
 * 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);
});

Oczywiście istnieje wiele innych programów obsługi, których możesz użyć zamiast tego.

Sam Wilson
źródło
1
Naprawdę podoba mi się ta odpowiedź, ponieważ 1) została zaktualizowana do wersji 5.1 i 2) używa metody w dokumentacji, aby rozszerzyć zachowanie dziennika.
Dylan Pierce
Doskonale, dodatkowy błysk do przodu nie jest potrzebny, ale nadal działa. Powinien brzmieć ... $ filename = storage_path ('logs / laravel -'. Php_sapi_name (). '. Log');
Andrew
Czy mogę zasugerować użycie zarówno nazwy użytkownika wykonującego skrypt, jak i nazwy php_sapi_name w połączeniu, ponieważ wielu użytkowników może wykonać Laravel z CLI, np. Kilku DBA uzyskuje dostęp do twojego serwera lub możesz chcieć, aby Laravel CRON działał jako apache. pobierz nazwę procesu wykonującego ten skrypt za pomocą posix_getpwuid (posix_geteuid ()) ['nazwa']; Zobacz mój pełny post poniżej.
Andrew
1
Jak go używać w Laravel 5.6? Ponieważ Laravel 5.6 ma zupełnie nowy system logowania.
Hamed Kamrava
26

Do takich celów należy używać zaawansowanych list ACL do plików i katalogów. setfaclbyłaby tu twoja odpowiedź. Jeśli chcesz nadać użytkownikowi www-data uprawnienia do zapisywania plików roota w określonym katalogu, możesz to zrobić w następujący sposób:

setfacl -d -m default:www-data:you-chosen-group:rwx /my/folder

Po wydaniu tego ustawiasz uprawnienia rwxdla użytkownika danych www do wszystkich plików, /my/folder/bez względu na to, kto je utworzył. Zobacz to i to pytanie w celach informacyjnych. Możesz również sprawdzić dokumentysetfacl .

Daj mi znać, jeśli to pomoże.

Paweł Tomkiel
źródło
3
Działało dla mnie następujące polecenie: setfacl -d -m g:www-data:rw /full/path/to/laravel/storage/logspo którym następuje php artisan cache:cleari composer dump-autoload.
Sawny
17

Miałem to w bardzo prosty sposób:

Napotkałem ten sam problem na Napotkałem Laravel 5.6

W config/logging.phpI właśnie aktualizowany codziennie zmieniające wartość ścieżki kanału zphp_sapi_name() w nim.

Tworzy to oddzielny katalog dla różnych php_sapi_name i umieszcza plik dziennika z sygnaturą czasową w ich katalogu perticular.

'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/' . php_sapi_name() . '/laravel.log'),
            'level' => 'debug',
            'days' => 7,
        ]

Więc dla mnie

  • Pliki dziennika są tworzone w ramach fpm-fcgi katalogu: Logs from website,owner: www-data
  • Pliki dziennika są tworzone w clikatalogu: z polecenia artisan (cronjob).owner: root

Więcej informacji na temat logowania Laravel 5.6: https://laravel.com/docs/5.6/logging

Oto mój config/logging.phpplik:

<?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',
        ],
    ],
];
Lahar Shah
źródło
ładne ... Twoje rozwiązanie jest czystsze ...
testuję
1
Jak wskazano w innym komentarzu, dzienniki to tylko część historii. Istnieją skompilowane widoki, pamięci podręczne danych, wstępnie buforowany kod źródłowy, z których każdy może zostać utworzony jako pliki lokalne przez użytkownika WWW lub CLI.
Jason
2
To nie zadziała, jeśli buforujesz konfigurację za pomocą artisan config:cache, ponieważ utworzy pamięć podręczną konfiguracji przy użyciu cli SAPI, który będzie używany zarówno dla żądań CLI, jak i WWW.
leeb
1
Działa to dla mnie, próbował get_current_usernie działa, ale php_sapi_namezrobić pracę (chociaż wydaje się brzydsze)
Richard Fu
Myślę, że to najszybszy i najlepszy sposób. Modyfikowanie konfiguracji nie modyfikuje podstawowej struktury Laravela, tylko konfigurację.
William Prigol Lopes
12

Dla mnie ten problem był czymś więcej niż uprawnieniami do dziennika ... Miałem problemy z czymkolwiek związanym z folderami bootstrap / cache i folderami przechowywania, w których jeden użytkownik utworzyłby plik / folder, a drugi nie mógł edytować / usuwać ze względu na standard Uprawnienia 644 i 755.

Typowe scenariusze to:

  • Plik bootstrap / cache / compiled.php tworzony przez użytkownika Apache, ale nieedytowalny przez użytkownika composer podczas wykonywania polecenia instalacji composer

  • Użytkownik apache tworzący pamięć podręczną, której nie można wyczyścić za pomocą użytkownika kompozytora

  • Opisane powyżej przerażające warunki wyścigu dziennika.

Marzeniem jest to, że bez względu na to, który użytkownik utworzy plik / folder, pozostali użytkownicy, którzy potrzebują dostępu, mają dokładnie takie same uprawnienia jak oryginalny autor.

TL; DR?

Oto jak to się robi.

Musimy utworzyć współdzieloną grupę użytkowników o nazwie laravel, która składa się z wszystkich użytkowników, którzy potrzebują dostępu do katalogów przechowywania i bootstrap / cache. Następnie musimy upewnić się, że nowo utworzone pliki i foldery mają odpowiednio uprawnienia grupy laravel i 664 i 775.

Można to łatwo zrobić dla istniejących plików / katalogów, ale potrzebna jest odrobina magii, aby dostosować domyślne zasady tworzenia plików / folderów ...

## 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

Wyłącznie do celów debugowania stwierdziłem, że podzielenie logów na obu użytkowników cli / web + było korzystne, więc nieznacznie zmodyfikowałem odpowiedź Sama Wilsona. Moim przypadkiem użycia była kolejka uruchomiona przez własnego użytkownika, więc pomogła w odróżnieniu użytkownika kompozytora używającego CLI (np. Testy jednostkowe) od demona kolejki.

$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);
}); 
Andrzej
źródło
To jest bardzo dobre. Czy Twój configureMonologUsingkod jest nadal potrzebny po uruchomieniu setfaclpoleceń?
jeff-h
7

Laravel 5.1

W naszym przypadku chcieliśmy utworzyć wszystkie pliki dziennika, aby wszystko w deploygrupie miało uprawnienia do odczytu / zapisu. Dlatego musieliśmy utworzyć wszystkie nowe pliki z 0664uprawnieniami, w przeciwieństwie do0644 domyślnych.

Dodaliśmy również program formatujący, aby dodać nowe wiersze dla lepszej czytelności:

$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);
});

Możliwe jest również połączenie tego z zaakceptowaną odpowiedzią

$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);
});
Artur Käpp
źródło
5

Laravel 5.5

Dodaj ten kod do bootstrap/app.php:

$app->configureMonologUsing(function (Monolog\Logger $monolog) {
    $filename = storage_path('logs/' . php_sapi_name() . '-' . posix_getpwuid(posix_geteuid())['name'] . '.log');
    $monolog->pushHandler($handler = new Monolog\Handler\RotatingFileHandler($filename, 30));
    $handler->setFilenameFormat('laravel-{date}-{filename}', 'Y-m-d');
    $formatter = new \Monolog\Formatter\LineFormatter(null, null, true, true);
    $formatter->includeStacktraces();
    $handler->setFormatter($formatter);
});
  • Będzie przechowywać takie pliki: laravel-2018-01-27-cli-raph.logi laravel-2018-01-27-fpm-cgi-raph.logktóry jest bardziej czytelny.
  • Nowe linie są zachowywane (jako domyślne zachowanie Laravel)
  • Działa z Laravel Log Viewer

Laravel 5.6

Musisz stworzyć klasę dla swojego loggera:

<?php

namespace App;

use Monolog\Logger as MonologLogger;

class Logger {
    public function __invoke(array $config)
    {
        $monolog = new MonologLogger('my-logger');
        $filename = storage_path('logs/' . php_sapi_name() . '-' . posix_getpwuid(posix_geteuid())['name'] . '.log');
        $monolog->pushHandler($handler = new \Monolog\Handler\RotatingFileHandler($filename, 30));
        $handler->setFilenameFormat('laravel-{date}-{filename}', 'Y-m-d');
        $formatter = new \Monolog\Formatter\LineFormatter(null, null, true, true);
        $formatter->includeStacktraces();
        $handler->setFormatter($formatter);
        return $monolog;
    }
}

Następnie musisz zarejestrować go w config/logging.php:

'channels' => [
    'custom' => [
        'driver' => 'custom',
        'via' => App\Logging\CreateCustomLogger::class,
    ],
],

Takie samo zachowanie jak w przypadku wersji 5.5:

  • Będzie przechowywać takie pliki: laravel-2018-01-27-cli-raph.logi laravel-2018-01-27-fpm-cgi-raph.logktóry jest bardziej czytelny.
  • Nowe linie są zachowywane (jako domyślne zachowanie Laravel)
  • Działa z Laravel Log Viewer
rap-2-godz
źródło
Najlepsza odpowiedź! Kudos
Shahid Karimi
4

Dodaj coś podobnego do następującego na początku app/start/artisan.phppliku (to jest w przypadku Laravel 4):

// If effectively root, touch the log file and make sure it belongs to www-data
if (posix_geteuid() === 0) {
    $file = storage_path() . '/logs/laravel.log';
    touch($file);
    chown($file, 'www-data');
    chgrp($file, 'www-data');
    chmod($file, 0664);
}

Dostosuj ścieżkę, jeśli wspomniany plik dziennika dziennego nie jest standardowym plikiem dziennika Laravel. Możesz także nie chcieć zmieniać grupy lub ustawiać uprawnień, tak jak ja tutaj robię. Powyższe ustawia grupę na www-datai ustawia uprawnienia do zapisu dla grupy. Następnie dodałem mojego zwykłego użytkownika dowww-data grupy, aby uruchamianie poleceń rzemieślnika jako mój zwykły użytkownik nadal mógł zapisywać w dzienniku.

Powiązaną poprawką jest umieszczenie na początku app/start/global.phppliku następujących elementów:

umask(0002);

Jeśli to zrobisz, chmodpowyższa kwestia stanie się dyskusyjna. Po ustawieniu umask na tę wartość, wszelkie nowe pliki tworzone przez PHP (i tym samym Laravel) będą miały tylko maskowane uprawnienia, aby „inni” użytkownicy nie mieli uprawnień do zapisu. Oznacza to, że katalogi będą się rozpoczynać jako, rwxrwxr-xa pliki jako rw-rw-r--. Więc jeśli www-datadziała PHP, każda pamięć podręczna i pliki dziennika, które tworzy, będą domyślnie zapisywalne przez każdego z głównej grupy tego użytkownika, czyli www-data.

drżenie
źródło
4

(Laravel 5.6) Niedawno napotkałem ten sam problem i po prostu ustawiłem zaplanowane polecenie do uruchomienia /app/Console/Kernel.php.

$schedule->exec('chown -R www-data:www-data /var/www/**********/storage/logs')->everyMinute();

Wiem, że to trochę przesada, ale działa jak urok i od tego czasu nie miałem żadnych problemów.

Ague Mort
źródło
To działa ? Tak, ale czy jest to najlepsza praktyka? Myślę, że nie.
Pablo Papalardo
3

Laravel 5.4

\Log::getMonolog()->popHandler(); \Log::useDailyFiles(storage_path('/logs/laravel-').get_current_user().'.log');

dodaj do bootfunkcji wAppServiceProvider

StupidDev
źródło
1

Laravel 5.8

Laravel 5.8 pozwala ustawić nazwę logowania config/logging.php.

Tak więc, korzystając z poprzednich odpowiedzi i komentarzy, jeśli chcesz nadać swojemu dziennikowi nazwę, używając zarówno rzeczywistej nazwy użytkownika posix ORAZ php_sapi_name()wartości, wystarczy zmienić nazwę dziennika. Korzystanie z dziennego sterownika umożliwia rotację dzienników, która działa na kombinację użytkownika / interfejsu API, co zapewnia, że ​​dziennik jest zawsze obracany przez konto, które może modyfikować dzienniki.

Dodałem również sprawdzenie funkcji Posix, które mogą nie istnieć w twoim lokalnym środowisku, w którym to przypadku nazwa dziennika jest po prostu domyślną nazwą standardową.

Zakładając, że używasz domyślnego kanału dziennika „codziennie”, możesz zmodyfikować klucz „kanały” w następujący sposób:

# config/logging.php
'channels' => [
    ...
    'daily' => [
        'driver' => 'daily',
        'path'   => storage_path(
            function_exists('posix_getpwuid') 
            && function_exists('posix_geteuid')
                ? 'logs/laravel'
                    . '-' . php_sapi_name()
                    . '-' . posix_getpwuid(posix_geteuid())['name'] 
                    . '.log'
                : 'logs/laravel.log'),
        'level'  => 'debug',
        'days'   => 15,
    ],
    ...

Spowoduje to utworzenie nazwy dziennika, która powinna być unikalna dla każdej kombinacji, na przykład laravel-cli-sfscs-2019-05-15.loglub w laravel-apache2handler-apache-2019-05-15.logzależności od punktu dostępu.

sfscs
źródło
0

Możesz po prostu zmienić uprawnienia do pliku dziennika w poleceniu rzemieślnika:

$path = storage_path('log/daily.log');
chown($path, get_current_user());

gdzie get_current_user () zwróci użytkownika bieżącego skryptu.

Innymi słowy, daily.logzawsze będzie miał www-dataswojego właściciela, nawet jeśli zainicjujesz skrypt jako rootużytkownik.

Adam
źródło
0

Jeśli używasz Laravel Envoyer , oto możliwa poprawka przy użyciu ACL w systemie Linux:

1. Najpierw uruchom następujący skrypt z rootuprawnieniami na serwerze:

W obu skryptach musisz zamienić zmienne zgodnie z instrukcją poniżej:

  • {{GŁÓWNA_ŚCIEŻKA}} : Ścieżka do katalogu wirtualnych hostów (np. Folder> zawierający aplikacje).
  • {{WEB_SERVER_USER}} : użytkownik, z którego korzysta Twój serwer internetowy.
  • {{DEPLOYMENT_USER}} : użytkownik, przez którego uruchamiany jest skrypt wdrażania.
#!/bin/bash

DIRS="storage current/bootstrap/cache"
MASTER_PATH={{MASTER_PATH}}

if [ -d $MASTER_PATH ]; then 
    cd $MASTER_PATH
    for p in `ls $MASTER_PATH`; do 
        if [ -d $MASTER_PATH/$p ]; then     
        cd $MASTER_PATH/$p
            echo "Project: $p -> $MASTER_PATH/$p"
            for i in $DIRS; do 
                echo "- directory: $i" 
                if [ -d $i ]; then 
                    echo "-- checking ACL..."
                    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
                    if [  $HAS_ACL -eq 0 ]; then 
                        echo "--- applying $i"
                        setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
                        setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
                    else
                        echo "--- skipping $i"
                    fi
                fi
            done
        echo "--------------"
        fi
    done
else
    echo "No $MASTER_PATH - skipping overall"
fi

2. Skonfiguruj następujący punkt zaczepienia rozmieszczenia na envoyer w sekcji „Aktywuj nowe wydanie”> „Przed tą akcją

PROJECT_DIRS="storage"
RELEASE_DIRS="bootstrap/cache"
 
cd {{ project }}
 
for i in $PROJECT_DIRS; do
  if [ -d $i ]; then
    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
    if [  $HAS_ACL -eq 0 ]; then
      echo "ACL set for directory {{project}}/$i"
      setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
      setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
    fi
  fi
done
 
cd {{ release }}
 
for i in $RELEASE_DIRS; do
  if [ -d $i ]; then
    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
    if [  $HAS_ACL -eq 0 ]; then
      echo "ACL set for directory {{project}}/$i"
      setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
      setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
    fi
  fi
done

3. Ponownie wdróż aplikację

Teraz przeprowadź ponowne wdrożenie aplikacji i powinno działać dalej.

Uwaga: Skrypt zdefiniowany w 1. powinien być uruchamiany za każdym razem, gdy dodajesz nowy projekt do maszyny.

Emil Pedersen
źródło
0
cd /path/to/project
chown -R www-data:root .
chmod -R g+s .
Eduardo
źródło
-1

Najlepszym sposobem, jaki znalazłem, jest to, że Fideloper sugeruje, http://fideloper.com/laravel-log-file-name , możesz ustawić konfigurację dziennika laravel bez dotykania klasy Log. Miej różne nazwy dla programów konsolowych i programów HTTP, myślę, że jest najlepszym rozwiązaniem.

Giacomo
źródło
-1

To rozwiązanie z pewnością będzie działać na Laravel V5.1 - V6.x

Przyczyny tego błędu:

  • Jest to głównie spowodowane problemami z pozwoleniami
  • Nie znaleziono zmiennych środowiskowych lub .env nie znaleziono pliku w katalogu głównym
  • Problem z rozszerzeniami PHP
  • Problem z bazą danych

Naprawić:

  • Ustaw odpowiednie uprawnienia:
    • Uruchom te polecenia (Ubuntu / Debian)
find /path/to/your/root/dir/ -type f -exec chmod 644 {} \;
find /path/to/your/root/dir/ -type d -exec chmod 755 {} \;

chown -R www-data:www-data /path/to/your/root/dir/

chgrp -R www-data storage bootstrap/cache
chmod -R ug+rwx storage bootstrap/cache
  • Jeśli plik .env nie istnieje, utwórz go touch .envi wklej zmienne środowiskowe, a następnie uruchom
   php artisan key:generate
   php artisan cache:clear
   php artisan config:clear
   composer dump-autoload
   php artisan migrate //only if not already migrated
Smit Patel
źródło