Jeżeli jesteś programistą Pythona oraz korzystasz ze środowiska AWS i Anacondy, to prędzej czy później napotkasz potrzebę uruchomienia skryptu Pythona jako procesu cronowego na Amazon Linux w środowisku Anaconda. To chyba nie powinno być trudne, prawda? Hmmm, niestety jest. Ponieważ spędziłem trochę czasu na konfiguracji crona na Amazon Linux w EC2, tak aby korzystał ze środowiska wirtualnego Anacondy, i nie raz padały przy tym z moich ust słowa potocznie uznawane za obelżywe, 😉 to chciałbym podzielić się z Wami pomysłem na to, jak to można zrobić prosto, szybko i bez nerwów.
W sieci jest oczywiście całkiem sporo treści dotyczącej konfiguracji pythonowych procesów cronowych. Cześć nawet dotyczy EC2 i Amazon Linux, ale jakoś żaden z tych postów nie rozwiązywał do końca wszystkich problemów, jakie ja napotkałem.
OK, zdefiniujmy zatem poszczególne kroki, które są niezbędne do konfiguracji pythonowego crona na AWS:
- Musimy mieć dostęp przez SSH do Amazon Linux działającego na AWS EC2 – zadanie w zasadzie trywialne, nie będę tego opisywał.
- Zainstalowana i zainicjowana Anaconda – instalacja również jest prosta. Na końcu procesu instalator pyta, czy zainicjalizować condę – należy wybrać „tak”. W efekcie, po zalogowaniu się przez SSH, mamy zawsze zaktywowane środowisko (base). Może być to dla niektórych denerwujące, ale upraszcza wiele kwestii, jeżeli użytkownik systemu operacyjnego jest wykorzystywany głównie do wykonywania skryptów Pythona. Tak powinno to wyglądać tuż po zalogowaniu:
- W pierwszej kolejności tworzymy wirtualne środowisko condy (załóżmy nazwę test-env). Tu jest opisane, jak to zrobić, wykonując kilka prostych komend. Można teoretycznie wykonać skrypt w środowisku base, ale jest to mocno niezalecane. Warto po prostu utworzyć dedykowane środowisko i zaimportować moduły, których potrzebujemy.
- Tworzymy skrypt pythonowy (załóżmy nazwę test.py), który chcemy uruchomić w cronie. Dla celów testowych będzie on wyświetlał informację, które środowisko condy jest aktywne. Wyświetlał? Proces cronowy? Oczywiście proces cronowy nie ma terminala, ale jego output przekierujemy potem do pliku i tam będzie można dla celów testowych podejrzeć wynik wykonania.
import os
print(os.environ['CONDA_DEFAULT_ENV'])
- Teraz najważniejszy krok, nie tak oczywisty, choć ostatecznie trywialny. Tworzymy skrypt systemu operacyjnego (załóżmy nazwę test.sh), w którym aktywujemy środowisko test-env i uruchomimy skrypt test.py. Kluczowa dla poprawnego działania jest linia pierwsza, pozostałe są dość oczywiste. Zakłada ona istnienie domyślnego usera Amazon Linux (ec2-user) oraz instalację Anacondy w katalogu anaconda3. Należy pamiętać, aby sprawdzić i w miarę potrzeby nadać uprawnienia do uruchomienia skryptu.
source /home/ec2-user/anaconda3/bin/activate
conda activate test-env
# Jeżeli chcesz w skrypcie sprawdzić, które środowisko jest aktywne: echo $CONDA_DEFAULT_ENV
python test.py
conda deactivate
- Prawie na sam koniec tworzymy skrypt z definicją joba cronowego (zakładam nazwę test.cron). Poniższe polecenie uruchamia nasz test.sh (a więc ostatecznie test.py) codziennie o godzinie 10:00 czasu lokalnego serwera – uwaga zależy on od centrum danych, w którym ulokujemy wirtualkę. Wywołanie skryptu ma przekierowany output do pliku test.log, gdzie można obejrzeć wynik wykonania.
00 10 * * * bash test.sh >> /home/ec2-user/test.log 2>&1
- Pozostaje nam zarejestrować joba w cronie systemowym.
crontab test.cron
- Aktualne ustawienia crona można sprawdzić poleceniem:
crontab -l
I to by było na tyle. 🙂
Masz pytanie? Zadaj je w komentarzu.
Spodobał ci się post? Będzie mi miło, gdy go polecisz.
Do zobaczenia wkrótce, przy okazji omawiania innego ciekawego tematu!