コンテナは、今日のソフトウェア開発に不可欠なツールです。コンテナを活用すると、どのような環境でもアプリケーションを簡単に実行できます。
コンテナを実行するための最も一般的なテクノロジーは、任意のオペレーティングシステムで実行されるDockerです。
このブログ投稿では、Dockerを上位3つの最も重要なユースケースに使用する方法を学びます。次の方法を学習します:
- Dockerを使用してデータベースをローカルで実行します
- ドッキングされたデータベースを使用して自動テストを実行します
- アプリケーションをローカルおよびDockerを使用して本番環境で実行します。
Java Spring Bootアプリケーションを使用しますが、すべての学習は、選択した他のすべてのプログラミング言語に適用されます。
すべての例を実行するには、次のことを行う必要があります。
- Dockerをインストールする
- Javaをインストールする
Dockerを使用して分離されたアプリケーションを実行する
Dockerは、反復的でありふれた構成タスクを取り除き、開発ライフサイクル全体で使用され、デスクトップとクラウドの高速で簡単なポータブルアプリケーション開発を実現します。 (出典:https://www.docker.com/use-cases/)
Dockerの超大国の中核は、いわゆるcgroupsを活用して、数秒で開始できる、軽量で分離された、ポータブルでパフォーマンスの高い環境を作成することです。
Dockerを使用して生産性を高める方法を見てみましょう。
Dockerを使用すると、さまざまな種類のデータベースを数秒で起動できます。簡単で、データベースを実行するために必要な他の要件でローカルシステムを汚染することはありません。すべてがDockerコンテナにパッケージ化されています。
Hub.docker.comを検索すると、多くのデータベースですぐに使用できるコンテナーを見つけることができます。
docker run
を使用する コマンドを使用すると、MySQLDockerコンテナを起動できます。
docker run --rm -v "$PWD/data":/var/lib/mysql --name mysql -e MYSQL_ROOT_PASSWORD=admin-password -e MYSQL_DATABASE=my-database -p 3306:3306 mysql:8.0.28-debian
このコマンドは、Dockerコンテナを実行する高度な機能を使用します:
-
-v "$PWD/data"
ローカルディレクトリをマップします./data
Dockerコンテナに移動します。これにより、データを失うことなくDockerコンテナを起動できます。 -
-p 3306:3306
コンテナポートをマップします3306
他のアプリケーションがそれを使用できるように、私たちのマシンに -
-e MYSQL_DATABASE=my-database
my-database
という新しいデータベースを作成するための環境変数を設定します 自動的に -
-e MYSQL_ROOT_PASSWORD=admin-password
管理者パスワードを設定するための環境変数を設定します。 -
--rm
停止するとコンテナを削除します。
これらの環境変数などは、Dockerイメージのページに記載されています。
人気のある技術スタックを使用して、JavaとSpringBootに基づくWebアプリケーションを構築します。 Dockerパーツに焦点を当てるために、公式のAccessing JPA Data WithRestGuideから簡単なデモアプリケーションのクローンを作成できます。
# Download the sample application
git clone https://github.com/spring-guides/gs-accessing-data-rest.git
# Open the final application folder
cd complete
このアプリケーションにはインメモリデータベースが付属していますが、複数のサービスが単一のデータベースにアクセスして変更することはできないため、本番環境には役立ちません。 MySQLデータベースは、アプリケーションをより多くの読み取りと書き込みにスケーリングするのに適しています。
したがって、MySQLドライバーをpom.xml
に追加します :
<!-- Disable in memory database -->
<!--
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
-->
<!-- MySQL driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
次に、構成ファイルsrc/main/resources/application.properties
を追加して、データベースに接続するための構成を追加する必要があります。 。
# Database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/my-database
spring.datasource.username=root
spring.datasource.password=admin-password
# Create table and database automatically
spring.jpa.hibernate.ddl-auto=update
これで、アプリケーションを起動して既存のエンドポイントを呼び出すことができます:
# Get all people
curl http://localhost:8080/people
# Add a person
curl -i -H "Content-Type:application/json" -d '{"firstName": "Frodo", "lastName": "Baggins"}' http://localhost:8080/people
# Get all people again, which now returns the created person
curl http://localhost:8080/people
データベース内のデータの書き込みと読み取りを行う基本的なアプリケーションを正常に使用しました。 MySQL Dockerデータベースを使用すると、堅牢なデータベースが数秒で稼働し、どのアプリケーションからでも使用できます。
アプリケーションには、実行中のデータベースを期待するテストがすでにあります。ただし、インメモリデータベースを実際のMySQLデータベースに置き換えたため、データベースを停止するとテストは正常に実行されません。
# Stop database
docker rm -f mysql
# Run tests
./mvnw clean test
... skipped output ...
[ERROR] Tests run: 7, Failures: 0, Errors: 7, Skipped: 0
... skipped output ...
テストを実行しているコンテナーをすばやく開始および停止するために、testcontainersと呼ばれる便利なツールがあります。そこには、Javaを含む多くのプログラミング言語用のライブラリがあります。
まず、pom.xml
にいくつかの依存関係を追加する必要があります :
<!-- testcontainer -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
testcontainersを使用するには、テストを更新する必要があります。これにより、テストの実行ごとにデータベースが開始されます。テストに注釈とフィールドを追加して、それを利用します:
//added imports
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers // Annotation to enable testcontainers
public class AccessingDataRestApplicationTests {
// Field to access the started database
@Container
private static MySQLContainer database = new MySQLContainer<>("mysql:5.7.34");
//Set database configuration using the started database
@DynamicPropertySource
static void databaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", database::getJdbcUrl);
registry.add("spring.datasource.username", database::getUsername);
registry.add("spring.datasource.password", database::getPassword);
}
テストを実行するたびにデータベースが開始されます。これにより、テストを実行するときに実際のデータベースを使用できます。すべての配線、セットアップ、起動、クリーンアップはすべてあなたのために行われます。
単純なDockerツールを使用してアプリケーションをDocker化することは可能ですが、お勧めしません。
アプリケーションをビルドし、Javaを含むベースコンテナを使用して、アプリケーションをコピーして実行できます。しかし、多くの落とし穴があり、これはすべての言語とフレームワークに当てはまります。ですから、常にあなたの生活を楽にするツールを探してください。
この例では、Jibとdistrolessコンテナーを使用して、Dockerコンテナーを簡単に構築します。両方を組み合わせて使用すると、最小限の安全で再現性のあるコンテナが得られます。これは、ローカルでも本番環境でも同じように機能します。
Jibを使用するには、Jibをpom.xml
に追加して、Mavenプラグインとして追加する必要があります。 :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Jib plugin -->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<from>
<image>gcr.io/distroless/java17:nonroot</image>
</from>
<to>
<image>my-docker-image</image>
</to>
</configuration>
</plugin>
</plugins>
</build>
これで、イメージをビルドしてアプリケーションを実行できます:
# build the docker container
./mvnw compile jib:dockerBuild
# find your build image
docker images
# start the database
docker run --rm -v "$PWD/data":/var/lib/mysql --name mysql -e MYSQL_ROOT_PASSWORD=admin-password -e MYSQL_DATABASE=my-database -p 3306:3306 mysql:8.0.28-debian
# start the docker container which contains your application
docker run --net=host my-docker-image
… skipped output…
2022-04-15 17:43:51.509 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-04-15 17:43:51.521 INFO 1 --- [ main] c.e.a.AccessingDataRestApplication : Started AccessingDataRestApplication in 6.146 seconds (JVM running for 6.568)
アプリケーションは、ネットワークモードのホスト--net=host
で起動されます 、これにより、開始したデータベースに簡単に接続できます。または、docker network
を作成することもできます 両方を同じネットワークで開始します。
コンテナをコンテナレジストリにプッシュし、任意のコンテナオーケストレーションツールから参照して、アプリケーションを本番環境で実行できます。