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?
cron
zadanie dotouch
nowego pliku dziennika codziennie o północy (oczywiście pod odpowiednim użytkownikiem).php artisan
jako użytkownik, dla którego chcesz utworzyć plik dziennika.sudo crontab -u www-data -e
Odpowiedzi:
Zacznijmy od tego, co jest stałe.
Masz
php artisan
polecenie, 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
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: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,chown
pliki klas rzemieślników pod wymaganą nazwą użytkownika.źródło
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.Laravel wersja 5.6.10 i ma później poparcie dla
permission
elementu konfiguracji (config/logging.php
) dosingle
i zdaily
kierowcą:Nie ma potrzeby żonglowania Monologiem w skrypcie bootstrap.
W szczególności dodano wsparcie w https://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8 .
źródło
'permission' => 0664
działa dla mnie (bez cudzysłowów)W przypadku Laravel 5.1 używam następującego u dołu strony
bootstrap/app.php
(jak wspomniano w dokumentach ):Oczywiście istnieje wiele innych programów obsługi, których możesz użyć zamiast tego.
źródło
Do takich celów należy używać zaawansowanych list ACL do plików i katalogów.
setfacl
był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:Po wydaniu tego ustawiasz uprawnienia
rwx
dla 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.
źródło
setfacl -d -m g:www-data:rw /full/path/to/laravel/storage/logs
po którym następujephp artisan cache:clear
icomposer dump-autoload
.Miałem to w bardzo prosty sposób:
Napotkałem ten sam problem na Napotkałem Laravel 5.6
W
config/logging.php
I 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.
Więc dla mnie
fpm-fcgi
katalogu: Logs from website,owner: www-data
cli
katalogu: 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.php
plik:źródło
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.get_current_user
nie działa, alephp_sapi_name
zrobić pracę (chociaż wydaje się brzydsze)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
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 ...
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.
źródło
configureMonologUsing
kod jest nadal potrzebny po uruchomieniusetfacl
poleceń?Laravel 5.1
W naszym przypadku chcieliśmy utworzyć wszystkie pliki dziennika, aby wszystko w
deploy
grupie miało uprawnienia do odczytu / zapisu. Dlatego musieliśmy utworzyć wszystkie nowe pliki z0664
uprawnieniami, w przeciwieństwie do0644
domyślnych.Dodaliśmy również program formatujący, aby dodać nowe wiersze dla lepszej czytelności:
Możliwe jest również połączenie tego z zaakceptowaną odpowiedzią
źródło
Jednym ze sposobów, aby to zadziałało, jest wykonanie cronjob jako danych www.
np. /ubuntu/189189/how-to-run-crontab-as-userwww-data
źródło
Laravel 5.5
Dodaj ten kod do
bootstrap/app.php
:laravel-2018-01-27-cli-raph.log
ilaravel-2018-01-27-fpm-cgi-raph.log
który jest bardziej czytelny.Laravel 5.6
Musisz stworzyć klasę dla swojego loggera:
Następnie musisz zarejestrować go w
config/logging.php
:Takie samo zachowanie jak w przypadku wersji 5.5:
laravel-2018-01-27-cli-raph.log
ilaravel-2018-01-27-fpm-cgi-raph.log
który jest bardziej czytelny.źródło
Dodaj coś podobnego do następującego na początku
app/start/artisan.php
pliku (to jest w przypadku Laravel 4):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-data
i 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.php
pliku następujących elementów:Jeśli to zrobisz,
chmod
powyż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-x
a pliki jakorw-rw-r--
. Więc jeśliwww-data
dział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, czyliwww-data
.źródło
(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.
źródło
Laravel 5.4
\Log::getMonolog()->popHandler(); \Log::useDailyFiles(storage_path('/logs/laravel-').get_current_user().'.log');
dodaj do
boot
funkcji wAppServiceProvider
źródło
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:
Spowoduje to utworzenie nazwy dziennika, która powinna być unikalna dla każdej kombinacji, na przykład
laravel-cli-sfscs-2019-05-15.log
lub wlaravel-apache2handler-apache-2019-05-15.log
zależności od punktu dostępu.źródło
Możesz po prostu zmienić uprawnienia do pliku dziennika w poleceniu rzemieślnika:
gdzie get_current_user () zwróci użytkownika bieżącego skryptu.
Innymi słowy,
daily.log
zawsze będzie miałwww-data
swojego właściciela, nawet jeśli zainicjujesz skrypt jakoroot
użytkownik.źródło
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
root
uprawnieniami na serwerze:2. Skonfiguruj następujący punkt zaczepienia rozmieszczenia na envoyer w sekcji „Aktywuj nowe wydanie”> „Przed tą akcją
3. Ponownie wdróż aplikację
Teraz przeprowadź ponowne wdrożenie aplikacji i powinno działać dalej.
źródło
źródło
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.
źródło
To rozwiązanie z pewnością będzie działać na Laravel V5.1 - V6.x
Przyczyny tego błędu:
.env
nie znaleziono pliku w katalogu głównymNaprawić:
touch .env
i wklej zmienne środowiskowe, a następnie uruchomźródło