どうも、ケニー(tsujikenzo)です。このシリーズでは、Docker入門をお届けしています。
前回は「Docker Compose前編」で、PythonアプリとRedisの、2つのDockerイメージを起動しました。
片方のターミナルでredisサーバーを立ち上げて、別のターミナルからpingを打つ、という連携を確認しました。
今回は、「Docker Compose中編」をお届けします。
PythonからRedisにアクセスする
前回は、重複URL(同じURLに何度もアクセスすること)など気にせず、スクレイピングをぶん回していました。
ここからは、「PythonアプリがRedisを使って、アクセスしたURLの重複を高速にチェックする」という機能を実装してみましょう。
まず、scraper.pyを以下のように修正します。
# scraper.py
```python
import requests
from bs4 import BeautifulSoup
import redis
def smart_scraper():
# Redisサーバーに接続(Composeならサービス名でOK)
r = redis.Redis(host='redis', port=6379, db=0)
response = requests.get("https://books.toscrape.com/")
soup = BeautifulSoup(response.text, 'html.parser')
books = soup.find_all('article', class_='product_pod')
for book in books:
title = book.h3.a['title']
detail_url = book.h3.a['href']
# 既に取得済みかどうか、Redisでチェック
if r.sismember('visited_urls', detail_url):
print(f"スキップ: 既に取得済み {title}")
continue
print(f"取得中...: {title}")
# 取得済みリストに登録
r.sadd('visited_urls', detail_url)
# ファイルに保存
with open("results.csv", "a") as f:
f.write(f"{title}\n")
if __name__ == "__main__":
smart_scraper()
```そして、「redis」というライブラリをPythonアプリに追加します。DockerfileのRUN pip installにredisを加えます。
```dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY scraper.py .
RUN pip install requests beautifulsoup4 redis
CMD ["python", "scraper.py"]
```Redisを起動する(復習)
それでは、「Redisを使うPythonアプリ」と「Redis」の両方を、Docker上(別々のターミナルを使用)起動してみましょう。
今回は「1つずつ docker run で起動」してみます。
- まず新しいターミナルを起動します。(画面省略)
- Redisが起動しているか確認します。
docker psわたしは、2日前から起動していたようです。

もし起動していない方は、前回のブログを読んで起動してください。
Pythonアプリを起動する(別ターミナル)
- Redisとは別で、新しいターミナルを起動します。(画面省略)
- さきほど作成したDockerfileからイメージを作ります。
docker build -t scraper-app .
次に、そのイメージを実行します。
docker run --rm --name scraper-app --network bridge scraper-appそうすると、エラーメッセージが出て、処理が終了すると思います。これは「host=’redis’ が見つからない」という意味です。

Pythonアプリ側からすると、突然出てきた「host=’redis’って何?」という状態です。「redis」というホスト名は、同じDockerネットワーク内でしか通らないからです。

同じネットワーク内に載せて起動する
まず、Docker上にネットワークを作成します。
docker network create app-netそして、「test-redis」ではなく、「redis」という名前で新しくコンテナを作成/起動します。その際に、オプションとしてネットワークを指定します。
docker run --rm -d --name redis --network app-net redis:7最後に、Pythonアプリを実行します。
docker run --rm --name scraper-app --network app-net -v "${PWD}:/app" scraper-app無事、取得できました。

そのまま、もう一度、Pythonアプリを実行してみましょう。
一度アクセスしたURLは、Redis上のデータベースに書き込まれているので、スキップされます。高速です。便利ですね。

しかしながら、このように docker run で1つずつコンテナを起動したり、ネットワークを作成するのは面倒ですよね。そこで登場するのが Docker Compose です。
Docker Composeとは
Docker Composeは、複数コンテナの起動やネットワーク設定を 1つのYAMLファイルにまとめて管理 できる仕組みです。
これまで手動でやっていた「Redis起動 → アプリ起動 → ネットワーク接続」を、1コマンドでまとめて起動できます。
実際にやってみましょう。
まず、すべてのコンテナを停止したいので、すべてのコンテナを確認しましょう。(復習)
docker ps -aコンテナを停止しましょう。
#個別のコンテナを停止
docker stop コンテナ名
#すべてのコンテナを停止
docker stop $(docker ps -q)docker-compose.ymlを作る
まず、同じプロジェクト内(今回はデスクトップです)に「docker-compose.yml」ファイルを作ります。メモ帳からで構いません。
services:
app:
build: .
volumes:
- .:/app
redis:
image: redis:7
ports:
- "6379:6379"docker compose up で起動
ymlファイルを読み込んで、ymlファイルの中に書かれているサービスをビルド(必要なら)して起動するのが、docker composeコマンドです。

ターミナルで実行しましょう。
docker compose up --buildデスクトップにcsvファイルが出力されました。

Docker Compose up内で処理を止める
docker compose up 内の処理を止めるには、キーボードで「Ctrl + C」を押下します。ログの追跡を止めつつ、起動中のコンテナにも停止シグナルを送ります。
docker compose down で停止
停止するときは以下です。
docker compose downまとめ
以上で、「ノンプログラマーのためのDocker入門 Docker Compose中編」をお送りしました。
次回は、最終回です。お楽しみに。



