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のイメージを採用

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