プロジェクトをDockerで渡す目的

状況:あなたが開発したプロジェクトを、チームメンバーや他の開発者に渡して、彼らの環境でも動かせるようにしたい。

目的:相手が「Docker本体がインストールされているPC」さえあれば、環境構築なしですぐにプロジェクトを動かせるようにする。

💡 何を渡すのか?

以下のファイルをGitリポジトリに含めて渡します:

  • Dockerfile:このプロジェクトをどう動かすかの設計書
  • docker-compose.yml:複数のコンテナをまとめて起動する指示書
  • .env.example:環境変数のサンプル(実際の値は含めない)
  • README.md:プロジェクトの説明と使い方
  • プロジェクトのコード:実際のアプリケーション

重要:Docker本体は渡しません。相手のPCにインストールされている前提です。

基本的な流れ

プロジェクトをDockerで渡すには、以下の手順で進めます。

ステップ1:Dockerfileを作成

状況:あなたのプロジェクトがNode.js、Python、PHPなどで作られている。

やること:プロジェクトのルートディレクトリにDockerfileという名前のファイルを作成します。

Node.jsプロジェクトの例

# ベースとなるイメージを指定
FROM node:18

# 作業ディレクトリを設定
WORKDIR /app

# package.jsonとpackage-lock.jsonをコピー
COPY package*.json ./

# 依存関係をインストール
RUN npm install

# アプリケーションのコードをコピー
COPY . .

# ポートを公開
EXPOSE 3000

# アプリケーションを起動
CMD ["npm", "start"]

💡 各行の意味

  • FROM:ベースとなるイメージ。Node.jsバージョン18を使用
  • WORKDIR:コンテナ内の作業フォルダ
  • COPY:ファイルをコンテナにコピー
  • RUN:コマンドを実行(ビルド時に1回だけ)
  • EXPOSE:使用するポート番号を宣言
  • CMD:コンテナ起動時に実行するコマンド

Pythonプロジェクトの例

FROM python:3.11

WORKDIR /app

COPY requirements.txt .

RUN pip install --break-system-packages -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

PHPプロジェクトの例

FROM php:8.2-apache

WORKDIR /var/www/html

COPY . .

RUN chown -R www-data:www-data /var/www/html

EXPOSE 80

CMD ["apache2-foreground"]

ステップ2:docker-compose.ymlを作成

状況:アプリケーションとデータベースなど、複数のコンテナを使う場合。

やること:プロジェクトのルートにdocker-compose.ymlを作成します。

例1:Node.js + PostgreSQL

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/myapp
    depends_on:
      - db
    volumes:
      - .:/app
      - /app/node_modules

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

例2:React(開発環境)

状況:Reactアプリケーションの開発環境を構築したい。

version: '3.8'

services:
  react-app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - CHOKIDAR_USEPOLLING=true
    stdin_open: true
    tty: true

Dockerfile:

FROM node:18

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

例3:Laravel + MySQL + phpMyAdmin

状況:LaravelアプリケーションをMySQL、phpMyAdminと一緒に動かしたい。

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
    depends_on:
      - db
    environment:
      - DB_HOST=db
      - DB_DATABASE=laravel
      - DB_USERNAME=laravel_user
      - DB_PASSWORD=secret

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel_user
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: root_secret
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - "3306:3306"

  phpmyadmin:
    image: phpmyadmin:latest
    ports:
      - "8080:80"
    environment:
      PMA_HOST: db
      PMA_USER: root
      PMA_PASSWORD: root_secret
    depends_on:
      - db

volumes:
  db-data:

Dockerfile:

FROM php:8.2-fpm

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

COPY . .

RUN composer install

RUN chown -R www-data:www-data /var/www/html

EXPOSE 8000

CMD php artisan serve --host=0.0.0.0 --port=8000

例4:WordPress + MySQL

状況:WordPressサイトを構築したい。

version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp-content:/var/www/html/wp-content
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_ROOT_PASSWORD: root_password
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:

例5:Django + PostgreSQL + Redis

状況:Djangoアプリケーションにキャッシュ(Redis)を追加したい。

version: '3.8'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    environment:
      - DATABASE_URL=postgresql://django:password@db:5432/djangodb
      - REDIS_URL=redis://redis:6379/0
    depends_on:
      - db
      - redis

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: djangodb
      POSTGRES_USER: django
      POSTGRES_PASSWORD: password
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres-data:

例6:Next.js + PostgreSQL(本番環境)

状況:Next.jsアプリケーションを本番環境用にビルドして動かしたい。

version: '3.8'

services:
  nextjs:
    build:
      context: .
      dockerfile: Dockerfile.prod
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://nextuser:nextpass@db:5432/nextdb
      - NODE_ENV=production
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: nextdb
      POSTGRES_USER: nextuser
      POSTGRES_PASSWORD: nextpass
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:

Dockerfile.prod:

FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

FROM node:18-alpine AS runner

WORKDIR /app

COPY --from=builder /app/package*.json ./
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000

CMD ["npm", "start"]

例7:NGINX + PHP-FPM + MySQL

状況:本格的なPHPアプリケーションを高速に動かしたい。

NGINXとは:高速なWebサーバー。Apacheよりもメモリ使用量が少なく、大量のアクセスに強い。

PHP-FPMとは:PHPを高速に実行するための仕組み。NGINXはPHPを直接実行できないので、PHP-FPMと組み合わせて使います。

💡 なぜこの構成を使うのか?

Apache+PHP:簡単だが、アクセスが多いと遅くなる

NGINX+PHP-FPM:設定は複雑だが、高速で本番環境向き

初心者は例3のLaravel(Apache)で十分です。アクセスが増えてきたらNGINXを検討しましょう。

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./public:/var/www/html
    depends_on:
      - php

  php:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./public:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data:

💡 各項目の意味

  • services:起動するコンテナの定義
  • build:Dockerfileからイメージをビルド(. は現在のディレクトリ)
  • image:Docker Hubから取得するイメージ
  • ports:ホスト:コンテナのポートマッピング
  • environment:環境変数の設定
  • depends_on:起動順序の制御
  • volumes:データの永続化とファイル共有

⚠️ パスワードの扱い

docker-compose.ymlに直接パスワードを書くのは開発環境のみ。本番環境では環境変数や.envファイルを使います。

ステップ3:.envファイルの準備

状況:APIキーやパスワードなど、機密情報を含む環境変数がある。

やること:

  1. .env.exampleファイルを作成(サンプル値を記載)
  2. .gitignore.envを追加(実際の値はGitにコミットしない)

.env.exampleの例

# データベース設定
DB_HOST=db
DB_PORT=5432
DB_USER=your_username
DB_PASSWORD=your_password
DB_NAME=your_database

# API設定
API_KEY=your_api_key_here
API_SECRET=your_api_secret_here

# アプリケーション設定
PORT=3000
NODE_ENV=development

.gitignoreに追加

.env
node_modules/
*.log

💡 なぜ.env.exampleを作るのか?

理由:プロジェクトを受け取った人が「どんな環境変数が必要か」を知るため。

使い方:受け取った人はcp .env.example .envでコピーして、実際の値を設定します。

ステップ4:docker-compose.ymlで.envを使う

状況:環境変数を外部ファイル(.env)から読み込みたい。

やること:docker-compose.ymlを以下のように修正します。

version: '3.8'

services:
  web:
    build: .
    ports:
      - "${PORT}:3000"
    environment:
      - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@db:${DB_PORT}/${DB_NAME}
      - API_KEY=${API_KEY}
    env_file:
      - .env
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

ステップ5:README.mdを作成

状況:プロジェクトを受け取った人が使い方を理解できるようにする。

やること:最低限、以下の情報を含むREADME.mdを作成します。

README.mdのテンプレート

# プロジェクト名

## 概要
このプロジェクトの説明

## 前提条件
- Docker Desktop がインストールされていること
- Gitがインストールされていること

## セットアップ手順

1. リポジトリをクローン
```bash
git clone https://github.com/username/project-name.git
cd project-name
```

2. 環境変数を設定
```bash
cp .env.example .env
```
.envファイルを開いて、必要な値を設定してください。

3. Dockerコンテナを起動
```bash
docker-compose up
```

4. ブラウザでアクセス
```
http://localhost:3000
```

## 使い方
- 管理画面: http://localhost:3000/admin
- API: http://localhost:3000/api

## トラブルシューティング

### ポートが使用中の場合
.envファイルのPORTを変更してください。

### データベース接続エラー
コンテナを再起動してください:
```bash
docker-compose down
docker-compose up
```

💡 README.mdに書くべきこと

  • プロジェクトの概要
  • 前提条件(Docker Desktopのインストールなど)
  • セットアップ手順(コピペで実行できるコマンド)
  • アクセスURL(ポート番号含む)
  • よくあるエラーと解決方法

よくある問題と対処法

ファイルの変更がコンテナに反映されない

症状:コードを修正しても、ブラウザで確認すると古いままになっている。

原因:volumesの設定がないため、ファイルがコンテナにコピーされたまま。

対処法:docker-compose.ymlにvolumesを追加します。

services:
  web:
    build: .
    volumes:
      - .:/app  # 現在のディレクトリをコンテナの/appにマウント
      - /app/node_modules  # node_modulesはコンテナ内のものを使う

データベースのデータが消える

症状:docker-compose downすると、登録したデータが消えてしまう。

原因:volumesでデータを永続化していない。

対処法:volumesを設定します。

services:
  db:
    image: postgres:15
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:  # 名前付きvolumeを定義

コンテナのビルドが遅い

症状:docker-compose up --buildが毎回時間がかかる。

原因:キャッシュが効いていない、またはCOPYの順序が悪い。

対処法:依存関係のファイルを先にCOPYします。

# 悪い例
COPY . .
RUN npm install

# 良い例
COPY package*.json ./  # 依存関係ファイルだけ先にコピー
RUN npm install        # キャッシュが効く
COPY . .              # その後、アプリケーションコードをコピー

他の人のPCで動かない

症状:自分のPCでは動くのに、チームメンバーのPCで動かない。

原因:環境依存のパスやポート番号をハードコードしている。

対処法:

  • 絶対パスではなく相対パスを使う
  • ポート番号は環境変数で設定可能にする
  • OSに依存する設定を避ける

チェックリスト

プロジェクトを渡す前に、以下を確認してください。

✓ Dockerfileがある

プロジェクトのルートディレクトリに配置されている

✓ docker-compose.ymlがある

すべてのサービスが定義されている

✓ .env.exampleがある

必要な環境変数がすべて記載されている

✓ .gitignoreが設定されている

.envファイルがGitにコミットされないようになっている

✓ README.mdがある

セットアップ手順が明確に書かれている

✓ 自分のPCで動作確認済み

クリーンな状態から起動できることを確認

💡 動作確認の方法

一度コンテナとイメージをすべて削除してから、改めて起動してみましょう:

docker-compose down -v
docker-compose up --build

これで正常に起動すれば、他の人も同じように起動できるはずです。