- Instalacja Dockera w maszynie wirtualnej
- Konfiguracja IntelijIDEA
- Aplikacja SpringBoot w kontenerze Dockera
- Własne repozytorium Dockery Registry
- Publikacja obrazu aplikacji w rejestrze
W swoim rozwiązaniu wykorzystuję maszynę wirtualną Ubuntu, na której zainstalowałem Dockera. Takie rozwiązanie przyjąłem ze względu na problemy z kompatybilnością wirtualizacji WIndows 10 opartej na Hyper-V z VMWare Workstation czy VirtualBox.
Poniżej opiszę jak skonfigurować środowisko IntelijIDEA do pracy z Dockerem w takiej konfiguracji.
Instalacja Dockera w maszynie wirtualnej
Po zainstalowaniu Dockera na wirtualnym linuksie (używam Ubuntu 20.04 LTS) modyfikuję plik sterujący usługą Dockera /lib/systemd/system/docker.service
EnvironmentFile=/etc/default/docker
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS
Jak widzisz, do podania parametrów konfiguracyjnych usługi użyłem zewnętrznego pliku. Poniżej zawartość /etc/default/docker
DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -H tcp://192.168.1.199:2375 -H unix:///var/run/docker.sock"
Zwróć uwagę na adres IP – w moim przypadku to adres maszyny wirtualnej 192.168.1.199. Docker będzie dostępny na porcie 2375.
Następnie wczytaj zmiany i zrestartuj Dockera:
sudo systemctl daemon-reload
sudo systemctl restart docker
Jeżeli używasz firewalla, to otwórz port 2375:
sudo sudo ufw allow 2375/tcp
i upewnij się, że port ma status open.
nmap -p 2375 192.168.1.199
Konfiguracja IntelijIDEA
W menu Settings skonfiguruj połączenie z Dockerem zainstalowanym na maszynie wirtualnej (Ctrl+Alt+S).
Jeśli wszystko poszło OK, to możesz połączyć się z Dockerem za pomocą przycisku Connect.
Aplikacja SpringBoot w kontenerze Dockera
Skoro mamy już skonfigurowanego Dockera, to spróbujemy uruchomić w nim Spring Bootową aplikację.
Testowana aplikacja to prosty @RestController
package pl.javascratcher.hellodocker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class HelloDockerApplication {
@GetMapping
public String index() {
return "It Works!";
}
public static void main(String[] args) {
SpringApplication.run(HelloDockerApplication.class, args);
}
}
Jeżeli nie zmieniłeś domyślnego portu aplikacji, to pod adresem: http://localhost:8080 zobaczysz tekst “It Works!”.
Dodaj do projektu plik Dockerfile, w którym będą znajdować się instrukcje niezbędne do zbudowania obrazu.
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Teraz pozostaje tylko zbudować obraz i uruchomić kontener.
Jeżeli proces nie powiedzie się i otrzymasz błąd Failed to deploy ‘ Dockerfile: Dockerfile’: Can’t retrieve image ID from build stream
to zbuduj plik JAR za pomocą Mavena.
mvn package
Skonfigurujmy jeszcze proces tworzenia i uruchamiania obrazu:
podając nazwę kontenera oraz tag, mapujemy również port aplikacji 8080.
Po uruchomieniu kontenera, możesz połączyć się z aplikacją podając adres wirtualnego hosta: http://192.168.1.199:8080
Po stronie linuksa maszyny wirtualnej możesz sprawdzić, że obraz został zainstalowany:
sudo docker images
Możesz również uruchomić kontener:
sudo docker run -d -p 8080:8080 hello-docker
Własne repozytorium Dockery Registry
Opublikowanie obrazu w rejestrze umożliwia łatwe wdrożenie aplikacji. Do pobrania i uruchomienia aplikacji wystarczy jedna komenda docker run
. Swój obraz możesz opublikować w jednym z ogólnodostępnych rejestrów, możesz też utworzyć własny rejestr. W poniższym przykładzie skorzystam z tej drugiej opcji.
Najprostszą opcją na uruchomienie rejestru jest po prostu uruchomienie kontenera:
docker run -d -p 5000:5000 --name registry registry:2
Zatrzymanie rejestru:
docker container stop registry
Konfiguracja
W związku z tym, iż umieszczam rejestr na serwerze publicznym, skonfiguruję certyfikat SSL, który pozwoli na użycie protokołu HTTPS zamiast HTTP.
W pliku docker-compose.yml zdefiniuję parametry rejestru:
registry:
restart: always
image: registry:2
container_name: registry
ports:
- 8443:443
environment:
REGISTRY_HTTP_ADDR: 0.0.0.0:443
REGISTRY_AUTH: htpasswd
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/server.crt
REGISTRY_HTTP_TLS_KEY: /certs/server.key
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /registry/data:/var/lib/registry
- /registry/certs:/certs
- /registry/auth:/auth
W powyższym przykładzie mapuje port na 8443 (pod tym adresem rejestr będzie dostępny) oraz wolumeny:
- /registry/data – miejsce na dane
- /registry/auth -lokalizacja pliku htpasswd z danymi do autoryzacji
- /registry/certs – katalog, w którym umieszczę certyfikat server.crt oraz klucz prywatny server.key
Certyfikat SSL
Jeżeli nie dysponujesz certyfikatem SSL, to możesz wygenerować do tego celu certyfikat typu self-signed .
Uwaga! Przed wygenerowaniem certyfikatu zmodyfikuj konfigurację OpenSSL – plik /usr/lib/ssl/openssl.cnf dodając w sekcji v3_ca klucz subjectAltName, wskazujący na twój adres IP.
[ v3_ca ]
subjectAltName = IP:192.168.1.199
Jeżeli tego nie zrobisz, podczas łączenia się z rejestrem otrzymasz komunikat o błędzie:
x509: cannot validate certificate for because it doesn’t contain any IP SANs
W celu wygenerowania certyfikatu wykonaj:
sudo openssl req -nodes -new -x509 -keyout server.key -out server.crt
Utworzone pliku server.key i server.crt umieść w /registry/certs
Zainstaluj również certyfikat w systemie:
sudo cp server.crt /usr/local/share/ca-certificates/server.crt
sudo update-ca-certificates
Brak zainstalowanego certyfikatu skutkuje podczas łączenia się z rejestrem błędem:
x509: certificate signed by unknown authority
Autoryzacja
W konfiguracji rejestru używam pliku htaccess, w którym znajdują się dane niezbędne do zalogowania. Poniższe polecenie dodaje użytkownika javascratches z hasłem topsecret
sudo docker run \
--entrypoint htpasswd \
httpd:2 -Bbn javascratches topsecret > /registry/auth/htpasswd
Możemy teraz uruchomić rejestr:
sudo docker-compose up -d
Logowanie do rejestru:
sudo docker login localhost:8443
Po wprowadzeniu użytkownika i hasła powinieneś otrzymać komunikat o udanym zalogowaniu.
Publikacja obrazu aplikacji w rejestrze
Przed przesłaniem obrazu do rejestru musisz nadać mu odpowiedni tag
sudo docker image tag hello-docker localhost:8443/hello-docker
Teraz możesz opublikować obraz:
sudo docker push localhost:8443/hello-docker
Swój obraz możesz publikować w rejestrze bezpośrednio z IntelijIDEA, najpierw dodaje rejestr:
Aby przesłać obraz do rejestru wywołaj polecenie Push Image..
a następnie uzupełnij nazwę repozytorium i tag:
Po przesłaniu obrazu możesz uruchamiać kontener podając adres rejestru oraz nazwę repozytorium.
sudo docker run 192.168.1.199:8443/javascratches/hello-docker:v1
Zamiast lokalnego adresu IP możesz rzecz jasna użyć adresu IP swojego serwera VPS.