Helpex - Trao đổi & giúp đỡ Đăng nhập

Dockerizing ứng dụng khởi động mùa xuân

Docker ở đây, Docker ở đó, tôi thấy Dockers ở khắp mọi nơi.

Trong bài đăng này, tôi sẽ mô tả quá trình di chuyển một ứng dụng Spring Boot sang Docker. Chúng tôi sẽ bắt đầu với việc sửa đổi một tệp xây dựng, sau đó chúng tôi sẽ tạo một Dockerfile để nó có thể chạy cục bộ. Cuối cùng, chúng tôi sẽ xuất bản hình ảnh của mình trong DockerHub .

Giới thiệu

Một vài tháng trước, tôi đã bắt đầu một dự án cá nhân mới có tên JVM Bloggers  để giúp các lập trình viên Ba Lan truyền bá tin tức về các bài đăng blog mới của họ. Ban đầu, ứng dụng Spring Boot này được lưu trữ trên máy cục bộ của tôi, nhưng tôi đã chuyển nó sang tài khoản miễn phí trên Heroku .

Và trong những tuần đầu tiên, tôi hài lòng. Ứng dụng không phải trực tuyến 24/7 vì vậy ngủ 8 giờ mỗi ngày (giới hạn của tài khoản Heroku miễn phí) không phải là vấn đề lớn và giới hạn bộ nhớ 500 MB cũng không giới hạn tôi. Nhưng khi JVM Bloggers phát triển, tôi bắt đầu gặp phải các vấn đề kỳ lạ với việc sử dụng bộ nhớ: ứng dụng bắt đầu ngốn 500-550MB và rất khó tìm ra nguồn gốc của hành vi này. Tôi thậm chí còn để ứng dụng chạy trên máy cục bộ của mình với một hồ sơ đính kèm nhưng vẫn không tìm thấy bất cứ điều gì đáng ngờ.

Vấn đề về dấu chân bộ nhớ trở nên khó chịu vì tôi phải theo dõi ứng dụng và khởi động lại nó sau mỗi 1-2 ngày và do bản chất của Heroku, tôi không thể chỉ ssh vào máy chủ và gỡ lỗi hoặc đính kèm một hồ sơ vào một quy trình đang chạy. Rõ ràng là nếu tôi định thêm nhiều tính năng hơn cho JVM Bloggers, tôi phải chuyển nó sang một thứ linh hoạt hơn - một máy Linux với Docker.

Docker

Ngày nay Docker là một chủ đề rất phổ biến đối với nhiều nhà phát triển, đặc biệt là trong các dự án chuyển sang kiến ​​trúc microservices. Nhưng tính năng thú vị nhất từ ​​góc độ vấn đề của tôi là khả năng tạo ra một hình ảnh tiêu chuẩn hóa của ứng dụng của tôi và chạy nó trong một môi trường khác mà không phải lo lắng về sự khác biệt. Một hình ảnh có thể được triển khai cục bộ hoặc trên hầu hết mọi máy Linux, vì vậy với Docker, tôi có thể kiểm tra ứng dụng của mình cục bộ và triển khai nó trên AWS hoặc một nơi nào khác mà không gặp nhiều rắc rối.

Di cư

Đầu tiên, chúng ta phải thêm một số phụ thuộc và nhiệm vụ mới vào  tập lệnh build.gradle của  mình :

buildscript {
    // ...
    dependencies {
        // ...
        classpath('se.transmode.gradle:gradle-docker:1.2')
    }
}

// ...

group = 'tdziurko' // this will be my login at DockerHub (more about it later in this post)

task buildDocker(type: Docker, dependsOn: build) {      // this task will build our Docker image
    push = true
    applicationName = jar.baseName
    dockerfile = file('src/main/docker/Dockerfile')
    doFirst {
        copy {
            from jar
            into stageDir
        }
    }
}

Trong dòng 16, chúng tôi đã chỉ định vị trí của Dockerfile của chúng tôi, vì vậy bây giờ đã đến lúc tạo một tệp ở đó.

Tạo Dockerfile

Dockerfile là một tệp cấu hình chỉ định cách tạo hình ảnh Docker của chúng tôi để chúng tôi có thể triển khai sau này.

FROM java:8
MAINTAINER email@example.com
VOLUME /tmp
EXPOSE 8080

ENV USER_NAME blogger
ENV APP_HOME /home/$USER_NAME/app

RUN useradd -ms /bin/bash $USER_NAME
RUN mkdir $APP_HOME

ADD jvm-bloggers-0.5.0.jar $APP_HOME/jvm-bloggers.jar
RUN chown $USER_NAME $APP_HOME/jvm-bloggers.jar

USER $USER_NAME
WORKDIR $APP_HOME
RUN bash -c 'touch jvm-bloggers.jar'

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","jvm-bloggers.jar"]

Hãy để tôi giải thích tệp này từng bước:

  • TỪ java: 8 : hình ảnh cơ sở của chúng tôi, nó giống như  từ khóa mở rộng trong Java. Ở đây chúng tôi muốn tạo cơ sở cho hình ảnh với Java 8 được cài đặt
  • VOLUME / tmp : thư mục được gắn kết nơi ứng dụng của chúng tôi có thể ghi thứ gì đó vào đĩa
  • EXPOSE 8080 : số cổng ứng dụng của chúng tôi sẽ được khởi động và nó sẽ có sẵn từ bên ngoài vùng chứa Docker
  • ENV USER_NAME blogger : biến trợ giúp với tên người dùng mà chúng tôi sẽ sử dụng để chạy ứng dụng của mình
  • ENV APP_HOME / home / $ USER_NAME / app : biến trình trợ giúp tiếp theo với thư mục nơi đặt ứng dụng của chúng tôi
  • RUN useradd -ms / bin / bash $ USER_NAME : tạo người dùng có tên được xác định bằng $ USER_NAME
  • RUN mkdir $ APP_HOME : tạo thư mục ứng dụng
  • THÊM jvm-bloggers-0.5.0.jar $ APP_HOME / jvm-bloggers.jar : thêm fat-jar vào hình ảnh của chúng tôi và đặt nó vào $ APP_HOME
  • RUN chown $ USER_NAME $ APP_HOME / jvm-bloggers.jar : tất cả các lệnh trước đó đã được thực thi dưới dạng ROOT, vì vậy chúng tôi cần thay đổi chủ sở hữu của tệp jar của mình thành $ USER_NAME . Nói chung sử dụng ROOT trong Docker được coi là một cách tiếp cận sai lầm vì bảo mật.
  • USER $ USER_NAME; WORKDIR $ APP_HOME : thay đổi người dùng và thư mục làm việc thành những thư mục mà chúng tôi muốn sử dụng để chạy ứng dụng của mình
  • RUN bash -c 'touch jvm-bloggers.jar' : chạm vào tệp của chúng tôi để tệp có thời gian sửa đổi
  • ENTRYPOINT [“java”, “- Djava.security.egd = file: / dev /./ urandom”, “- jar”, ​​“jvm-bloggers.jar”] : thực thi fat-jar của chúng ta (urandom dành cho nguồn Tomcat của Sự hỗn loạn)

Chạy hình ảnh Docker cục bộ

Bây giờ chúng tôi đã có mọi thứ sẵn sàng để xây dựng và khởi chạy hình ảnh Docker của mình.

./gradlew clean build buildDocker

Phản ứng:

:buildDocker FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':buildDocker'.
> Docker execution failed
  Command line [docker push tdziurko/jvm-bloggers:latest] returned:
  unauthorized: access to the requested resource is not authorized

Task  buildDocker  không thành công vì chúng tôi không có tài khoản trên  DockerHub  hoặc chúng tôi chưa đăng nhập ở đó. nhưng nếu bạn kiểm tra hình ảnh địa phương ...

docker images

... bạn sẽ thấy rằng hình ảnh mới nhất của chúng tôi có thẻ đã sẵn sàng để sử dụng:

REPOSITORY                  TAG                             IMAGE ID            CREATED             VIRTUAL SIZE
tdziurko/jvm-bloggers       latest                          a09f884c5aa9        11 minutes ago      785.6 MB

Vì vậy, chúng tôi có thể chạy nó trong vùng chứa Docker bằng lệnh sau:

docker run -p 8080:8080 --add-host=database:<your_local_db_host> -e jasypt.encryptor.password="<secretPassword>" -e spring.profiles.active="dev" tdziurko/jvm-bloggers:latest

Một lần nữa, một số đoạn cần được giải thích chi tiết hơn:

  • —Add-host = database: <your_local_db_host> : thêm địa chỉ vào / etc / hosts trong vùng chứa, cơ sở dữ liệu var phải là địa chỉ của cơ sở dữ liệu của chúng ta, ví dụ: 192.168.0.101
  • -e jasypt.encryptor.password = “” : Mật khẩu jasypt để giải mã một số giá trị từ các tệp * .properties, -e thêm nó dưới dạng biến env vào vùng chứa
  • -e spring.profiles.active = “dev” : Cấu hình Spring Boot. dev là một được sử dụng để chạy ứng dụng cục bộ

Sau một vài giây, bạn sẽ thấy rằng ứng dụng của chúng tôi đã khởi động và nó đang chạy trong vùng chứa Docker.

Xuất bản lên DockerHub

Có sẵn hình ảnh Docker cục bộ là được miễn là bạn chỉ định chơi với hình ảnh đó trên máy tính của riêng mình, nhưng vì chúng tôi đang hướng tới việc triển khai AWS nên chúng tôi cần xuất bản hình ảnh của mình lên DockerHub để nó có thể truy cập được từ bất kỳ máy Linux nào.

Trước tiên, cần tạo một tài khoản ở đó (  trong trường hợp của tôi là tdziurko ) và đăng nhập bằng ứng dụng khách Docker để chúng tôi có thể xuất bản nó.

$ docker login
Username: tdziurko
Password:
Email: tomek@example.com
WARNING: login credentials saved in /Users/tomek/.docker/config.json
Login Succeeded

Bây giờ chúng ta có thể xây dựng lại ứng dụng của mình để đẩy hình ảnh lên DockerHub:

./gradlew clean build buildDocker

Sau một vài phút, chúng tôi sẽ thấy thông báo XÂY DỰNG THÀNH CÔNG và nếu bạn truy cập trang hồ sơ công khai DockerHub của mình, bạn sẽ thấy thông báo tương tự:

có nghĩa là hình ảnh Docker của chúng tôi với ứng dụng đang chờ triển khai tới máy AWS EC2. Nhưng đây là tài liệu cho một bài đăng trên blog khác :)

Tóm lược

Trong một vài bước, tôi đã mô tả cách thêm các khả năng của Docker vào dự án Java của bạn, cách định cấu hình hình ảnh của bạn và xuất bản nó trong DockerHub. Toàn bộ quá trình này không quá phức tạp và cho phép chúng tôi chuẩn bị ứng dụng để triển khai trên mọi máy hoặc máy chủ Linux hỗ trợ Docker.

9 hữu ích 0 bình luận 7.0k xem chia sẻ

Có thể bạn quan tâm

loading