45

docker を使用して Java Web アプリケーションを aws エラスティック Beanstalk にデプロイしようとしています。アイデアは、開発とテストのためにコンテナーをローカルで実行し、最終的に git を使用して本番環境にプッシュできるようにすることです。

tomcat8 と java8 がインストールされた基本イメージを作成しました。gradle ビルドを実行するイメージはこの基本イメージから継承され、ビルド プロセスが高速化されます。

docker を使用してビルドされた継承アプリケーション コンテナーが gradle の依存関係をキャッシュしていないように見えるという事実を除いて、すべてがうまく機能し、gradlew を含めて毎回ダウンロードします。次のコマンドを使用して Web アプリケーションを構築します。

./gradlew war

これでファイルをキャッシュできる方法はありますか~/.gradle?ビルドを劇的に高速化します。

これは Beanstalk ではそれほど問題ではありませんが、ご想像のとおり、これには多くの時間がかかるため、ローカルでビルドして実行しようとする開発者にとっては大きな問題です。

基本イメージの dockerfile:

FROM phusion/baseimage
EXPOSE 8080
RUN apt-get update
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections
RUN apt-get -y install oracle-java8-installer
RUN java -version
ENV TOMCAT_VERSION 8.0.9
RUN wget --quiet --no-cookies http://archive.apache.org/dist/tomcat/tomcat-8/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz -O /tmp/catalina.tar.gz
# Unpack
RUN tar xzf /tmp/catalina.tar.gz -C /opt
RUN mv /opt/apache-tomcat-${TOMCAT_VERSION} /opt/tomcat
RUN ln -s /opt/tomcat/logs /var/log/tomcat
RUN rm /tmp/catalina.tar.gz
# Remove unneeded apps
RUN rm -rf /opt/tomcat/webapps/examples
RUN rm -rf /opt/tomcat/webapps/docs
RUN rm -rf /opt/tomcat/webapps/ROOT
ENV CATALINA_HOME /opt/tomcat
ENV PATH $PATH:$CATALINA_HOME/bin
ENV CATALINA_OPTS $PARAM1
# Start Tomcat
CMD ["/opt/tomcat/bin/catalina.sh", "run"]

アプリケーション dockerfile:

FROM <tag name here for base image>
RUN mkdir ~/.gradle
# run some extra stuff here to add things to gradle.properties file
# Add project Source
ADD . /var/app/myapp
# Compile and Deploy Application, this is what is downloading gradlew and all the maven dependencies every time, if only there was a way to take the changes it makes to ~/.gradle and persist it as a cache layer
RUN cd /var/app/myapp/ && ./gradlew war
RUN mv /var/app/myapp/build/libs/myapp.war /opt/tomcat/webapps/ROOT.war
# Start Tomcat
CMD ["/opt/tomcat/bin/catalina.sh", "run"]
4

4 に答える 4

14

build.gradle にresolveDependenciesタスクを追加します。

task resolveDependencies {
    doLast {
        project.rootProject.allprojects.each { subProject ->
            subProject.buildscript.configurations.each { configuration ->
                configuration.resolve()
            }
            subProject.configurations.each { configuration ->
                configuration.resolve()
            }
        }
    }
}

Dockerfile を更新します。

ADD build.gradle /opt/app/
WORKDIR /opt/app
RUN gradle resolveDependencies

ADD . .

RUN gradle build -x test --parallel && \
    touch build/libs/api.jar

ベローは私が今やっていることです:

build.gradle

ext {
    speed = project.hasProperty('speed') ? project.getProperty('speed') : false
    offlineCompile = new File("$buildDir/output/lib")
}

dependencies {
    if (speed) {
        compile fileTree(dir: offlineCompile, include: '*.jar')
    } else {
        // ...dependencies
    }
}

task downloadRepos(type: Copy) {
    from configurations.all
    into offlineCompile
}

Dockerfile

ADD build.gradle /opt/app/
WORKDIR /opt/app

RUN gradle downloadRepos

ADD . /opt/app
RUN gradle build -Pspeed=true
于 2016-05-25T15:53:23.093 に答える
9

アプリケーション イメージを 2 つのイメージに分割することを検討してください。1 つは myapp.war のビルド用、もう 1 つはアプリケーションの実行用です。そうすれば、実際のビルド中に Docker ボリュームを使用して、ホストの~/.gradleフォルダーをビルドを実行するコンテナーにバインドできます。ただし、アプリケーションを実行するための 1 つのステップだけではなく、より多くのステップが必要になります。例:

ビルダーイメージ

FROM <tag name here for base image including all build time dependencies>

# Add project Source
# -> you can use a project specific gradle.properties in your project root
# in order to override global/user gradle.properties
ADD . /var/app/myapp

RUN mkdir -p /root/.gradle
ENV HOME /root
# declare shared volume path
VOLUME /root/.gradle
WORKDIR /var/app/myapp/ 

# Compile only
CMD ["./gradlew", "war"]

アプリケーションイメージ

FROM <tag name here for application base image>

ADD ./ROOT.war /opt/tomcat/webapps/ROOT.war

# Start Tomcat
CMD ["/opt/tomcat/bin/catalina.sh", "run"]

ビルダー Dockerfile がそこにあり、アプリケーション Dockerfile がwebappサブフォルダー (または任意の他のパス) にあると仮定して、プロジェクト ルートで使用する方法:

$ docker build -t builder .
$ docker run --name=build-result -v ~/.gradle/:/root/.gradle/ builder
$ docker cp build-result:/var/app/myapp/myapp.war webapp/ROOT.war
$ cd webapp
$ docker build -t application .
$ docker run -d -P application

表示されているコードはまだテストしていませんが、理解していただければ幸いです。この例は、.gradle/ キャッシュにデータ ボリュームを使用することで改善される場合もあります。詳細については、Dockerユーザー ガイドを参照してください。

于 2014-10-06T10:10:06.413 に答える