VirtualBox a zmiany małych plików

Pracując z VirtualBoxem, częstą bolączką jest aktualizacja małych plików we współdzielonym katalogu. Gdy system-gospodarz zaktualizuje mały plik (np. plik .js lub .css), działający w maszynie wirtualnej serwer nie wysyła zaktualizowanego pliku, a jedynie jego zdeformowaną wersję.

Niniejszym postem chciałbym rozpocząć serię kilku luźno ze sobą powiązanych wpisów na temat pracy z VirtualBoxem (nie używam Vagranta ani Dockera, prawdopodobnie z lenistwa: pracuje mi się dobrze z VirtualBoxem i nie chce mi się na razie na siłę nic poprawiać). A teraz przejdźmy do mięsa.

VirtualBox jest bardzo fajny, gdy nie chcemy instalować w systemie-gospodarzu dodatkowego oprogramowania. Ja w ten sposób ogarniam serwer Nginx z działającym za nim PHP, w innej maszynie działa sobie serwer MySQL, w jeszcze kolejnej MongoDB. Każda maszyna wykorzystuje w miarę niewielką pulę zasobów, oferuje jakieś oprogramowanie potrzebne w projekcie, nad którym aktualnie pracuję i mogę ją sobie włączać i wyłączać na życzenie.

Zaznaczmy także, bo to ważne dla poniżej opisywanej sytuacji, że cały development odbywa się w systemie-gospodarzu. System-gość korzysta z katalogu współdzielonego, serwując pliki, które na bieżącą są modyfikowane poza maszyną wirtualną.

Wszystko byłoby ładne i piękne, gdyby nie pewien szczegół.

Gdy w systemie-gospodarzu aktualizowany jest niewielki plik (pod pojęciem „niewielki” rozumiem tu rozmiar np. do 2kB), działający w maszynie wirtualnej serwer nie wysyła poprawnej nowej wersji tego pliku. Zamiast tego, wysyła wersję kompletnie bezużyteczną, w której gdzieś na końcu pliku znaleźć można blok krzaczków (prawdopodobnie są to puste znaki, wyświetlane przez różne edytory w dziwny sposób). W przypadku plików CSS mamy błędy w konsoli i nowe style nie są zastosowane. W przypadku pliku JS parser napotyka na błąd składni i w ogóle nie wykonuje kodu.

Jest to o tyle denerwujące, że dziergając kod, często używam jakiegoś watchera, który po każdej zmianie tworzy nową wersję plików wyjściowych, np. kompilując kod LESS do wyjściowego CSS. Skutkuje to ciągłym zastępowaniem poprzedniego pliku nowym, a więc i ciągłym wysyłaniem śmieci przez serwer w maszynie wirtualnej. Pierwszy raz natknąłem się na to podczas hackathonu, gdzie pierwszą godzinę musiałem poświęcić na szukanie rozwiązania takiego prozaicznego problemu zamiast na kodowanie.

Okazuje się, że jest jakiś problem z implementacją wirtualnego systemu plików, z którego korzysta VirtualBox. W używanej przeze mnie wersji VirtualBox (5.0.18) nie ma na razie rozwiązania na poziomie samego systemu plików (vboxsf), pomimo, że problem jest znany od dawna i był wielokrotnie zgłaszany przez rzesze użytkowników.

Na szczęście jest obejście na poziomie serwera. W przypadku Nginx należy wyedytować plik /etc/nginx/nginx.conf. W nim, w bloku http znaleźć można następującą dyrektywę:

sendfile on;

Wystarczy ją wyłączyć:

sendfile off;

Po zrestartowaniu serwera wszyzstko powinno działać normalnie.

Nie korzystam na co dzień z serwera Apache, ale podobno rozwiązanie jest niemal identyczne. Wyedytować należy plik apache.conf lub httpd.conf (chyba na różnych systemach jest jeden albo drugi, a przynajmniej tak wynika ze znalezionych przez mnie źródeł). Należy tam dodać lub zmodyfikować istniejącą dyrektywę EnableSendfile:

EnableSendfile off

Napisz komentarz


Szukaj wpisów


Chmura tagów