本記事はClaudeと共に作業をした際に結構引っかかったので、設定完了後にClaudeにBlogとしてまとめてもらったものです。
この記事について
Synology NASのContainer Manager(Docker)を使って、家庭内LANにDNSサーバ(Pi-hole)とLDAPサーバ(OpenLDAP)を構築する手順をまとめました。実際のトラブルシューティング経験をもとに、ハマりやすいポイントを明確に回避できるよう解説しています。
目次
前提条件
- Synology DSM 7.2以降
- Container Manager インストール済み
- NASに固定IPアドレスが割り当て済み(本記事では
192.168.0.10を使用) - SSHアクセスが有効になっている
⚠️ 重要:NASのIPアドレスを固定する
DNSサーバのIPが変わるとLAN全体に影響します。必ず固定IPを割り当ててから作業を始めてください。
Pi-hole(DNSサーバ)の構築
ステップ1:フォルダをSSHで作成する
⚠️ ハマりポイント①:フォルダは必ずフルパスで作成する
File Stationで見える/dockerは表示上の名前です。実際のパスは/volume1/dockerです。フルパスを指定しないとPermission deniedエラーが発生します。
SSHでNASにログインして以下を実行します:
sudo mkdir -p /volume1/docker/pihole/etc-pihole
sudo mkdir -p /volume1/docker/pihole/etc-dnsmasq.d
作成確認:
ls /volume1/docker/pihole/
# → etc-pihole etc-dnsmasq.d と表示されればOK
ステップ2:.envファイルを作成する
⚠️ ハマりポイント②:パスワードに
!などの特殊文字を含む場合はYAMLに直接書かない
WEBPASSWORD: 'Password1!'のようにYAMLに直接書くと、!がYAMLやシェルで特殊文字として解釈されパスワードが正しく設定されません。必ず.envファイルに切り出してください。
echo 'WEBPASSWORD=YourPassword1!' > /volume1/docker/pihole/.env
ステップ3:Container Managerでプロジェクトを作成する
Container Manager → 「プロジェクト」→「作成」
| 設定項目 | 入力内容 |
|---|---|
| プロジェクト名 | pihole |
| パス | /volume1/docker/pihole |
| ソース | 「compose.ymlを作成する」を選択 |
以下のcompose.ymlを貼り付けます:
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
ports:
- "192.168.0.10:53:53/tcp"
- "192.168.0.10:53:53/udp"
- "8080:80/tcp"
environment:
TZ: 'Asia/Tokyo'
WEBPASSWORD: ${WEBPASSWORD}
volumes:
- '/volume1/docker/pihole/etc-pihole:/etc/pihole'
- '/volume1/docker/pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
restart: unless-stopped
⚠️ ハマりポイント③:volumesのパスは
/volume1/docker/から始める
/docker/pihole/etc-piholeのように書くとBind mount failed: does not existエラーが発生します。必ず/volume1/docker/から始まるフルパスを指定してください。
⚠️ ハマりポイント④:ポートはNASのIPアドレスにバインドする
"53:53/udp"のように書くと全インターフェースでバインドされます。"192.168.0.10:53:53/udp"のようにLAN側のIPを明示することで、外部からの意図しないアクセスを防げます。
「次へ」→「完了」でコンテナが起動します。
ステップ4:管理画面にアクセスする
http://192.168.0.10:8080/admin
.env に設定したパスワードでログインできれば成功です。
⚠️ ハマりポイント⑤:パスワードでログインできない場合はコンテナ内から直接設定する
.envファイルが正しく読み込まれていない場合があります。その際はSSHから以下のコマンドでパスワードをリセットできます:sudo docker exec pihole pihole -a -p 'NewPassword1!'
ステップ5:カスタムDNSレコードを追加する
管理画面の Local DNS → DNS Records からLAN内の機器に名前を付けられます。
| ドメイン名 | IPアドレス |
|---|---|
nas.home |
192.168.0.10 |
router.home |
192.168.0.1 |
printer.home |
192.168.0.50 |
ℹ️ Pi-holeのバージョンによってメニューの場所が異なります
「Local DNS」が見当たらない場合は以下のURLに直接アクセスしてください:
http://192.168.0.10:8080/admin/dns_records.php
ステップ6:LAN全体にDNSを反映させる
ルーターの管理画面で DHCPサーバのプライマリDNS を 192.168.0.10 に変更します。これでLAN内の全端末が自動的にPi-holeをDNSとして使うようになります。
OpenLDAP(LDAPサーバ)の構築
ステップ1:フォルダを作成する
sudo mkdir -p /volume1/docker/openldap/data
sudo mkdir -p /volume1/docker/openldap/config
⚠️ ハマりポイント⑥:フォルダの所有者をコンテナのUID/GIDに合わせる
osixia/openldapはUID/GID 911 で動作します。所有者が合っていないと起動時にPermission deniedエラーが発生します。
sudo chown -R 911:911 /volume1/docker/openldap/data
sudo chown -R 911:911 /volume1/docker/openldap/config
ステップ2:.envファイルを作成する
echo 'LDAP_ADMIN_PASSWORD=YourPassword1!' > /volume1/docker/openldap/.env
ステップ3:Container Managerで新しいプロジェクトを作成する
⚠️ ハマりポイント⑦:Pi-holeとは別のプロジェクトとして作成する
同じプロジェクトに追加すると管理がしにくくなります。独立したプロジェクトにすることで個別に起動・停止・更新できます。
Container Manager → 「プロジェクト」→「作成」
| 設定項目 | 入力内容 |
|---|---|
| プロジェクト名 | openldap |
| パス | /volume1/docker/openldap |
| ソース | 「compose.ymlを作成する」を選択 |
以下のcompose.ymlを貼り付けます:
services:
openldap:
image: osixia/openldap:latest
container_name: openldap
ports:
- "389:389"
- "636:636"
environment:
LDAP_ORGANISATION: 'test'
LDAP_DOMAIN: 'test.local'
LDAP_ADMIN_PASSWORD: ${LDAP_ADMIN_PASSWORD}
TZ: 'Asia/Tokyo'
volumes:
- '/volume1/docker/openldap/data:/var/lib/ldap'
- '/volume1/docker/openldap/config:/etc/ldap/slapd.d'
networks:
- ldap_network
restart: unless-stopped
phpldapadmin:
image: osixia/phpldapadmin:latest
container_name: phpldapadmin
ports:
- "8081:80"
environment:
PHPLDAPADMIN_LDAP_HOSTS: openldap
PHPLDAPADMIN_HTTPS: 'false'
depends_on:
- openldap
networks:
- ldap_network
restart: unless-stopped
networks:
ldap_network:
driver: bridge
⚠️ ハマりポイント⑧:openldapとphpldapadminは同じnetworkに入れる
同じプロジェクト内でもnetworksの指定がないと別々のネットワークに配置され、phpldapadminからopenldapに接続できません。両サービスに同じネットワーク(ldap_network)を指定することで、コンテナ名(openldap)で名前解決できるようになります。
⚠️ ハマりポイント⑨:bitnami/openldapは使わない
bitnami/openldap:latestはSynology環境でイメージが見つからないエラーが発生することがあります。osixia/openldap:latestの方が安定しています。
ステップ4:phpldapadminにアクセスする
http://192.168.0.10:8081
| 項目 | 値 |
|---|---|
| Login DN | cn=admin,dc=test,dc=local |
| Password |
.env に設定した管理者パスワード |
ステップ5:OUとユーザーを作成する
⚠️ ハマりポイント⑩:osixia/openldapはou=peopleを自動作成しない
bitnami版と異なり、osixia版はOU(組織単位)を自動作成しません。phpldapadminから手動で作成する必要があります。
ou=people の作成:
- 左ツリーの
dc=test,dc=localをクリック - 「Create a child entry」→「Generic: Organisational Unit」
-
peopleと入力 →「Create Object」→「Commit」
同様に ou=groups も作成します。
ユーザーの追加:
- 左ツリーの
ou=peopleをクリック - 「Create a child entry」→「Generic: User Account」
- 必要情報を入力 →「Create Object」→「Commit」
LDAPの動作確認
SSHから確認する
# 管理者で検索
sudo docker exec openldap ldapsearch -x \
-H ldap://localhost:389 \
-b "dc=test,dc=local" \
-D "cn=admin,dc=test,dc=local" \
-w YourPassword1!
# ユーザー認証テスト
sudo docker exec openldap ldapsearch -x \
-H ldap://localhost:389 \
-b "cn=Taro Yamada,ou=people,dc=test,dc=local" \
-D "cn=Taro Yamada,ou=people,dc=test,dc=local" \
-w YourPassword1!
result: 0 Success が返れば認証成功です。
LAN内の別端末から確認する(Linux/Mac)
ldapsearch -x \
-H ldap://192.168.0.10:389 \
-b "cn=Taro Yamada,ou=people,dc=test,dc=local" \
-D "cn=Taro Yamada,ou=people,dc=test,dc=local" \
-w YourPassword1!
よくあるトラブルと解決方法
| エラー | 原因 | 解決方法 |
|---|---|---|
Bind mount failed: does not exist |
volumesのパスが間違っている |
/volume1/docker/ から始まるフルパスを指定する |
Permission denied(フォルダ作成時) |
sudoなしで実行している |
sudo mkdir -p で実行する |
Permission denied(コンテナ起動時) |
フォルダの所有者がコンテナのUID/GIDと一致していない |
sudo chown -R 911:911 で所有者を変更する |
| Pi-holeの管理画面にログインできない | 特殊文字を含むパスワードがYAMLで正しく解釈されていない |
.env ファイルに切り出すか、sudo docker exec pihole pihole -a -p 'パスワード' でリセットする |
Can't contact LDAP server (-1) |
phpldapadminとopenldapが同じnetworkにいない | compose.ymlで両サービスに同じnetworkを指定する |
slapd failed with status 1 |
古いデータが残っていてコンフィグが競合している |
sudo rm -rf /volume1/docker/openldap/data/* でデータを削除してから再起動する |
manifest unknown |
イメージタグが存在しない |
bitnami/openldap の代わりに osixia/openldap:latest を使う |
構成の全体像
[ LAN内の各端末 ]
↓ DNS問い合わせ (ポート53)
[ Pi-hole コンテナ ]
- 管理画面: http://192.168.0.10:8080/admin
- カスタムDNSレコード管理
- 広告ブロック
[ LAN内の各サービス ]
↓ LDAP認証 (ポート389)
[ OpenLDAP コンテナ ]
- phpldapadmin: http://192.168.0.10:8081
- ユーザー/グループ管理
- Base DN: dc=test,dc=local
他サービスとLDAP連携する際の接続情報
| 項目 | 値 |
|---|---|
| サーバ | 192.168.0.10 |
| ポート | 389 |
| Base DN | dc=test,dc=local |
| 管理者DN | cn=admin,dc=test,dc=local |
| ユーザーOU | ou=people,dc=test,dc=local |
| グループOU | ou=groups,dc=test,dc=local |