" - *Container* (kontener) - instancja obrazu. Może być uruchomiona, zatrzymana. Stan kontenera można zapisać tworząc nowy obraz. Uruchomienie kontenera zazwyczaj zajmuje mało czasu.\n",
" - *Image* (obraz) - niezmienny (readonly) przepis na stworzenie kontenera. Obrazy można ściągnąć lub udostępnić za pośrednictem *rejestru*. Budowanie obrazu trwa zazwyczaj długo.\n",
" - Możliwa zarówno pod Linux, Windows i MacOS.\n",
" - Kontenery Linuxowe można uruchamiać również pod Windowsem (za pomocą Docker Desktop lub WSL 2 (Windows Subsystem for Linux). Pod spodem oba używają maszyny wirtualnej (Hyper-V) z Linuxem, w której uruchamiane są kontenery [link](https://www.docker.com/blog/docker-hearts-wsl-2/)"
"- ```docker help [polecenie]``` - wyświetla listę dostępnych poleceń dockera lub opis podanego polecenia. Rozbudowana dokumentacja poleceń: https://docs.docker.com/engine/reference/commandline/docker/\n",
"- ```docker run``` - uruchamia istniejący obraz tworząc kontener. Przykładowe wywołania:\n",
" - ```docker run -i -t ubuntu```<br>\n",
" Uruchamia kontener z obrazu \"ubuntu\", allokuje terminal (`-t`) i ustawia tryb \"interaktywny\" (`-i`), dzięki czemu dostajemy terminal \"wenątrz\" kontenera i możemy wywoływać w nim polecenia\n",
"\n",
" - ```docker run -p 8080:8080 jenkins/jenkins:lts```<br>\n",
" Uruchomi kontener z Jenkinsem, w wersji \"LTS\". Jeśli obraz Jenkins nie był wcześniej zbudowany/pobrany na lokalną maszynę, automatycznie zostanie pobrany z [Docker Hub](https://hub.docker.com/r/jenkins/jenkins).\n",
" Port 8080 konenera zostanie powiązany z portem 8080 hosta. Dzięki temu będziemy mogli w przeglądarce dostać się do Jenkinsa pod adresem http://localhost:8080\n",
"- ```docker build [OPTIONS] PATH | URL | -``` - buduje obraz na podstawie pliku Dockerfile i kontekstu (plików dostępnych podczas budowania). Przykład:<br>\n",
" buduje obraz przekazując bieżący katalog (`.`) jako kontekst i korzystając z pliku Dockerfile znajdującego się tamże. Obraz zostanie otagowany (`-t`) tagiem `tzietkiewicz/helloworld` z wersją `1.0`"
"1. Zainstaluj Docker (lub skorzystaj z https://laboratoria.wmi.amu.edu.pl/en/issues/docker/)\n",
"2. Uruchom obraz `ubuntu` w trybie interaktywnym z terminalem (`docker run -ti ubuntu`)\n",
"\n",
"Poniższe punkty wywołujemy wewnątrz kontenera (w otwartym właśnie terminalu):\n",
"\n",
"3. Jaka wersja Ubuntu działa w kontenerze? (polecenie `cat /etc/issue`)\n",
"4. Jaki użytkownik wywołuje polecenia? (polecenie `whoami`)\n",
"5. Jaki jest bieżący katalog? (polecenie `pwd`)\n",
"5. Jaki procesor jest widoczny w środku kontenera? Czy jest to procesor Twojej maszyny? (`lscpu`)\n",
"6. Ile wolnego miejsca na dysku jest widoczne wewnątrz kontenera (`df -h`)? Czy jest to zgodne z tym, co pokazuje maszyna hosta?\n",
"7. Sprawdź ile dostępnej pamięci RAM widać w konenerze (`free -h`). Czy zgadza się to z wynikiem na maszynie hosta?\n",
"8. Spróbuj uruchomić jedno z popularnych narzędzi Linuksowych, dostępnych na maszynie hosta (np. `vim`, `less`, `htop`). Czy udało się je uruchomić?\n",
"9. Zainstaluj w kontenerze jedno z brakujących narzędzi, np: `apt update; apt install htop`\n",
"10. Uruchom następujące polecenie: <br>\n",
"`while true; do date > time.log; sleep 1; done`\n",
"będzie ono co sekundę zapisywać bieżący timestamp w pliku time.log\n",
"\n",
"Poniższe polecenia wykonujemy na zewnątrz kontenera (otwórz w tym celu nową konsolę):\n",
"\n",
"11. Sprawdź ID uruchomionego kontenera (`docker ps`) i zatrzymaj go (`docker stop`)\n",
"12. Sprawdź co się stało w oknie z konsolą kontenera\n",
"13. Uruchom kontener jeszcze raz (`docker start`). Gdzie jest nasza konsola?!!\n",
"14. Żeby otrzymać konsolę, wykonaj jedno z poniższych:\n",
" - zatrzymaj kontener i uruchom jeszcze raz z flagą `-i`\n",
" - uruchom polecenie \"bash\" w kontenerze za pomocą polecenia `docker exec -ti CONTAINER_ID bash` - pozwala ono uruchomić dowolne polecenie w działającym kontenerze.\n",
"15. Czy polecenie `while true; do date > time.log; sleep 1; done` wciąż działa? Sprawdź ostatni timestamp zapisany do pliku `time.log`"
" - Polecenia dockera są pisane WIELKIMI LITERAMI\n",
" - Wywołanie każdego polecenia tworzy nową warstwę (*layer*)\n",
" - Jeśli zbudowaliśmy obraz a potem zmieniliśmy jedno z poleceń / dodaliśmy nowe, to przebudowane zostaną tylko warstwy od zmienionej w dół (osczędność czasu i zasobów)"
"# Nasz obraz będzie dzidziczył z obrazu Ubuntu w wersji latest\n",
"FROM ubuntu:latest\n",
"\n",
"# Instalujemy niezbędne zależności. Zwróć uwagę na flagę \"-y\" (assume yes)\n",
"RUN apt update && apt install -y figlet\n",
"\n",
"# Stwórzmy w kontenerze (jeśli nie istnieje) katalog /app i przejdźmy do niego (wszystkie kolejne polecenia RUN, CMD, ENTRYPOINT, COPY i ADD będą w nim wykonywane)\n",
"WORKDIR /app\n",
"\n",
"# Skopiujmy nasz skrypt do katalogu /app w kontenerze\n",
"COPY ./figlet-loop.sh ./\n",
"\n",
"# Domyślne polecenie, które zostanie uruchomione w kontenerze po jego starcie\n",
"(Reading database ... 4039 files and directories currently installed.)\n",
"Preparing to unpack .../figlet_2.2.5-3_amd64.deb ...\n",
"Unpacking figlet (2.2.5-3) ...\n",
"Setting up figlet (2.2.5-3) ...\n",
"update-alternatives: using /usr/bin/figlet-figlet to provide /usr/bin/figlet (figlet) in auto mode\n",
"update-alternatives: warning: skip creation of /usr/share/man/man6/figlet.6.gz because associated file /usr/share/man/man6/figlet-figlet.6.gz (of link group figlet) doesn't exist\n",
"1. Napisz prosty Dockerfile, który zdefinuje środowisko potrzebne do wywołania poleceń stworzonych na zajęciach \"2. Dane\". Przypuszczalnie wystarczy, że zainstalujesz zależności takie jak kaggle czy pandas, np: \n",
"Niech zdefiniowany przez Ciebie obraz dziedziczy z jakiegoś popoularneg obrazu, np. `ubuntu`\n",
"Umieść Dockerfile w głównym katalogu repozytorium ze skryptami stworzonymi na zajęciach 2.\n",
"\n",
"2. Zbuduj obraz korzystając z polecenia `docker build .`\n",
" Na końcu otrzymasz id obrazu, który powstał\n",
"3. Uruchom kontener z terminalem `docker run -ti IMAGE_ID` podając ID obrazu, które otrzymałeś w poleceniu 2.\n",
"4. Spróbuj uruchomić jeden z twoich skryptów w kontenerze. Jeśli brakuje jakiś zależności: możesz spróbować zainstalować je interaktywnie w konsoli. W ten sposób będziesz wiedział jakie polecenia dodać do Dockerfile.\n",
"6. Utwórz bezpłatne konto na https://hub.docker.com/\n",
"7. Po zalogowaniu stwórz nowe repozytorium (https://hub.docker.com/repository/create), możesz nazwać je np. `ium`\n",
"8. W ustawieniach docker hub wygeneruj \"Access token\" (https://hub.docker.com/settings/security)\n",
"9. Uruchom `docker login --username TWÓJ_DOCKER_ID` i podaj stworzony w poprzednim kroku \"Access token\"\n",
"10. Dodaj tag do obrazu stworzonego 2 punkcie 3. Dzięki temu będzie można go opublikować: `docker tag IMAGE_ID TWÓJ_DOCKER_ID/ium:NUMER_WERSJI`. Mogliśmy otagować obraz na etapie jego budowania (flaga `-t`), ale wtedy nie znaliśmy jeszcze nazwy użytkownika i repozytorium z Docker Hub.\n",
"11. Teraz możesz wypchnąć swój otagowany obraz do repozytorium: `docker push TWÓJ_DOCKER_ID/ium:NUMER_WERSJI`\n",
"12. Twój obraz powinien być widoczny na Docker Hub. Inni mogą go teraz znaleźć na [Docker Hub](https://hub.docker.com/search?q=&type=image), np.:<br>\n",
"13. Link do obrazu w Docker Hub wklej do arkusza ze zbiorami danych [link](https://uam.sharepoint.com/:x:/s/2021SL06-DIUMUI0LABInynieriauczeniamaszynowego-Grupa11/EYhZK_aXp41BsIVS4K-L1V4B_vM2FjO5nJZMWv2QKXJolA?e=DKIS2O)"
" - **Controller**: The central, coordinating process which stores configuration, loads plugins, and renders the various user interfaces for Jenkins\n",
" - **Agent**: An agent is typically a machine, or container, which connects to a Jenkins controller and executes tasks when directed by the controller\n",
" - **Master**: A deprecated term, synonymous with Controller.\n",
" - **Node**: A machine which is part of the Jenkins environment and capable of executing Pipelines or Projects. Both the Controller and Agents are considered to be Nodes.\n",
" - **Executor**: A slot for execution of work defined by a Pipeline or Project on a Node. A Node may have zero or more Executors configured which corresponds to how many concurrent Projects or Pipelines are able to execute on that Node."
"Główna instancja Jenkinsa (tzw. *Controller* aka. *Master*) może mieć podłączonych kilka węzłów (\"nodes\") typu \"slave\".\n",
" - *Controller* jest odpowiedzialny za interakcję z użytkownikiem, rozdzielanie zadań dla między agentów\n",
" - Zadania (\"builds\") są wykonywane na jednym z \"Agentów\". Node, na którym jest uruchomiony \"Controller\" może działać również jako \"Agent\"\n",
" - Każdy węzeł może działać pod kontrolą innego systemu operacyjnego. Dzięki temu możemy wykonywać zadania (albo ich części) w różnych środowiskach\n",
" - Do definiowana gdzie może być wykonana dana część pipeline, służy sekcja [agent / node](https://www.jenkins.io/doc/book/pipeline/syntax/#agent). Poniższy kod wywoła sie tylko na węźle/węzłach \"myAgent\":\n",
"1. Zmodyfikuj stworzony na poprzednich (3.) zajęciach Jenkinsfile opisujący pipeline \"s123456-create-dataset\" tak, żeby wywoływać w nim skrypty stworzone na zajęciach 2., w środku kontenera stworzonego w zadaniu 2.<br> \n",
" Skorzystaj z mechanizmu tworzącego kontener bezpośrednio na Jenkinsie wprost z pliku Dockerfile.\n",
"\n",
"2. Zmodyfikuj stworzony na poprzednich (3.) zajęciach Jenkinsfile opisujący pipeline \"s123456-dataset-stats\" tak, żeby wywoływać w nim skrypty stworzone na zajęciach 2., w środku kontenera stworzonego w zadaniu 2.<br>\n",