起動するときに余計なこと考えずに失敗しなくて、
DockerでLaravelを動かす仕組み――nginx・PHP・PostgreSQL・Portainer・WUDの関係
Ubuntu VPS上でLaravelのWebアプリ、データベース、Docker管理画面、更新確認ツールを動かす構成を初心者向けに整理します。Laravelは通常のブラウザから利用でき、PortainerとWUDは管理者だけがブラウザで開ける構成です。
1. 全体構成
インターネット上のブラウザ
│ HTTP / HTTPS
▼
Ubuntu VPS
└─ Docker Engine
├─ nginxコンテナ ─────── 公開窓口
│ │ FastCGI
│ ▼
├─ PHP-FPMコンテナ ──── Laravelを実行
│ │
│ ▼
├─ PostgreSQLコンテナ ─ データを保存
├─ Portainerコンテナ ── Docker管理画面
└─ WUDコンテナ ─────── イメージ更新を確認
Docker Engineは1つだけです。nginx、PHP-FPM、PostgreSQL、Portainer、WUDは、同じDocker Engine上で動く別々のコンテナです。LaravelはPHP-FPMコンテナ内で実行されるアプリケーションです。
2. 各コンテナの役割
| 要素 | 役割 | 外部公開 |
|---|---|---|
| nginx | ブラウザからのアクセスを受け、PHP処理をPHP-FPMへ渡す | 80・443番 |
| PHP-FPM | PHPを実行し、Laravelの処理結果をnginxへ返す | 公開しない |
| Laravel | 画面表示、ログイン、検索、データ処理などWebアプリ本体 | nginx経由 |
| PostgreSQL | Laravelが使うデータベース | 公開しない |
| Portainer CE | DockerをGUIで確認・管理する | localhostのみ |
| WUD | Dockerイメージの更新を検出する | localhostのみ |
3. ブラウザからアクセスする流れ
- ブラウザでLaravel用ドメインを開く
- VPSの80番または443番へ接続する
- nginxがリクエストを受ける
- PHP処理をPHP-FPMへ渡す
- Laravelが必要に応じてPostgreSQLへ接続する
- 処理結果がnginx経由でブラウザへ戻る
https://example.com
↓
VPSの443番
↓
nginx
↓
php:9000
↓
Laravel
↓
postgres:5432
4. コンテナ同士の通信
同じDockerネットワークに接続したコンテナは、Composeのサービス名で通信できます。
- nginxからPHPへ:
php:9000 - LaravelからPostgreSQLへ:
postgres:5432
LaravelのDB_HOSTにはpostgresを指定します。PHPコンテナ内のlocalhostはPHPコンテナ自身を意味するためです。
5. 推奨ディレクトリ構成
/srv/
├─ laravel-app/
│ ├─ compose.yml
│ ├─ .env
│ ├─ docker/
│ │ ├─ nginx/default.conf
│ │ └─ php/Dockerfile
│ └─ src/
│ ├─ artisan
│ ├─ app/
│ ├─ public/
│ └─ storage/
└─ docker-management/
└─ compose.yml
Laravel側と管理ツール側を別のComposeプロジェクトに分けます。それぞれでdocker compose up -dを実行すると、同じDocker Engine上へ追加されます。
6. Laravel側のCompose例
/srv/laravel-app/compose.ymlの基本例です。
name: laravel-app
services:
nginx:
image: nginx:alpine
container_name: laravel-nginx
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./src:/var/www/html:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
networks:
- app-network
php:
build:
context: ./docker/php
container_name: laravel-php
restart: unless-stopped
working_dir: /var/www/html
volumes:
- ./src:/var/www/html
environment:
APP_ENV: production
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: laravel
DB_USERNAME: laravel
DB_PASSWORD: ${DB_PASSWORD}
depends_on:
postgres:
condition: service_healthy
networks:
- app-network
postgres:
image: postgres:16-alpine
container_name: laravel-postgres
restart: unless-stopped
environment:
POSTGRES_DB: laravel
POSTGRES_USER: laravel
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U laravel -d laravel"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
volumes:
postgres_data:
networks:
app-network:
PostgreSQLにはportsを書いていないため、VPS外部から5432番へ直接接続できません。Composeと同じディレクトリの.envには、DB_PASSWORD=長いランダムなパスワードを設定します。
7. Portainer・WUD側のCompose例
/srv/docker-management/compose.ymlの例です。
name: docker-management
services:
portainer:
image: portainer/portainer-ce:2.39.6
container_name: portainer
restart: unless-stopped
ports:
- "127.0.0.1:9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
wud:
image: getwud/wud:8.3.1
container_name: wud
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
TZ: Asia/Tokyo
WUD_WATCHER_LOCAL_CRON: "0 6 * * *"
WUD_WATCHER_LOCAL_WATCHBYDEFAULT: "true"
WUD_WATCHER_LOCAL_WATCHEVENTS: "false"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- wud_data:/store
volumes:
portainer_data:
wud_data:
PortainerとWUDはVPSの127.0.0.1だけに公開します。インターネットから直接は開けません。
8. nginx設定例
/srv/laravel-app/docker/nginx/default.confの基本例です。
server {
listen 80;
server_name example.com;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
fastcgi_pass php:9000;により、PHP処理をphpサービスへ渡します。
9. 起動方法
Laravel側
cd /srv/laravel-app
docker compose config
docker compose build
docker compose up -d
docker compose ps
管理ツール側
cd /srv/docker-management
docker compose config
docker compose pull
docker compose up -d
docker compose ps
全体は次で確認できます。
docker ps
docker compose ls
10. 管理画面へのブラウザアクセス
WindowsのPowerShellからSSHトンネルを開きます。
ssh -L 9443:127.0.0.1:9443 -L 3000:127.0.0.1:3000 ユーザー名@VPSのIPアドレス
SSH接続を開いたまま、ブラウザで次を開きます。
- Laravel:
https://取得したドメイン - Portainer:
https://localhost:9443 - WUD:
http://localhost:3000
Laravelは一般利用者向けに公開し、PortainerとWUDはSSH接続できる管理者だけが利用します。
11. 更新とデータ管理
| 対象 | 管理方法 | 更新方法 |
|---|---|---|
| Ubuntu | APT | セキュリティ更新は自動、通常更新は手動 |
| Docker Engine | APT | メンテナンス時間に手動 |
| nginx・PHP・PostgreSQL | WUDで検出 | Composeから手動 |
| Laravel | Gitなど | コード配備、Composer、マイグレーション |
| コンテナの状態 | Portainer | ログと稼働状態を確認 |
cd /srv/laravel-app
docker compose pull
docker compose build --pull php
docker compose up -d
docker compose ps
docker compose logs --tail 100
PostgreSQLデータはpostgres_dataボリューム、Portainer設定はportainer_data、WUD履歴はwud_dataに保存されます。
docker compose down -vはボリュームを削除するため、通常は使いません。主な確認コマンド
docker ps
docker compose ls
docker system df
df -h /
cd /srv/laravel-app
docker compose logs --tail 100 nginx
docker compose logs --tail 100 php
docker compose logs --tail 100 postgres
docker exec laravel-nginx nginx -t
docker compose exec php php artisan about
12. まとめ
- nginxがブラウザからのアクセスを受ける
- PHP-FPMがLaravelを実行する
- LaravelがPostgreSQLへデータを保存する
- PortainerがDocker全体をGUIで見えるようにする
- WUDがコンテナイメージの更新を確認する
Laravelはドメインから通常のブラウザで利用できます。PortainerとWUDはlocalhostだけに公開し、SSHトンネル経由でブラウザ表示します。これにより、Webアプリの公開とDocker管理画面の保護を両立できます。
Dockerでは、稼働中のコンテナを直接作り込むより、Composeファイル、Dockerfile、nginx設定、Laravelソース、環境変数を設計図として保ち、同じ構成を再現できる状態にすることが重要です。

