Nie masz środowiska? Docker na pomoc!

Dlaczego Docker? Wiele osób pyta mnie, czy do nauki potrzebne jest specjalne środowisko lub klaster. Klaster na pewno jest fajną opcją. Mimo wszystko sporo możliwości daje pojedyncza maszyna z Dockerem na pokładzie.

Dlaczego Docker?

Od momentu gdy poznałem podstawy Docker, nie potrafię sobie przypomnieć kiedy instalowałem jakąś bazę danych na swoim komputerze. Bardzo ułatwia pracę, deweloperkę i poznawanie nowych technologii bez zaśmiecania sobie systemu. Nie będę wchodzić w szczegóły opisując co to jest i jak to działa. W skrócie: jest to lekka wirtualizacja. Aplikacje opakowane są w kontenery, przez co w łatwy i powtarzalny sposób można je przenosić i odpalać na różnych maszynach. Możemy zasymulować klaster uruchamiając kilka kontenerów naraz.

Warto zastanowić się nad skonteneryzowaniem swojej aplikacji. Na końcu wpisu znajdziesz przykład konteneryzacji aplikacji w Pythonie z biblioteką Flask

Co warto wiedzieć?

Docker Compose

Zamiast pisać za każdym razem „docker run … <milion opcji> … <nazwa kontenera>”, można spisać to w formie plku YAML i uruchamiać nawet kilka kontenerów naraz. Kontenery mogą być od siebie zależne (np. aplikacja jest zależna od bazy danych, więc ta powstanie pierwsza)

Porty

Jeśli chcesz dostać się do usług jakiegoś kontenera pamiętaj o wystawieniu odpowiedniego portu

Volume

Volume to zmapowanie systemu plików w kontenerze do systemu plików systemu operacyjnego maszyny. Jeśli postawisz kontener z bazą i nie zmapujesz odpowiedniego folderu, po wyłączeniu kontenera prawdopodobnie stracisz dane.

Network

Jeśli zależy Ci na tym, aby kilka kontenerów ze sobą gadało, upewnij się, że są w tej samej sieci (dockerowej)

DNS

Docker ma swojego wewnętrznego dns-a dla utworzonych sieci, więc jeśli utworzysz kontener o nazwie XYZ, to po tej właśnie nazwie znajdą go inne kontenery w tej samej sieci.

Kilka komend

  • docker exec -it <nazwa kontenera> /bin/bash lub jesli kontener nei ma bash-a docker exec -it <nazwa kontenera> sh – odpalenie terminala z poziomu konteneru
  • docker logs <nazwa kontenera> – wyświetlenie logów danego kontenera. Jeśli chcesz śledzić je na bierząco wystarczy dodać -f

Lista kontenerów

Poniżej zebrałem kilka aplikacji/systemów/jak zwał które mają na celu zainteresować Cię tematem. Może akurat zastanawiasz się jak na szybko coś odpalić. Koniecznie zerknij na Docker Hub, zanim zaczniesz coś instalować na swojej maszynie deweloperskiej.

Jupyter

docker run -d -P --name notebook jupyter/all-spark-notebook

Szczegóły znajdziesz w dokumentacji. Jeśli interesuje Cię PySpark, Apache Spark i Scala, warto zerknąć tutaj

Apache Airflow

Tej techonologii użyłem w mini projekcie związanym z danymi GPS komunikacji miejskiej w Warszawie. Postawienie go ręcznie pip-em wymaga spełnienia pewnych zależności. W przypadku dockera problem ten nas nie dotyczy. Warto zerknąć na repozytorium https://github.com/puckel/docker-airflow. Poniżej Docker Compose z tego repo.

version: '2.1'
services:
    postgres:
        image: postgres:9.6
        environment:
            - POSTGRES_USER=airflow
            - POSTGRES_PASSWORD=airflow
            - POSTGRES_DB=airflow

    webserver:
        image: puckel/docker-airflow:1.10.6
        restart: always
        depends_on:
            - postgres
        environment:
            - LOAD_EX=n
            - EXECUTOR=Local
        volumes:
            - ./dags:/usr/local/airflow/dags
            # Uncomment to include custom plugins
            # - ./plugins:/usr/local/airflow/plugins
        ports:
            - "8080:8080"
        command: webserver
        healthcheck:
            test: ["CMD-SHELL", "[ -f /usr/local/airflow/airflow-webserver.pid ]"]
            interval: 30s
            timeout: 30s
            retries: 3

Microsoft SQL Server

Zdziwiony? MSSQL można odpalić na linuchu i to w formie dockera. Poniższa komenda odpali nam SQL Server w wersji 2017 Express.

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -e 'MSSQL_PID=Express' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latest-ubuntu 

Apache Kafka

W internecie znajdziesz kilka sposobów/obrazów/kontenerów z Apache Kafka. Pisał też o tym Radek na http://bigdatapassion.pl/blog/kafka/kafka-docker/ . Ja używam poniższego Docker Compose opartego o kontener utworzony przez firmę Bitnami.

version: '2'

services:
  zookeeper:
    image: 'bitnami/zookeeper:3'
    ports:
      - '2181:2181'
    volumes:
      - 'zookeeper_data:/bitnami'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  kafka:
    image: 'bitnami/kafka:2'
    ports:
      - '9092:9092'
      - '29092:29092'
    volumes:
      - 'kafka_data:/bitnami'
    environment:
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,PLAINTEXT_HOST://:29092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
    depends_on:
      - zookeeper

volumes:
  zookeeper_data:
    driver: local
  kafka_data:
    driver: local

Cassandra

Postawienie Cassandry to banał. Istnieje oficjalny kontener z prostą dokumentacją. Jest opcja postawienia klastra. Poniżej przykład włączenia konsoli cassandry w kontenerze.

maciej@ubuntu:~$ sudo docker exec -it some-cassandra cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 2.1.21 | CQL spec 3.2.1 | Native protocol v3]
Use HELP for help.
cqlsh> 

Elastic Search + Kibana

Mój ulubiny zestaw do zbierania logów. Poniżej docker compose, którego najczęściej używam. Pamietaj o odpowiednim skonfigurowaniu linucha.

version: '2.2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
    restart: unless-stopped
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  kibana:
    image: docker.elastic.co/kibana/kibana:7.1.1
    restart: unless-stopped
    depends_on:
      - elasticsearch
    ports:
      - 5601:5601
    volumes:
      - kibanadata:/usr/share/kibana/data
    networks:
      - esnet

volumes:
  esdata:
    driver: local
  kibanadata:
    driver: local

networks:
  esnet:

Własny kontener

Poniżej przykład Dockerfile dla zestawu Python + Flask. Aplikacja jest to plik app.py, a hostowana jest gunicornem. W pliku requirements.txt znajdują się wszystkie potrzebne biblioteki do pobrania przez pip-a.

FROM python:3.8-alpine

RUN adduser -D someuser

WORKDIR /home/app

RUN apk add --no-cache --update python3-dev  gcc build-base

COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN apk add --no-cache --update python3
RUN python3 -m ensurepip
RUN venv/bin/pip3 install --upgrade pip
RUN venv/bin/pip3 install -r requirements.txt
RUN venv/bin/pip3 install gunicorn


COPY ./ .
RUN chmod +x /home/app/boot.sh

ENV FLASK_APP app.py

RUN chown -R bell:bell ./
USER someuser

EXPOSE 5000
ENTRYPOINT ["/home/app/boot.sh"]

Po wrzuceniu Dockerfile do katalogu z aplikacją wystarczy „docker build -t moj-kontenerek .” Kod Dockerfile jest dość prosty. Bierzemy kontener python-…, następnie instalowane są zależności, kopiowany kod aplikacji, wystawiany port 5000, a pod koniec ustawiany skrypt boot.sh jako Entrypoint. Treść pliku poniżej.

source venv/bin/activate
exec gunicorn -b :5000 --access-logfile - --error-logfile - app:app

3 myśli w temacie “Nie masz środowiska? Docker na pomoc!”

    1. Hej, pewnie masz racje. W tym przypadku (z tego co pamiętam) gcc bylo potrzebne do zainstalowania pipem gunicorna. Same kod aplikacji, z racji ze to python, sie nie kompiluje. Jak tworzę kontenery .net core to uzuwam multi-stage build.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *