Dockerイメージ データの永続化 コンテナと接続する
Docker Compose
インストール
VScodeにRemote Developmentをインストール(DevContainers内包)

Snippet
Docker
docker pull ubuntu:22.04 docker image ls -a docker container ls -a docker container run -it docker container exec [container-name] bash
Docker Compose
# 複数コンテナを一気に作成する docker compose up (-d) # 起動中のコンテナを確認 docker compose ps # bashでコンテナに入る docker compose exec [container-name] bash # コンテナを全て終了する docker compose down
# make sure the version of web container node --version v18.20.3
Dockerイメージ
コンテナの型となるテンプレ
スクリプト・バイナリ・ファイルシステム・環境変数など
docker image pull {イメージ名} docker image build {コンテキストパス} docker image inspect {イメージ名} # イメージの詳細情報 docker image ls docker image rm {イメージ名}
docker container run {イメージ名} {立ち上げ直後に実行したいコマンド名} docker container run -itd --rm --name {コンテナ名} --network {NW名} {イメージ名} -i --interactive 標準入力CLOSED → OPENにするOP -t --tty 出力を整形する疑似テレタイプライター -d --detach バックグラウンド実行(デタッチトモード) --net --network ネットワークに接続する docker container ls docker container inspect {コンテナ名} # コンテナの詳細情報 docker container restart {コンテナ名} # 再度UP状態にする docker container stop {コンテナ名} # 止めてExited状態にする docker container rm {コンテナ名} # Exitedコンテナを削除する docker container rm -f {コンテナ名} # 動作中のコンテナでも強制削除できる docker container prune # Exitedコンテナを全て廃棄
Upコンテナに対してコマンド実行を指示
コンテナ内にログインしなくてもコマンドを実行できる
docker container exec -it {コンテナ名} {実行させるコマンド} -i --interactive 標準入力CLOSED → OPENにするOP -t --tty 出力を整形する疑似テレタイプライター -d --detach バックグラウンド実行(デタッチトモード) 例)docker container exec -it my-ubuntu-1 ping -c 4 8.8.8.8
docker container detatch {コンテナ} # デタッチしてバックグラウンドで実行する docker container attach {コンテナ} # アタッチしてフォアグラウンド操作できるようにする
データの永続化
ボリューム
container-1 container-2
volume を共有
docker container run -v {Vol名}:{コンテナ内絶対パス} --name {コンテナ名} {イメージ} 例)docker container run -it -v my-volume:/app1 --name container-1 ubuntu:22.04
バインドマウント
PCのローカル任意ディレクトリ と Dockerコンテナの任意ディレクトリ を同期させる
docker container run -v {ホスト絶対パス}:{コンテナ内絶対パス} {イメージ} 例)docker container run -it -v my-volume:/app1 --name container-1 ubuntu:22.04 docker container run -it -v C:\USERS\ISDMS\ONEDRIVE\ドキュメント\DOCKER\UDEMY\MY-DIR:/app ubuntu:22.04 docker container run -it -v $(pwd)\MY-DIR:/app ubuntu:22.04
ボリュームとバインドマウントの使い分け
ボリューム(Docker内部) | バインドマウント(ホストと同期) | |
複数のコンテナ間でのデータ共有可能か? | YES | YES |
ホストからのデータアクセス可能か? | NO | YES |
ホストの環境に依存するか? | NO | YES |
ボリューム【推奨】= ホスト環境で左右される(データベースはボリュームに置くのが基本)
バインドマウント = 開発中など、ホストから積極的にコンテナデータへアクセス/共有が必要な時
コンテナと接続する
コンテナのポート制御(ホストマシン⇔コンテナ)
ポート番号が開いていないと(PORTをホストと接続していないとアプリに)アクセスできない
例)80番でNginxにアクセス
ホストとコンテナのポートを紐づける
docker container run -p {ホスト側のポート}:{コンテナ側のポート} {イメージ}
コンテナのネットワーク制御(コンテナ⇔コンテナ)
複数のコンテナを同時に立ち上げることが普通になっている。
コンテナ同士の通信を簡単にしたり、不要なコンテナ同士の通信を防ぐために隔離する
docker network ls NETWORK ID NAME DRIVER SCOPE xxxxxxxxxx bridge bridge local ← 最重要 xxxxxxxxxx host host local xxxxxxxxxx none null local
ブリッジネットワーク
複数のコンテナ同士の通信を橋渡しする
docker container run -itd --rm --name my-nginx-1 nginx docker network inspect {ネットワーク名} # bridge/host/none docker network create my-net docker network ls docker container run -itd --rm --name my-nginx-2 --network {ネットワーク名} {イメージ} docker network inspect my-net
ブリッジネットワーク内で通信をする
Dockerfile FROM ubuntu:22.04 RUN apt update && apt install -y iputils-ping curl CMD ["bash"] # ------------ docker image build -t my-ubuntu . docker container run -itd --name my-ubuntu-1 my-ubuntu # デフォルトでbridgeに所属 docker container run -itd --name my-ubuntu-2 --network my-net my-ubuntu
ブリッジネットワークでの名前解決
※デフォルトのbridgeネットワーク内では使えない
docker container exec -it my-ubuntu-1 bash root@xxx:/# curl http://my-nginx-1 > curl: (6) Could not resolve host: my-nginx-1 # デフォルトbridge NW内だとダメ docker container exec -it my-ubuntu-2 bash > root@xxx:/# curl http://my-nginx-2 <html> <head> <title>Welcome to nginx!</title> <style> ・・・・ <p><em>Thank you for using nginx.</em></p> </body> </html>
ブリッジネットワークの削除
docker network rm {ネットワーク名}
Docker Composeで複数コンテナを扱う
Docker Composeとは?
・多くのDockerコマンドを実行するのは大変
・他人に同じ環境を共有するのが困難
↓
Docker Composeが解決する
/webapi
├ /api
|├ Dockerfile
|├ /src/main/java/com/example/api
| ├ ApiApplication.java
| ├ HelloController.java
├ docker-compose.yml
docker-compose.yml ヤムルにport、network, volume設定を書く
docker compose up # このymlファイルに書かれた通りの条件でコンテナが立ち上がる
コンテナ条件
Custom Bridge
↑↓ ↑↓
8080 → 8080 container → 5432 container ⇔ Volume
spring boot PostgreSQL
api db db-storage
spring initializr(Java)から、APIサーバのイメージを作る

Project:Gradle-Groovy Langage:Java Spring Boot:3.2.5
Project Metadata:Artifact/Name = api Packaging:Jar Java:17
Dependencies:Spring Web, Spring Data JPA, PostgreSQL Driver, H2 Database
APIサーバの動作を定義するJavaファイルを作成
\webapi\api\src\main\java\com\example\api\HelloController.java
package com.example.api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class HelloController { @RequestMapping("/hello") public String hello( @RequestParam String lang ) { return "HELLO"; } }
\webapi\api\Dockerfile
FROM gradle:7 WORKDIR /api COPY . . CMD [ "./gradlew", "bootRun" ]
①まず試しにapiサーバー設定を試してみる
イメージをビルド
docker image build -t api-img . # -t タグ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE api-img latest 3cb713f05d03 25 minutes ago 702MB
コンテナを起動
docker container run -p 8080:8080 --rm api-img # 実験なので--rmつけとく Downloading https://services.gradle.org/distributions/gradle-8.7-bin.zip ............10%.............20%.............30%.............40%............50%.............60%.............70%.............80%.............90%............100% Welcome to Gradle 8.7! Here are the highlights of this release: - Compiling and testing with Java 22 - Cacheable Groovy script compilation - New methods in lazy collection properties For more details see https://docs.gradle.org/8.7/release-notes.html Starting a Gradle Daemon (subsequent builds will be faster) > Task :compileJava > Task :processResources > Task :classes > Task :resolveMainClassName > Task :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.2.5) # 起動した
ブラウザのURLに
http://localhost:8080/api/hello?lang=ja

この内容でAPIサーバを作成しよう
②Docker Composeを使って一気にAPIサーバを起動するコンテナを立ち上げる
/webapi
├ /api
|├ Dockerfile
|├ /src/main/java/com/example/api
| ├ ApiApplication.java
| ├ HelloController.java
├ docker-compose.yml
# webapi 配下にdocker-compose.yml ファイルを作成 version: '3.9' services: api: build: ./api ports: - 8080:8080
これを
docker compose up
することで、
docker image build -t api-img ./api
docker container run –name api -p 8080:8080 api-img
をいっぺんに実行したのと同じ効果が得られる。
↓
localhost:8080/api/hello?lang=今はなんでもいい

同じようにWebAPIが立ち上がった
③Docker Composeを使って一気にDBを起動するコンテナを立ち上げる
/webapi
├ /api
|├ Dockerfile
|├ /src/main/java/com/example/api
| ├ ApiApplication.java
| ├ HelloController.java
├ /db/initdb
| ├ 1-create-greetings.sql
| ├ 2-insert-greetings.sql
├ docker-compose.yml
docker-compose.yml に db: 以下を追記
version: '3.9' services: api: build: ./api ports: - 8080:8080 db: image: postgres:15 ports: - 5432:5432 environment: - POSTGRES_PASSWORD=mypassword - POSTGRES_USER=postgres - POSTGRES_DB=appdb volumes: - db-storage:/var/run/postgresql/data # /var/lib/ではなかった - ./db/initdb:/docker-entrypoint-initdb.d volumes: db-storage:
1-create-greetings.sql
CREATE TABLE greetings ( id SERIAL, lang VARCHAR(255) NOT NULL, text VARCHAR(255) NOT NULL, PRIMARY KEY (id) );
2-insert-greetings.sql
INSERT INTO greetings (lang, text) VALUES ('ja', 'こんにちは'), ('en', 'Hello') ;
docker compose からDBコンテナだけを立ち上げる
docker compose up db -d
DBの中を確認
docker compose exec db bash root@7494e39143b3:/# psql -U postgres psql (15.6 (Debian 15.6-1.pgdg120+2)) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+------------+------------+------------+-----------------+----------------------- appdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres (4 rows) postgres=# \c appdb You are now connected to database "appdb" as user "postgres". appdb=# \dt
一旦、docker composeで作ったコンテナを全て落とす
docker compose down [+] Running 3/3 ✔ Container webapi-db-1 Removed ✔ Container webapi-api-1 Removed ✔ Network webapi_default Removed
④APIコンテナとDBコンテナを接続する
/webapi
├ /api
|├ Dockerfile
|├ /src
| ├ /main
| | ├ /java/com/example/api
| | ├ /entities
| | | ├ GreetingEntity.java
| | ├ ApiApplication.java
| | ├ GreetingRepository.java
| | ├ HelloController.java
| ├ /resources
| ├ application.properties
├ /db/initdb
| ├ 1-create-greetings.sql
| ├ 2-insert-greetings.sql
├ docker-compose.yml
GreetingRepository.java
DBコンテナへ接続するためのレイヤーを作成
package com.example.api; import com.example.api.entities.GreetingEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import jakarta.transaction.Transactional; @Repository @Transactional public interface GreetingRepository extends JpaRepository<GreetingEntity, String> { GreetingEntity findFirstByLang(String lang); /*ここで接続*/ }
/entities/GreetingEntity.java
package com.example.api.entities; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; @Entity @Table(name = "greetings") public class GreetingEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; /* DBテーブルのスキーマ */ public String lang; /* (1-create-greetings.sql) */ public String text; /* と一致させている */ }
HelloController.java 修正
package com.example.api; import com.example.api.entities.GreetingEntity; /*追加*/ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") public class HelloController { @Autowired private GreetingRepository repository; /*インスタンス作成*/ @RequestMapping("/hello") public String hello( @RequestParam String lang ) { GreetingEntity entity = this.repository.findFirstByLang(lang); /*DBからlangの値を取得*/ return entity.text; /*値を返す*/ } }
application.properties 追記
※spring boot全体の環境変数を定義するファイル
spring.application.name=api spring.datasource.url=jdbc:postgresql://db:5432/appdb spring.datasource.username=postgres spring.datasource.password=mypassword spring.datasource.driver-class-name=org.postgresql.driver spring.jpa.hibernate.ddl-auto=none
docker-compose.yml 追記
version: '3.9' services: api: build: ./api ports: - 8080:8080 depends_on: # ここを追記 - db db: image: postgres:15 ports: - 5432:5432 environment: - POSTGRES_PASSWORD=mypassword - POSTGRES_USER=postgres - POSTGRES_DB=appdb volumes: - db-storage:/var/run/postgresql/data # /var/lib/じゃないじゃん! - ./db/initdb:/docker-entrypoint-initdb.d volumes: db-storage:
⑤いよいよ docker compose をリビルド
–build オプションを付けることでイメージの作り直しが行われる
※–buildをつけないと、以前のイメージを使ってしまう為
docker compose up --build
udemy セクション11 実務想定Webアプリ開発体験
docker compose up -d docker compose ps container_name: api - React(gradle) port: 8080 docker compose exec api bash cd /workspace ./gradlew bootRun container_name: web - springboot(Node.js) port: 3000 docker compose exec web bash cd /workspace npm install npm run start
AWSで、GitHubActionsからAWS ECR(DockerHubのAWS版みたいなの), ECSにアクセスできるTokenを発行する

許可するポリシー
AmazonEC2ContainerRegistryPowerUser
AmazonECS_FullAccess

アクセスキーを作成


ECRでプライベートリポジトリの作成

ECSでクラスターの作成


タスク定義
Amazon ECR Public Gallery からnginxのイメージを採用

クラスターの中にサービスを作成