Pertanyaan Cara membangun kontainer buruh pelabuhan untuk aplikasi java
Apa yang ingin saya lakukan adalah membangun citra buruh pelabuhan untuk aplikasi Java saya, tetapi pertimbangan berikut harus benar untuk sebagian besar bahasa yang dikompilasi.
masalah
Pada server saya membangun saya ingin menghasilkan gambar buruh pelabuhan untuk aplikasi saya sebagai deliverable. Untuk ini saya harus mengkompilasi aplikasi menggunakan beberapa alat membangun (biasanya Gradle, Maven atau Ant) dan kemudian menambahkan file JAR yang dibuat ke gambar buruh pelabuhan. Karena saya ingin gambar buruh pelabuhan untuk mengeksekusi file JAR saya tentu saja akan mulai dari gambar dasar dengan Java yang sudah diinstal.
Ada tiga cara untuk melakukan ini:
biarkan alat membangun mengontrol proses
Dalam hal ini alat build saya mengontrol seluruh proses. Jadi ini mempersiapkan file JAR dan setelah JAR dibuat itu memanggil Docker untuk membuat gambar. Ini berfungsi karena JAR dibuat sebelumnya dan Docker dapat mengabaikan proses pembangunan yang dibutuhkan untuk membuat JAR.
Tapi Dockerfile saya tidak lagi berdiri sendiri. Itu tergantung pada langkah-langkah yang terjadi di luar Docker untuk bekerja. Dalam Dockerfile saya, saya akan memiliki COPY
atau ADD
pernyataan yang seharusnya menyalin file JAR ke gambar. Pernyataan ini akan gagal ketika toples tidak dibuat sebelumnya. Jadi hanya mengeksekusi Dockerfile mungkin tidak berfungsi. Ini menjadi masalah jika Anda ingin mengintegrasikan dengan layanan yang hanya dibangun menggunakan Dockerfile ini seperti fitur auto-build di DockerHub.
biarkan Docker mengontrol build
Dalam hal ini semua langkah yang diperlukan untuk membuat gambar ditambahkan ke Dockerfile sehingga gambar dapat dibuat dengan hanya mengeksekusi build Docker.
Masalah utama dengan pendekatan ini adalah bahwa tidak ada cara untuk menambahkan ke perintah Dockerfile yang harus dijalankan di luar gambar buruh pelabuhan yang dibuat. Ini berarti saya harus menambahkan kode sumber saya dan alat membangun saya ke gambar buruh pelabuhan dan membangun file JAR saya di dalam gambar. Ini akan menghasilkan gambar saya menjadi lebih besar dari yang seharusnya karena semua file yang ditambahkan yang tidak diperlukan pada saat runtime. Ini juga akan menambahkan lapisan tambahan ke gambar saya.
Edit:
Sebagai @ adrian-mouat menunjukkan jika saya akan menambahkan sumber, membangun aplikasi dan menghapus sumber dalam satu pernyataan RUN saya bisa menghindari menambahkan file dan layer yang tidak perlu ke gambar Docker. Ini berarti membuat beberapa perintah dirantai gila.
dua bangun terpisah
Dalam hal ini kami membagi dua build kami: pertama kami membuat file JAR menggunakan alat build kami dan mengunggahnya ke repositori (Maven atau Ivy repository). Kami kemudian memicu build Docker terpisah yang hanya menambahkan file JAR dari repositori.
kesimpulan
Menurut saya, cara yang lebih baik adalah membiarkan alat membangun mengontrol proses. Ini akan menghasilkan gambar buruh pelabuhan yang bersih dan karena gambar inilah yang ingin kami sampaikan, ini penting. Untuk menghindari Dockerfile yang berpotensi tidak berfungsi, berbohong tentang ini harus dibuat sebagai bagian dari build. Jadi tidak ada yang secara tidak sengaja menggunakannya untuk memulai membangun rusak.
Tetapi ini tidak memungkinkan saya untuk berintegrasi dengan DockerHub.
pertanyaan
Apakah ada cara lain yang saya lewatkan?
32
2017-07-29 09:28
asal
Jawaban:
Hub registri buruh pelabuhan memiliki Gambar Maven yang dapat digunakan untuk membuat kontainer java.
Menggunakan pendekatan ini, mesin build tidak perlu memiliki Java atau Maven pra-instal, Docker mengontrol seluruh proses build.
Contoh
├── Dockerfile
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── org
│ │ └── demo
│ │ └── App.java
│ └── resources
│ └── log4j.properties
└── test
└── java
└── org
└── demo
└── AppTest.java
Wadah dibangun sebagai berikut:
docker build -t my-maven .
Dan jalankan sebagai berikut:
$ docker run -it --rm my-maven
0 [main] INFO org.demo.App - hello world
Dockerfile
FROM maven:3.3-jdk-8-onbuild
CMD ["java","-jar","/usr/src/app/target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"]
Memperbarui
Jika Anda ingin mengoptimalkan penampung untuk mengecualikan sumber, Anda dapat membuat Dockerfile yang hanya menyertakan jar yang dibangun:
FROM java:8
ADD target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar /opt/demo/demo-1.0-SNAPSHOT-jar-with-dependencies.jar
CMD ["java","-jar","/opt/demo/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"]
Dan buat penampung dalam dua langkah:
docker run -it --rm -w /opt/maven \
-v $PWD:/opt/maven \
-v $HOME/.m2:/root/.m2 \
maven:3.3-jdk-8 \
mvn clean install
docker build -t my-app .
__
Perbarui (2017-07-27)
Docker sekarang memiliki file membangun multi-tahap kemampuan. Hal ini memungkinkan Docker untuk membangun wadah dengan gambar yang berisi alat-alat build tetapi menghasilkan gambar hanya dengan dependensi runtime.
Contoh berikut menunjukkan konsep ini, perhatikan bagaimana toples disalin dari direktori target fase build pertama
FROM maven:3.3-jdk-8-onbuild
FROM java:8
COPY --from=0 /usr/src/app/target/demo-1.0-SNAPSHOT.jar /opt/demo.jar
CMD ["java","-jar","/opt/demo.jar"]
21
2017-07-29 20:11
Struktur aplikasi java
Demo
└── src
| ├── main
| │ ├── java
| │ │ └── org
| │ │ └── demo
| │ │ └── App.java
| │ └── resources
| │ └── application.properties
| └── test
| └── java
| └── org
| └── demo
| └── App.java
├──── Dockerfile
├──── pom.xml
Isi Dockerfile
FROM java:8
EXPOSE 8080
ADD /target/demo.jar demo.jar
ENTRYPOINT ["java","-jar","demo.jar"]
Perintah untuk membangun dan menjalankan gambar
- Pergi ke direktori proyek. Katakanlah D: / Demo
$ cd D/demo
$ mvn clean install
$ docker build demo .
$ docker run -p 8080:8080 -t demo
Periksa apakah penampung sedang berjalan atau tidak
$ docker ps
Outputnya akan
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55c11a464f5a demo1 "java -jar demo.jar" 21 seconds ago Up About a minute 0.0.0.0:8080->8080/tcp cranky_mayer
4
2018-04-01 12:25
Beberapa hal:
Jika Anda menghapus file dalam instruksi yang sama yang Anda tambahkan, mereka tidak akan memakan ruang di dalam gambar. Jika Anda melihat beberapa Dockerfiles untuk gambar resmi, Anda akan melihat mereka mengunduh sumber, membuatnya, dan menghapus semuanya dalam langkah yang sama (mis. https://github.com/docker-library/python/blob/0fa3202789648132971160f686f5a37595108f44/3.5/slim/Dockerfile). Ini berarti Anda perlu melakukan beberapa senam yang mengganggu, tetapi itu sangat bisa dilakukan.
Saya tidak melihat masalah dengan dua Dockerfiles yang terpisah. Yang menyenangkan tentang ini adalah Anda bisa menggunakan JRE daripada JDK untuk menjadi tuan rumah guci Anda.
1
2017-07-29 11:23
Cara termudah adalah dengan biarkan alat membangun mengontrol proses. Jika tidak, Anda harus memelihara file build alat build Anda (seperti pom.xml
untuk Maven atau build.gradle
untuk Gradle) serta a Dockerfile
.
Cara mudah untuk membangun kontainer Docker untuk aplikasi Java Anda adalah menggunakan Jib, yang tersedia sebagai Maven dan Gradle plugin.
Misalnya, jika Anda menggunakan Maven dan ingin membangun penampung Anda ke daemon Docker yang sedang berjalan, Anda bisa menjalankan perintah yang satu ini:
mvn compile com.google.cloud.tools:jib-maven-plugin:0.9.2:dockerBuild
Anda juga bisa membangun langsung ke registri Docker dengan Jib tanpa perlu menginstal docker
, jalankan daemon Docker (yang membutuhkan hak akses root), atau tulis a Dockerfile
. Ini juga lebih cepat dan membangun gambar secara reproduktif.
Lihat lebih banyak tentang Jib di repo Github-nya: https://github.com/GoogleContainerTools/jib
1
2017-07-09 13:01
ada penggunaan alternatif untuk menjalankan jar atau paket perang
- tambahkan guci ke dalam gambar.
- mengatur heapsize untuk java
- jalankan perintah jar melalui entrypoint
contoh dockerfile
FROM base
ADD sample.jar renamed.jar
ENV HEAP_SIZE 256m
ENTRYPOINT exec java -Xms$HEAP_SIZE -Xmx$HEAP_SIZE -jar renamed.jar
di samping contoh penyebaran paket di tomcat
FROM tomcat7
ADD sample.war ${CATALINA_HOME}/webapps/ROOT.war
CMD ${CATALINA_HOME}/bin/catalina.sh run
Membuat dockerfiles sebagai gambar
cp tomcat.dockerfile /workingdir/Dockerfile
docker build -t name /workingdir/Dockerfile .
Daftar gambar
docker images
Gunakan gambar untuk membuat penampung
docker run --name cont_name --extra-vars var1=val1 var2=val2 imagename
0
2017-12-26 22:09
Sini Saya menggambarkan bagaimana saya melakukannya di lingkungan pengembangan saya.
- Bangun perang / guci secara lokal dengan Maven
- Salin ke folder Docker lokal
- Menjalankan Plugin Intellij Docker yang menciptakan gambar buruh pelabuhan yang berisi perang / guci, menjalankan server aplikasi dan menyebarkannya di server Docker yang jauh
Semoga itu membantu.
0
2018-01-29 10:04
Kami menggunakan Spotify Docker Maven Plugin untuk sementara. Plugin memungkinkan Anda untuk mengikat Docker membangunnya ke fase siklus hidup Maven.
Sebuah contoh:
Jalankan Docker membangun setelah pengemasan (fase: paket) aplikasi Anda dengan mengkonfigurasi plugin untuk menambahkan aplikasi yang dibangun sebagai sumber daya untuk membangun konteks Docker. Dalam tahap penerapan jalankan tujuan dorong Docker untuk mendorong gambar Docker Anda ke registri. Ini dapat berjalan di samping plugin penyebaran normal, yang menerbitkan artefak ke dalam repositori seperti Nexus.
Kemudian, kami membaginya menjadi dua pekerjaan terpisah di server CI. Karena Docker hanyalah salah satu cara untuk menjalankan aplikasi Anda (kadang-kadang kita membutuhkan aplikasi yang dirilis pada lingkungan yang berbeda tidak hanya Docker), build Maven tidak boleh bergantung pada Docker.
Jadi pekerjaan pertama merilis aplikasi di Nexus (melalui penyebaran Maven). Pekerjaan kedua (yang dapat menjadi ketergantungan hilir pekerjaan pertama) mengunduh artifak rilis terbaru, melakukan pembuatan Docker dan mendorong gambar ke registri. Untuk mengunduh rilis terbaru kami menggunakan Versi Plugin Maven (versi: gunakan-rilis terbaru) serta Maven Ketergantungan Plugin (ketergantungan: dapatkan dan ketergantungan: copy).
Pekerjaan kedua juga dapat dimulai untuk versi tertentu dari aplikasi untuk (kembali) membangun gambar Docker untuk rilis yang lebih lama. Selain itu Anda dapat menggunakan membangun pipa (pada Jenkins), yang mengeksekusi kedua pekerjaan dan melewati versi rilis atau artefak rilis ke build Docker.
0
2017-07-27 18:33