Marcin Lewandowski
Marcin Lewandowski
Programista PHP ( Symfony ), blogger, trener oraz miłośnik kawy. Na co dzień pracuję z Symfony, RabbitMQ, ElasticSearch, Node.js, Redis, Docker, MySQL.

Konfiguracja MacBook M1 dla web developera

Konfiguracja MacBook M1 dla web developera

Nowe MacBook-i z procesorem M1 są powiewem świeżości w ekosystemie Apple, ale także dużym krokiem na przód pod kątem wydajności procesorów. Kiedyś byliśmy przyzwyczajeni do prawa Moora, które mówiło, że moc obliczeniowa podwaja się co 24 miesiące. Jednak od dość dawna nie odczuwamy w żaden sposób wzrostu mocy obliczeniowej naszych komputerów. Aż do teraz, procesor M1 od Apple pokazał, że może być dużo wydajniej.

Jednak zastosowana architektura ARM w procesorach zmusza twórców oprogramowania do dostosowania swoich programów do nowej architektury. To potrwa jeszcze chwilę, więc można się zastanawiać czy Apple postradało zmysły wypuszczając procesory na które nie ma jeszcze wystarczającej ilości oprogramowania ??

Rosetta 2

Odpowiedź na postawione pytanie brzmi nie, nie postradało zmysłów. Przygotowało coś co nazwali Rosetta 2 i służy do uruchamiania aplikacji pisanych na procesory Intel-a. Oczywiście będzie strata wydajności w porównaniu do aplikacji natywnych, lecz przy większej wydajności procesora M1 i tak aplikacje uruchamiane za pomocą Rosetty będą działały szybciej niż ich natywne odpowiedniki. Zaś za kilka miesięcy większość aplikacji będzie natywnie działała na procesorach od Apple.

Niech za przykład posłuży firma JetBrains, która jest dostawcą jednego z lepszych IDE do pracy web developera. Już w tym momencie mamy natywne wsparcie procesorów M1. Jak widać da się dość szybko dostarczyć oprogramowanie natywnie wspierające architekturę ARM.

Przygotowanie środowiska

Skoro wiemy, że nie wszystko wspiera natywnie architekturę ARM to konieczna będzie instalacja Rosetty, najlepiej zrobić to z linii komend.

softwareupdate --install-rosetta --agree-to-license

Po zakończeniu instalacji chcielibyśmy móc wybrać czy instalujemy oprogramowanie z wykorzystaniem Rosetty, czy też oprogramowanie wspiera nową architekturę i możemy aplikację zainstalować standardowo.

W tym celu utworzymy specjalne polecenie arm, które będziemy wykorzystywali do instalacji oprogramowania przez Rosettę ;)

Tworzymy plik .zshrc w katalogu domowym naszego użytkownika.

nano ~/.zshrc

I w pliku umieszczamy poniższą zawartość.

arm() {
  arch -x86_64 $@
}

Restartujemy komputer. I od tego momentu możemy posługiwać się poleceniem arm.

Homebrew

Praktycznie każdy użytkownik MacBook-a zna menadżer pakietów Homebrew. Menadżer ten od wersji 2.6.0 zaczął wspierać natywnie procesory M1.

Today I’d like to announce Homebrew 2.6.0. The most significant changes since 2.5.0 are macOS Big Sur support on Intel, brew commands replacing all brew cask commands, the beginnings of macOS M1/Apple Silicon/ARM support and API deprecations.

Jednak sami twórcy, na ten moment zalecają instalację menadżera przez Rosettę 2.

We currently recommend running Homebrew using Intel emulation with Rosetta 2.

Więc instalujemy Homebrew z wykorzystaniem polecenia arm.

arm /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Po zakończeniu instalacji będziemy mogli używać naszego ulubionego menadżera pakietów. Jednak nadal będzie konieczne używanie polecenia arm przy instalowaniu nowego oprogramowania.

Nginx

Mając menadżer pakietów Homebrew na pokładzie możemy zainstalować Nginx-a oraz inne oprogramowanie. I jak widać poniżej instalujemy je poprzedzając polecenie instalacji brew install nginx naszym dodatkowym poleceniem arm.

arm brew install nginx

Po instalacji zmieniamy użytkownika i grupę na jakich ma pracować Nginx.

Edytujemy plik /usr/local/etc/nginx/nginx.conf i w pierwszej linii ustawiamy:

user <nazwa_użytkownika> staff;

Restartujemy nginx-a:

brew services restart nginx

I serwer WWW jest na pokładzie. Mi będzie on potrzebny do uruchomienia phpMyAdmin-a. Gdyż pozostałe projekty uruchamiam za pomocą aplikacji Symfony lub NodeJS.

PHP

Jako że programuję na codzień w PHP to będzie mi on potrzebny. I tak samo jak w przypadku Nginx-a instaluję go wykorzystując Homebrew.

arm brew install php

Restartujemy terminal i sprawdzamy jaką wersję PHP mamy.

php -v

Potrzebujemy jeszcze zmienić użytkownika na jakim będzie pracował FPM, co robimy w pliku /usr/local/etc/php/8.0/php-fpm.d/www.conf

user = <nazwa_użytkownika>
group = staff

Zamiast <nazwa_użytkownika> podajemy nazwę naszego użytkownika. Po wprowadzeniu i zapisaniu zmian uruchamiamy PHP.

brew services php start

MySQL / MariaDB

W zależności czy wolicie MySQL-a czy MariaDB to wykonujecie instalację odpowiedniego pakietu. Poniżej przykład instalacji MySQL-a.

arm brew install mysql
arm brew services start mysql

Po instalacji konieczna jest konfiguracja, którą wykonujemy uruchamiając polecenie:

mysql_secure_installation

Zostaniemy poproszeni o ustawienie hasła oraz podjęcie decyzji, czy możliwe jest logowanie zdalne dla root-a oraz parę innych mniej istotnych elementów. Po zakończeniu konfiguracji prawie jesteśmy gotowi do pracy.

phpMyAdmin

Programista to leniwy człowiek. Więc zamiast klepać polecenia SQL służące do przeglądania czy edycji rekordów wolę większość wyklikać. Dlatego instaluję zawsze phpMyAdmin-a.

Pobieramy phpMyAdmin-a ze strony https://www.phpmyadmin.net/downloads/ i rozpakowujemy w katalogu /usr/local/var/www/phpmyadmin. Teraz potrzebujemy móc jakoś wywołać phpmyadmin-a i do tego celu przyda nam się Nginx.

Tworzymy plik /usr/local/etc/nginx/servers/phpmyadmin o zawartości:

server {
    listen   80; 
 
    server_name  phpmyadmin;
     
    root       /usr/local/var/www/phpmyadmin/;
 
    index index.php index.html index.htm;
  
    access_log  /usr/local/etc/nginx/logs/phpmyadmin.access.log;
    error_log  /usr/local/etc/nginx/logs/phpmyadmin.error.log;
  
    location ~ \.php$ {
        try_files      $uri = 404;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
 
    error_page  404     /404.html;
    error_page  403     /403.html;
}

Dodatkowo konieczne będzie utworzenie katalogu na logi phpmyadmin-a w ścieżce, którą podaliśmy w pliku. W tym celu przechodzimy do katalog /usr/local/etc/nginx/

cd /usr/local/etc/nginx/

A następnie zakładamy katalog logs.

mkdir logs

Teraz możemy spokojnie zrestartować Nginx-a.

brew services restart nginx

Ostatnim krokiem będzie dodanie wpisu w pliku /etc/hosts

127.0.0.1   phpmyadmin

Od tego momentu po wpisaniu w przeglądarkę http://phpmyadmin powinniśmy zobaczyć ekran logowania.

Po podaniu loginu root i hasła, które ustawiliśmy podczas konfiguracji MySQL-a możemy już zarządzać naszymi bazami danych.

Symfony

Instalacja aplikacji dostarczanej przez twórców Symfony do uruchamiania aplikacji tworzonych z wykorzystaniem tego frameworka. Sprowadza się do wykonania poniższego polecenia.

curl -sS https://get.symfony.com/cli/installer | arm bash

Po zakończeniu instalacji otrzymamy informację The Symfony CLI v4.21.6 was installed successfully!. Numer wersji może się różnić, ale najważniejsze że instalacja zakończyła się sukcesem.

Teraz pozostaje nam tylko podjąć decyzję czy chcemy, żeby polecenie było dostępne globalnie, czy tylko dla nas. Lenistwo znów przemawia za instalacją globalną ;)

mv /Users/<nazwa_użytkownika>/.symfony/bin/symfony /usr/local/bin/symfony

Powyższe polecenie zostanie wam podpowiedziane po instalacji Symfony CLI.

Composer

W przypadku Composer-a instalacja niczym się nie różni od tej standardowej. Czyli przechodzimy na stronę https://getcomposer.org/download i przeklejamy poszczególne polecenia do terminala.

Mogą one wyglądać następująco:

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

I na koniec instalacja globalna 😉

mv composer.phar /usr/local/bin/composer

NodeJS

Do pełni szczęścia potrzebuję jeszcze NodeJS, w którym piszę mikroserwisy. I tutaj mamy do wyboru pobranie instalatora ze strony https://nodejs.org/en/download/ lub wykorzystać menadżer pakietów.

Lata temu pracowałem na linuksie i dalej mam z nim styczność więc kocham konsolę więc zapewne was to nie zdziwi, że posłużę się menadżerem pakietów.

arm brew install node

Po zakończeniu instalacji pozostaje sprawdzić jaka wersja node i npm zostały zainstalowane.

node -v

U mnie pojawiła się wersja v15.7.0.

npm -v

A NPM w wersji 7.4.3. Oczywiście u was te wersje mogą być już inne.

Docker ! ! !

I tu pojawia się chyba największy problem na ten moment. Docker aktualnie jest w wersji beta jeśli chodzi o wsparcie procesora od Apple. I o ile z instalacją nie powinno być problemu to już z samymi obrazami takie problemy mogą wystąpić.

W mojej codziennej pracy wykorzystuję trzy obrazy:

  • ElasticSearch,
  • RabbitMQ,
  • REDIS

I szczerze na ten moment nie chcę walczyć z Docker-em na MacBook-u Air M1, gdyż zwyczajnie szkoda mi czasu na walkę z wiatrakami. Mogę dużo lepiej wykorzystać ten czas niż kombinowanie jak uruchomić poszczególne kontenery tak, aby chciały działać.

Więc jeśli, na codzień pracujesz z wirtualizacją i jest Ci ona konieczna do pracy to, na razie odpuść sobie nowy procesor lub zrób to co ja, czyli kontenery stoją na zewnętrznej maszynie. W moim przypadku jest to maszyna do robienia backupów więc w większości przypadków stoi niewykorzystywana. Ale o tym jak można takie środowisko skonfigurować opowiem w osobnym wpisie ;)

Ostrzeżenie

Na własnej skórze się przekonałem jak bardzo należy zwracać uwagę na to co podłączamy do naszego MacBook-a. Otóż nowe MacBook-i posiadają bardzo małą ilość złączy, co jest ich bardzo dużą wadą. Mój poprzedni MacBook Pro z 2015 posiadał najlepszą ilość złączy na świecie.

Niestety obecny posiada tylko dwa wejścia co jest żenującą ilością i nie jestem w stanie zrozumieć tej decyzji inżynierów z Apple.

Więc jak sami rozumiecie, hub usb to konieczność w tym przypadku. A że do tej pory korzystałem z rozwiązań Green Cell to kupiłem u nich HUB USB-C Green Cell 7.

I wszystko by było w porządku gdyby nie to, że ten hub spowodował spalenie płyty głównej mojego MacBook-a :( Dopiero w serwisie dowiedziałem się, że z HUB-ami od Green Cell-a są problemy pomimo początkowej deklaracji producenta mówiącej o kompatybilności z każdym laptopem wyposażonym w USB-C.

Na szczęście producent zmienił opis. Od teraz HUB nie jest kompatybilny z najnowszymi komputerami z procesorem M1. Nie mniej uważam, że informacja te powinna być bardziej wyróżniona, gdyż nie każdy czyta dokładnie pełen opis produktu.

Zaznaczenie na żółto to moja robota nie producenta ;)

Oczywiście to nie jest tak, że tylko Green Cell ma problemy z kompatybilnością. Na forach można przeczytać o wielu przypadkach spalenia płyty głównej przez HUB-y innych producentów. Mi chłopaki z serwisu polecili HUB-a Adam z którym ponoć nie ma takich cyrków. I rzeczywiście do tej pory nie wystąpiły żadne problemy.

PS. Kaczki nie dodają do HUB-a ;)

Podsumowanie

Być może dla części z was cały ten proces wyda się skomplikowany i niepotrzebny. Przecież na linuksie wszystko to da się zrobić szybciej i bez kombinowania. A Windows to już w ogóle przy tym bajka, do wszystkiego jest instalator, klikasz parę razy “Next” i koniec roboty, działa.

Niestety nie zgodzę się z wami w stu procentach. Linux ma podobny poziom skomplikowania jeśli chodzi o instalację, a biorąc pod uwagę mnogość dystrybucji na których często te same rzeczy robi się inaczej to powiem wam, że szkoda mi na to życia.

Co do Windowsa to jedno słowo blue screen.

Nie wrócę do tego systemu i mam nadzieję, że nie będę musiał. Choć na nim też dość długo siedziałem i programowałem więc wiem, że się da, ale jest dużo problemów z narzędziami, które często są tworzone z myślą o środowiskach unix-owych.

Wracając jednak do Apple i procesora M1. Na pewno jest to duży krok na przód zmuszający konkurentów do ruszenia tyłków. Nie oznacza to, że każdy z was powinien rzucać się na tę architekturę tylko ze względu na wydajność. Mamy tu problemy wieku dziecięcego, które w większości przypadków są rozwiązane za pomocą Rosetty 2. Jednak, każdy kto musi mieć wirtualizację musi na ten moment sobie odpuścić i poczekać, aż Docker i pochodne rozwiązania otrzymają natywne wsparcie.