Docker - zaprzęgamy kontenery do pracy

W moim pierwszym artykule o Docker pokazałem wam jak przygotować podstawowy kontener, który zawiera php. mysql oraz apache. Trochę mi się oberwało, że skoro używam kontenerów to wypadałoby na każdy serwis postawić oddzielny kontener i w razie potrzeb przełączać się między kontenerami by uzyskać różne środowiska testowe bez konieczności większych zmian w konfiguracji. Ok, nauka zapamiętana... Dziś pokażę więc wam jak stworzyć kilka różnych kontenerów, każdy z jedną usługą, a następnie połączę to wszystko w jedno piękne środowisko testowe, w którym możemy odpalać naszą aplikację zarówno na php5 jak i php7

Narzędzia i obrazy

Dzisiaj, by nam się przyjemniej pracowało użyjemy następujących narzędzi:

  • Docker builder z Dockerfile - dzięki temu przygotujemy jak ma wyglądać nasz obraz danego kontenera
  • Docker compose - pozwala zarządzać naszymi kontenerami, określać zależności między nimi - wszystko to by jedną prostą komendą postawić/zatrzymać w sekundę nasze środowisko pracy.

Skorzystamy również z gotowych obrazów:

  • phusion/baseimage - obraz zawierający pare przydatnych rzeczy
  • sameersbn/mysql - z niego zbudujemy kontener na mysql co by pokazać wam, iż nie trzeba za każdym razem wymyślać koła na nowo

Wszystkie obrazy korzystają z obrazu ubuntu:14.04

Struktura katalogów

Aby nam się przyjemnie pracowało, stwórzmy sobie jakiś katalog, który będzie naszym głównym katalogiem dla dzisiejszego arta. W nim stwórzmy następujące katalogi:

  • images - katalog na nasze pliki konfiguracyjne obrazów
  • log - tutaj będą mapowane pliki logów z naszych kontenerów
  • src - tutaj będzie kod źródłowy naszej aplikacji

HTTP server

Jako serwera użyjemy dla odmiany NGINX zamiast Apache2. Utwórzmy zatem katalog images/nginx a w nim plik Dockerfile o następującej treści:

FROM phusion/baseimage
MAINTAINER author <author@email.pl>
CMD ["/sbin/my_init"]
RUN apt-get update && apt-get install -y python-software-properties
RUN add-apt-repository ppa:nginx/stable
RUN apt-get update && apt-get install -y nginx
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN mkdir -p /etc/service/nginx
ADD start.sh /etc/service/nginx/run
RUN chmod +x /etc/service/nginx/run
EXPOSE 80
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

gdzie:

  • Linia 1 - określa obraz bazowy do zbudowania naszego obrazu
  • Linia 2 - określa autora obrazu
  • Linia 3 - inicjalizuje kilka zadań dostarczonych wraz z obrazem phusion/baseimage
  • Linie 4,5,6 - instalują nginx
  • Linie 8,9,10 - kopiują plik start.sh do kontenera, który to zostanie odpalony przez obraz bazowy i wystaruje nginx
  • Linia 11 - mówi dla Docker, by każdy kontener odpalony z naszego obrazu był wystawiony na porcie 80
  • Linia 12 - czyści obraz ze zbędnych rzeczy

Do katalogu images/nginx dodajmy jeszcze brakujący plik start.sh:

#!/usr/bin/env bash
service nginx start

W naszym głównym katalogu odpalamy teraz z konsoli komendę

docker build -t nginx images/nginx

Powyższa komenda powinna zbudować nam nasz obraz o nazwie nginx. Pierwsze odpalenie tej komendy może chwilkę zająć, gdyż będa nam się pobierać niezbędne obrazy o ile nie zostału pobrany wcześniej przy innej okazji. Wykonując

docker images

powinniśmy zobaczyć na liście nasz świeżo utworzony obraz oraz obraz phusion/baseimage na podstawie którego powstał nasz obraz.

Mamy więc już obraz. Stwórzmy teraz na jego podstawie kontener, byśmy mogli w końcu coś przetestować. W tym celu w naszym głównym katalogu utwórzmy plik docker-compose.yml o treści:

nginx:
  image: nginx
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www
    - ./src/project1/project1.conf:/etc/nginx/sites-enabled/project1.conf
    - ./log/nginx:/var/log/nginx

gdzie:

  • Linia 1 - to nazwa naszego kontenera
  • Linia 2 - to nazwa obrazu na podstawie którego tworzyć będziemy kontener
  • Linie 3,4 - mówią, że nasz lokalny port 8080 będziemy mapować na port 80 kontenera. Nginx w kontenerze nasłuchuje na porcie 80
  • Linia 6 - nasz lokalny katalog scr mapuje na katalog /var/www kontenera dzięki czemu wszelkie zmiany w plikach jakie zrobimy w naszym lokalnym katalogu src, będą widoczne od razu w kontenerze
  • Linia 7 - nasz lokalny plik project1.conf mapujemy do katalogu kontenera dzięki czemu nginx zczyta nasz konigurację naszego pierwszego projektu
  • Linia 8 - nasz lokalny katalog log mapujemy na katalog log kontenera, dzięki czemu będziemy mogli sobie lokalnie przeglądać wszelkie logi nginxa z kontenera

Utwórzmy brakujący plik src/project1/project1.conf

server {
    listen 80;
    index index.html;
    server_name project1.test;
    error_log  /var/log/nginx/project1_error.log;
    access_log /var/log/nginx/project1_access.log;
    root /var/www/project1/public;
}

Jest to standardowy plik konfiguracyjny strony w nginx i nie ma tu co za bardzo tłumaczyć. Jedynie godne zauważenia jest to, iż pliki dostępne przez przeglądarkę znadować się będą w katalogu public. Utwórzmy więc w katalogu src/project1/public plik index.html o treści:

Hellow World!

Ok, wszystko gotowe do opalenia naszego kontenera. W tym celu wywołajmy w konsoli komendę

docker-compose up -d

Sprawdźmy, czy nasz kontener faktycznie wystartował. Odpalmy komendę

docker ps

Jeśli widzimy nasz ładny kontener, znaczy że jest. W pliku project1.conf powiedzieliśmy, że nasz projekt będzie odpalany w przeglądarce pod nazwą project1.test. Dodajmy więc do pliku /etc/hosts następującą linijkę:

127.0.0.1 project1.test

A następnie w przelgądarce wpiszmy:

http://project1.test:8080/

Podaliśmy port 8080 gdyż wcześniej określiliśmy, iż przez ten właśnie port nasz system będzie łączył się z kontenerem. Powinnismy na ekranie przelgądarki zobaczyć tekst Hello World. Pierwszy kontener działa.

PHP 5.6

Serwer http mamy już gotowy. Teraz przydałaby się nam obsługa php. Stworzymy więc wpierw obraz z php 5.6. W tym celu tworzymy katalog images/php56 a w nim Dockerfile o treści

FROM phusion/baseimage
MAINTAINER author <author@email.pl>

CMD ["/sbin/my_init"]
RUN apt-get update && \
    apt-get install -y python-software-properties
RUN sudo add-apt-repository ppa:ondrej/php5-5.6    
RUN apt-get update && \
    apt-get install -y --force-yes php5-fpm php5-mysql php5-mcrypt php5-intl php5-curl php5-gd php5-xsl

EXPOSE 9000    

RUN mkdir -p /etc/service/php-fpm
ADD start.sh /etc/service/php-fpm/run
RUN chmod +x /etc/service/php-fpm/run


RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Plik jest podobny do poprzedniego, z tym że zamiast nginx, instalujemy tam php 5.6 i wystawiamy kontenery na porcie 9000. Stwórzmy jeszcze tam plik images/php56/start.sh o treści

#!/usr/bin/env bash
php5-fpm -c /etc/php5/fpm --fpm-config /etc/php5/fpm/php-fpm.conf -F

który będzie nam startował php po wystartowaniu kontenera. Pliki obrazu mamy już gotowe. Utwórzmy teraz obraz odpalając komendę z katalogu głównego:

docker build -t php56 images/php56

Komendą

docker images

możemy sprawdzić nasz aktualny stan obrazów. Obraz z php 5.6 gotowy. Odpalmy teraz kontener na jego podstawie - modyfikujemy główny plik zarządzający obrazami docker-compose.yml

nginx:
  image: nginx
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www
    - ./src/project1/project1.conf:/etc/nginx/sites-enabled/project1.conf
    - ./log/nginx:/var/log/nginx
  links:
    - php56
php56:
  image: php56
  volumes:
    - ./images/php56/php-fpm.conf:/etc/php5/fpm/php-fpm.conf
    - ./src:/var/www
  • Linie 9,10 - mówimy kontenerowi nginx, iż będzie połączony z kontenerem php56. Dzięki temu kontener nginx będzie wiedział że pod nazwą php56 kryje się kontener, z którym ma się połączyć (w praktyce poprostu w kontenerze nginx w /etc/hosts powstaną odpowiednie wpisy)
  • Linia 11 - określamy nazwę kontenera na php56
  • Linia 12 - mówimy, iż tworzymy kontener z obrazku php56
  • Linia 14 - mapujemy plik z konfiguracją php-fpm w odpowiednie miejsce w kontenerze
  • Linia 15 - mapujemy nasze lokalne pliki źródłowe by kontener miał na czym działać

Jeśli chcecie, to jest to również dobry moment by podpiąć plik php.ini z własną konfiguracją. Stwórzmy jeszcze brakujący plik php-fpm.conf w katalogu images/php56

[global]
pid = /run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
daemonize = no

[www]
user = www-data
group = www-data
listen = 9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /

Zauważmy, że określamy, iż php będzie nasłuchiwać na porcie 9000 - tym sam co powiedzieliśmy tworząc obraz php56. Zmodyfikujmy jeszcze nasz plik konfiguracyjny projektu nginx ( src/project1/project1.conf ), by zaczął obsługiwać też php przekierowując żądania php do kontenera z php

server {
    listen 80;
    index index.php index.html;
    server_name project1.test;
    error_log  /var/log/nginx/project1_error.log;
    access_log /var/log/nginx/project1_access.log;
    root /var/www/project1/public;
    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php56:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Linia 14 mówi, iż żądania php mają być przekierowywane do kontenera php56 na porcie 9000. Odpalamy teraz jeszcze raz nasze kontenery komendą z głównego katalogu

docker-compose up -d

Mamy teraz działające dwa kontenery. Stwórzmy jeszcze plik src/project1/public/index.php

<?php
phpinfo();

i odpalmy jeszcze raz http://project1.test:8080 - powinniśmy zobaczyć ładną informację jakiego php używamy

PHP 7.0

Obiecałem na początku, iż będziemy mogli też potestować php 7.0 - no to do dzieła. Tworzymy katalog images/php70 a w nim plik Dockerfile

FROM phusion/baseimage
MAINTAINER author <author@email.pl>

CMD ["/sbin/my_init"]
RUN apt-get update && \
    apt-get install -y python-software-properties
RUN sudo add-apt-repository ppa:ondrej/php    
RUN apt-get update && \
    apt-get install -y --force-yes php7.0-fpm php7.0-mysql

EXPOSE 9000    

RUN mkdir -p /etc/service/php-fpm
ADD start.sh /etc/service/php-fpm/run
RUN chmod +x /etc/service/php-fpm/run


RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Tyle razy już to dziś przerabialiśmy, że nie ma co tłumaczyć. Jak widzicie, zamiast php 5.6 instalujemy php 7.0. Tworzymy jeszcze plik images/php70/start.sh

#!/usr/bin/env bash
php-fpm7.0 -c /etc/php7/fpm --fpm-config /etc/php7/fpm/php-fpm.conf -F

i tworzymy obraz komendą z katalogu głównego

docker build -t php70 images/php70

Obraz gotowy, tworzymy kontener. W tym celu modyfikujemy plik docker-compose.yml

nginx:
  image: nginx
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www
    - ./src/project1/project1.conf:/etc/nginx/sites-enabled/project1.conf
    - ./log/nginx:/var/log/nginx
  links:
    - php56
    - php70
php56:
  image: php56
  volumes:
    - ./images/php56/php-fpm.conf:/etc/php5/fpm/php-fpm.conf
    - ./src:/var/www
php70:
  image: php70
  volumes:
    - ./images/php70/php-fpm.conf:/etc/php7/fpm/php-fpm.conf
    - ./src:/var/www

Dodaliśmy poprostu opis nowego kontenera php70 a w kontenerze nginx dołączamy go obok php56. Dodajemy jeszcze brakujący plik z konfiguracją php-fpm images/php70/php-fpm.conf

[global]
pid = /run/php7-fpm.pid
error_log = /var/log/php7-fpm.log
daemonize = no

[www]
user = www-data
group = www-data
listen = 9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /

oraz zmodyfikujmy src/project1/project1.conf by obsługiwał wywołania dla php 7.0

server {
    listen 80;
    index index.php index.html;
    server_name project1.test;
    error_log  /var/log/nginx/project1_error.log;
    access_log /var/log/nginx/project1_access.log;
    root /var/www/project1/public;
    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php56:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

server {
    listen 80;
    index index.php index.html;
    server_name project1-70.test;
    error_log  /var/log/nginx/project1-70_error.log;
    access_log /var/log/nginx/project1-70_access.log;
    root /var/www/project1/public;
    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php70:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Jak widzicie, nasz kod będzie odpalany przez php 7.0 pod adresem project1-70.test. Dodajmy więc ten adres do naszych hostów w /etc/hosts

127.0.0.1 projest1.test
127.0.0.1 projest1-70.test

i wystartujmy nasze kontenery jeszcze raz komendą z katalogu głównego

docker-compose up -d

Teraz wpisując w przeglądarkę http://project1-70.test:8080/ powinniśmy zobaczyć info, iż mamy php 7.0. Wpisując zaś http://project1.test:8080/ mamy info o php 5.6 - nasz aplikacja może więc być odpalana pod różnymi php a jedyne co musimy zrobić to wpisać innego hosta. Proste, szybkie, genialne.

MySQL

Ok, szalejemy dziś. Mamy już kontenery na serwer, na różne php ale co tam, dodajmy jeszcze jeden na mysql. Tym razem nie będziemy wymyślać koła na nowo i skorzystamy już z gotowego obrazu sameersbn/mysql. Tak więc, skoro obraz już mamy, przechodzimy od razu do tworzenia kontenera. W tym celu modyfikujemy nasz docker-compose.yml

nginx:
  image: nginx
  ports:
    - "8080:80"
  volumes:
    - ./src:/var/www
    - ./src/project1/project1.conf:/etc/nginx/sites-enabled/project1.conf
    - ./log/nginx:/var/log/nginx
  links:
    - php56
    - php70
php56:
  image: php56
  volumes:
    - ./images/php56/php-fpm.conf:/etc/php5/fpm/php-fpm.conf
    - ./src:/var/www
  links:
    - db
php70:
  image: php70
  volumes:
    - ./images/php70/php-fpm.conf:/etc/php7/fpm/php-fpm.conf
    - ./src:/var/www
  links:
    - db
db:
  image: sameersbn/mysql
  volumes:
   - /var/lib/mysql
  environment:
   - DB_NAME=db_test
   - DB_USER=db_test_user
   - DB_PASS=db_test_pass

Jak widzicie, do kontenerów php56 oraz php70 dodaliśmy informację, iż mają się połączyć z kontenerem db. Zaś w konetenerze db określamy volume /var/lib/mysql - oznaczać to będzie, iż ten katalog kontener zostanie utworzony na naszym kompie a nie w kontenerze, dzięki czemu przy kolejnych tworzeniach kontenerów, nie będzie on znikał - nie chcemy przecież by nasza baza gineła nam przy każdej zmianie konfiguracji kontenera. Dodatkowo też określamy jaka ma zostać stworzona na dzień dobry baza - ot taki bajer od twórcy obrazu, z którego korzystamy. Ok, odpalamy komendę

docker-compose up -d

i mamy już 4 kontenery wpółgrające ze sobą. Zmodyfikujmy jeszcze nasz src/project1/public/index.php by sprawdzić, czy na pewno łączy się z bazą w naszym nowym kontenerze

<?php
try {
  $pdo = new PDO(
      'mysql:host=db;dbname=db_test',
      'db_test_user',
      'db_test_pass'
  );
  echo 'Mysql connection - ok';
} catch (Exception $e) {
  echo 'Connection error!!' . $e->getMessage();
}

phpinfo();?>

Odpalamy teraz http://project1.test:8080/ lub http://project1-70.test:8080/ i jeśli widzimy na ekranie Mysql connection - ok znaczy, że wszystko działa jak należy.

Podsumowanie

Nigdy nie pracowałem w takim systemie, że każdy większy proces mam wydzielony do oddzielnego kontenera. WIdzę jednak w tym duży potencjał. W każdej chwili mogę podmienić jeden kontener na inny bez konieczności zmiany całego środowiska - wystarczy że zmienie tylko dany proces. Moge też bardzo szybko przetestować moją aplikację pod różnymi php bez dzikiego kombinowania w instalacje kilku php działających obok siebie - pamiętam jak pare lat temu miałem z tym "niezłą" zabawę. Także kontenery zaczynają mi się podobać coraz bardziej z dnia na dzień.

Moja zabawa z kontenerami nie jest długa, więc całkiem możliwe, że można to zrobić jeszcze lepiej. Wszelkie uwagi/sugestie mile widziane. Paczka z gotowymi plikami, które tu zaprezentowałem znajduje się do pobrania w dziale Download (Docker/Multi kontenery)

Komentarze

 

2016-02-01 20:17 gość_by_ikar

Muszę przyznać że wyręczyłeś mnie, ponieważ zrobiłeś coś co w sumie ja obiecałem opisać, na swoje usprawiedliwienie mam tylko tyle że byłem chory przez weekend, miałem za to zabrać się dopiero teraz, patrzę na rss, a tutaj @nospor całkiem zgrabnie wszystko opisał

Podoba mi się to że spodobało ci się to jak to działa. Co do osobnych kontenerów, to raczej nie powinieneś tego traktować jako zupełnie wirtualna maszyna, bo docker na prawdę stara się użyć tyle ile może z innych kontenerów które stoją na tym samym obrazie. Dzięki czemu tak na prawdę docker staje się naszym demonem inicializacji, który uruchamia bądź restartuje nasze usługi, jednocześnie trzymając wszystkie hermetycznie wewnątrz ich własnych przestrzeni.

Istnieją narzędzia dzięki którym można stworzyć sobie pule serwerów (klaster) i do tej puli serwerów wrzucać nasze kontenery, czy też przenosić razem z danymi kontenery pomiędzy serwerami. Bez zbędnego reinstalowania, wszędzie ta sama wersja oprogramowania, wszystko hermetyczne, a konfiguracja wszędzie ta sama.

Ciekawe rzeczy których używam praktycznie każdego dnia:
- haproxy - loadbalancer konfigurowany w łatwy sposób poprzez "linkowanie" kontenerów;
- drone - CI do testowania naszej infrastruktury, odpalania testów jednostkowych, budowania zależnosci, deploymentu i wielu innych;
- swarm - zarządzanie kontenerami na różnych hostach;
- weave - łączenie kontenerów pomiędzy różnymi hostami poprzez publiczną sieć (coraz mniej potrzebny, dlatego że ostatnie zmiany w samym libnetwork dockera właśnie prowadzą ku temu aby można było łączyć sobie kontenery jak się chce);
- flocker - zarządzanie wolumenami kontenerów, przenoszenie całych kontenerów wraz z danymi pomiędzy różnymi hostami etc;
- cadvisor - real time monitoring kontenerów (oraz zarządzanie nimi) + api do przechowywania logów np w influxDB, dzięki czemu będzie można sobie podpiąć taki wykresik: http://docs.grafana.org/reference/graph/
- mesos - narzędzia do zarządzania farmą serwerów w dość "inteligentny" sposób: https://www.youtube.com/watch?v=0I6qG9RQUnY które mnie osobiście trochę przerażają ;D

Nie licząc mesos który jest raczej ciekawostką, całą resztę narzędzi używam każdego dnia i muszę przyznać że im bardziej zagłębiam się w temat dockera, tym bardziej jestem zadowolony z tego narzędzia. A jak coś potrzebuje doinstalować, to pierwsze co przychodzi mi do głowy "na pewno jest jakiś kontener na to" haha

No to teraz czekać na wątki związane z dockerem na forum. Co mnie cieszy, bo raz że będę mógł pomóc w problemach przez które przebrnąłem, albo ktoś będzie miał problem który z czasem może i mnie dotyczyć.

2016-02-02 11:18 nospor

Muszę przyznać że wyręczyłeś mnie, ponieważ zrobiłeś coś co w sumie ja obiecałem opisać, na swoje usprawiedliwienie mam tylko tyle że byłem chory przez weekend, miałem za to zabrać się dopiero teraz, patrzę na rss, a tutaj @nospor całkiem zgrabnie wszystko opisał
Dziękuję
Tak, czekałem na Twoj wpis, a że się nie mogłem doczekać i miałem chwilke wolnego czasu, to zrobiłem mały research i jakoś to poszło.

Dzięki za linki i opis dodatkowych narzędzi - wzbogaciłeś tym tego arta . Pare z nich na pewno mi się przyda, jak np. flocker - jakby co uśmiechę się do Ciebie w razie problemów

2016-02-03 09:11 gość_ayeo

Hej,

wielkie dzięki. To jest to co chciałem uzyskać. Walczyłem z tym wiele godzin i nie umiałem zmusić kontenerów do rozmawiania ze sobą. Jedyne co zmieniłem w Twoich obrazach to dodałem

RUN rm etc/nginx/sites-enabled/default

Nie wiem czemu, ale mi namiętnie czytał konfiga z tego pliku zamiast z project1. Po tej drobnej zmianie wszystko działa wspaniale! http://q.i-systems.pl/file/77697e53.png

Pozdrawiam i dziękuję jeszcze raz Szkoda, że nie opublikowałeś tego tydzień wcześniej

2016-02-03 10:21 gość_ayeo

Hej, nie mogę edytować już niestety. Wydaje mi się, że do konfiguracji php7 wkradł się mały błąd. Tam w konfigu ngnixa i samego php musimy podać port 9001 zamiast 900 (używanego dla 56).

Dodatkowo to co powinniśmy mieć w etc/hosts to (przynajmniej na osx)

192.168.99.100 project1.test
192.168.99.100 project1-70.test

Może komuś się przyda

2016-02-03 10:36 gość_ayeo

To znowu ja, użyłem jeszcze w docker-compose.yml "build" zamiast "image" co pozwala po prostu od razu uruchomić docker-compose up

http://pastebin.com/zXAtuwW7

2016-02-03 11:25 nospor

Wydaje mi się, że do konfiguracji php7 wkradł się mały błąd. Tam w konfigu ngnixa i samego php musimy podać port 9001 zamiast 900 (używanego dla 56).
Nie, nie trzeba. Zauwaz ze owsze, to sa te same porty 9000 ale na zupelnie roznych kontenerach i nie kolidują ze sobą. A przynajmniej nie kolidują na linux, nie wiem jak to jest na osx.

Dodatkowo to co powinniśmy mieć w etc/hosts to (przynajmniej na osx)

192.168.99.100 project1.test
192.168.99.100 project1-70.test
No tak, jesli nie uzywasz linux tylko osx czy windows to docker nie jest stawiany natywnie na linux tylko na virtualce i wowczas IP faktycznie jest inne.

To znowu ja, użyłem jeszcze w docker-compose.yml "build" zamiast "image" co pozwala po prostu od razu uruchomić docker-compose up
Tak. masz racje. Można dodac parametr BUILD bezposrednio do docker-compose.yml.

Szkoda, że nie opublikowałeś tego tydzień wcześniej
Tydzien wczesniej walczyłem ze zwykłym jednym kontenerem. Potrzebowałem tygodnia by wejść na level wyżej

2016-02-03 11:28 nospor

RUN rm etc/nginx/sites-enabled/default

Nie wiem czemu, ale mi namiętnie czytał konfiga z tego pliku zamiast z project1.
Poniewaz jak widac na załączonym przez Ciebie screenie, w przeglądarce podajesz IP zamiast nazwe hosta. Temu nginx nie wie jaki konfig załadować. Pamietaj, że nginx rozpoznaje konfiguracje po hostach.
Jakbyś uzył http://project1.test:8080/ to powinno ci działać niezależnie czy masz default czy nie.

2016-02-03 11:35 nospor

No i jak juz bedziesz poslugiwal sie hostami to bedziesz mogl zaglować czy chcesz php56 czy php70. Teraz przez IP on ci czyta tylko i wyłacznie pierwszą znalezioną konfiguracje. Takze temu ci sie wydaje, ze byl blad z portami 9000 i 9001

2016-02-03 11:51 gość_ayeo

Z tym portem to chodzi o to, że Dockerfile (w paczce) dla php70 zawiera "EXPOSE 9001". Oczywiście masz rację, że można używać 9000. Z hostem również masz rację, napierw walczyłem z tym po IP stąd ten komentarz.

Jeszcze raz dzięki za ten wpis. Też tydzień poprzedni walczyłem z tym, ale nie udało mi się zmusić do współpracy tych maszyn. Działały wszystkie wariacje dwuelementowe (php z mysql, http z php) ale nigdy wszystko razem. Dzięki temu postowi wszystko śmiga jak należy. Mało kto w necie stawia php osobno, a na tym mi zależało właśnie. Z ciekawych rzeczy widziałem też wydzielenie kodu aplikacji do osobnego kontenera i podmontowanie volume (compose). Nie wiem tylko czy ma to dla mnie sens, chcemy docelowo robić deploy Kubernetessem.

2016-02-03 12:34 nospor

Z tym portem to chodzi o to, że Dockerfile (w paczce) dla php70 zawiera "EXPOSE 9001".
hm... faktycznie...w pewnym momencie eksperymentowalem z portami i musialem zapomniec poprawic zanim wrzucilem. Dzieki, zaraz poprawie paczke

Z ciekawych rzeczy widziałem też wydzielenie kodu aplikacji do osobnego kontenera i podmontowanie volume (compose).
No wlasnie tez nie wiem jaki jest sens tego... moze ktos nas oswieci

2016-02-03 15:06 gość_ayeo

Sens jest taki, że w przypadku aktualizacji kodu (commit do repo) nie musisz przebudowywać całego obrazu serwera tylko budujesz nowy obraz samego volumenu. Chodzi o to, że aplikację budujesz tylko raz. Kontener zawiera więc skonfigurowaną i działającą aplikację. Brzmi to absurdalnie bo po co przebudowywać po każdym commicie obraz kontenera, od trzymania kodu jest repo. Jednak to jest cudowne. Masz dokładnie tę samą aplikację u developera, na testach i na produkcji. Nie budujesz jej 500 razy. Dev dostaje skonfigurowaną i działającą. Deploy Kubernetesem polega wyłącznie na aktualizacji obrazu. Resztę robi on sam (podmienie contenery na vmkach).

Nie wiem tylko właśnie czy dla adminów nie będzie lepiej mieć tego razem (ale wydaje mi się, że nie)

2016-02-03 15:06 gość_ayeo

Oczywiście przebudowanie obrazu powinno być automatyczne po pushu do mastera

2016-02-03 15:14 nospor

Chyba się muszę przespać z tą myślą

2016-02-04 22:49 gość_ayeo

To się chyba nazywa "Build Once, Deploy Many" jakbyś szukał

2016-02-04 22:53 gość_ayeo

https://blog.openshift.com/build-once-deploy-anywhere/

2016-02-04 23:30 nospor

Ok, dzieki za linka. Jutro postaram sie to przejrzec

2016-02-09 14:10 gość_ayeo

Zbudowałem swój zestaw bazując na Twoim. Jest dostępny na githubie:

https://github.com/ayeo/docker_php_env

W dokumentacji jest oczywiście informacja o Twoim wpisie

2016-02-09 15:53 nospor

Widzę, iż stworzyłeś oddzielny kontener na kod. No ok, widze w tym jakąś logike, ale jeszcze nie do końca. O ile ładne to sie sprawdza w łączeniu innych kontenerów z kodem, nie trzeba się bawić już w lokalne ścieżki, to próbuje jeszcze doszukać się w tym sensu o którym pisałeś wcześniej. Ale nadal nie mogę.
Jesteś w stanie to mi jeszcze raz wytłumaczyć jak dla dziecka? A może jeszcze w tej konfiguracji nie jest to zawarte ta wcześniejsza logika?

Jak wystawiasz VOLUME /var/www i jednocześnie podmontowujesz go pod swoj lokalne .src, to gdzie ostatecznie trzymana jest wersja kodu? Lokalnie czy w wystawionym VOLUME? Co jesli odetniesz lokalne src - zachowa sie wtedy w VOLUME? Mogę to sprawdzić ale narazie nie mam na to czasu a problem mnie ciekawi.

2016-02-09 21:57 gość_ayeo

Nie podmontowuję pod swój src docelowo. Kod jest w samym kontenerze, w pełni skonfigurowany (composer, autoload, konfiguracja). Deploy na serwer testowy, developerski czy produkcyjny to tylko podmiana kontenera (w tym wypadku tego z kodem).

2016-02-09 23:14 gość_ayeo

Poprawiłem konfig na githubie

2016-02-10 09:42 gość_by_ikar

Sens w kontenerach z osobnym kodem, tak zwanych data kontenerach, jest taki, że można taki kontener łatwo zmigrować na różne wersje, jak i przenieść pomiędzy maszynami. Takie narzędzia jak flocker mogą wówczas przenieść cały taki kontener na inną maszynę. Tyle tylko, że to ma bardziej produkcyjne zastosowanie, niż na developmencie. I to też wtedy kiedy nasza aplikacja wymaga jakiegoś skalowania. Ale to też nie jest tak że to jest jakaś konieczność, bo przecież można mieć swojego NFS'a na którym będziemy współdzielić pomiędzy różnymi maszynami nasze pliki. Można też skorzystać z innych rozwiązań. Lecz każde z tych rozwiązań ma swoje zalety i wady, o ile przy aplikacjach bezstanowych jest dość spore pole do wyboru rozwiązania, o tyle aplikacje stateful (nie wiem jak to przetłumaczyć) to już jest trochę więcej kombinowania.

Dla przykładu: aplikacja napisana w node.js która nasłuchuje na zdarzeniach mających miejsce w redisie (coś jak triggery w mysql, tyle tylko że nie ograniczone jedynie do mysql). podczas aktualizacji kodu musisz uruchomić ponownie aplikacje, aby zaczytała sobie nowy kod. Z kolei kiedy twoja aplikacja nie będzie tych zdarzeń z redisa przetwarzać, twój system będzie miał luki czasowe podczas deploymentu. Load balancing? Nie bardzo, ta aplikacja nie jest wystawiona na świat, działa sobie w tle. No i zaczynają się robić schody. Nie wszystko jest takie łatwe jak w aplikacjach bezstanowych do których wystarczy dostawić zapasowy serwer i load balancer. Więc kwestia tego jakie ma twoja aplikacja wymagania, u mnie w firmie o tyle wyszliśmy z tego obronną ręką, że cały projekt był projektowany razem z deploymentem. Chociaż i tak wiele problemów napotkaliśmy po drodze, o których nie mieliśmy podczas projektowania pojęcia.

2016-02-10 10:06 nospor

Nie podmontowuję pod swój src docelowo
podmontowywales w pierwszej wersji konfiguracji wiec mi teraz nie sciemniaj Teraz zmieniles.

Ok, moze kiedys dorosne do tej idei. Teraz nie potrzebuje

2016-02-10 10:44 gość_ayeo

Pisałem, że poprawiłem konfig

2016-04-24 10:33 gość_szymon

Świetny artykuł!
Zastanawiam się, czy można użyć Dockera na serwerze produkcyjnym. U siebie instaluję obrazy z nginx'em, php i jakąś bazą i czy opłaca się - pod względem wydajności - zainstalować te same obrazy na produkcji?

2016-04-24 19:53 nospor

No szybciej to działać raczej nie będzie. Jak nie masz jakiejś specjalnej potrzeby to raczej tak nie kombinuj

2016-05-03 01:17 gość_nekih82

super artykul
ikar, a gdzie ty umieszczal swoje wpisy? bo chetnie poczytam, wdrazam sie w dockera i chce dobrze zglebic temat.

Dodaj komentarz

 

Dostępne bbcode: b, u, i, url, code, php, css, html, sql, js

Ostatnio komentowane

  1. ShoutBox nospor
  2. ShoutBox Artur
  3. PHP South Coast conf... nospor
  4. PHP South Coast conf... srednioZaawansowanyPHPowiec
  5. Docker - podstawowy ... nospor
  6. Docker - podstawowy ... Leelum
  7. Pager nospor

Skrypty użytkowników

  1. Klasa obsługi szablo... Lirdoner
  2. Sekcje user76
  3. Klasa walidująca for... user76
  4. Licznik Gości online korey
  5. Form Builder Comandeer
  6. Dynamiczny licznik z... korey
  7. Captcha Comandeer