2026年5月24日

2026年5月24日

ポート80/443の競合を解消する方法(Address already in use の原因と直し方)

Nginx や Apache が「Address already in use」で起動しないときは、ポート80(HTTP)や443(HTTPS)を別のプロセスがすでに使っています。直し方は、エラーメッセージで競合しているポートとアドレスを確かめ、ss や lsof で「誰が使っているか」を特定し、そのプロセスを止めるか、どちらかの待ち受けポートを変えることです。この記事では、症状の読み方から、よくある原因を可能性の高い順に、確認方法と直し方をあわせて説明します。

どんな症状が出るのか

ポートの競合は、Webサーバーの起動や再起動のタイミングで表面化します。代表的なエラーは次のようなものです。

# Nginx(/var/log/nginx/error.log や journalctl に出る)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)

# Apache
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
no listening sockets available, shutting down

ポイントは「98: Address already in use」という部分です。これは「そのアドレスとポートの組み合わせを、すでに別のソケットが待ち受けている」という意味で、設定ファイルの書き方の誤りとは別の問題です。

似たエラーに「13: Permission denied」があります。こちらは競合ではなく、一般ユーザーの権限で1024番未満のポートを開こうとした場合や、SELinux がポートの割り当てを拒否した場合に出ます。番号が98か13かで、調べる方向が変わるので最初に見分けてください。

エラーメッセージは次のコマンドで確認できます。

sudo systemctl status nginx      # Apache なら apache2(Debian/Ubuntu)または httpd(RHEL系)
sudo journalctl -u nginx -n 50 --no-pager
sudo nginx -t                    # 設定ファイルの構文チェック

ステップ1:ポートを使っているプロセスを特定する

まず、80番と443番を誰が待ち受けているかを調べます。ss はほとんどのLinuxに標準で入っています。

# 80番・443番で LISTEN しているプロセスを表示する(sudo を付けないとプロセス名が見えない)
sudo ss -ltnp '( sport = :80 or sport = :443 )'

# lsof が入っていれば、こちらでも確認できる
sudo lsof -nP -iTCP:80 -sTCP:LISTEN
sudo lsof -nP -iTCP:443 -sTCP:LISTEN

出力の users:(("apache2",pid=1234,fd=4)) のような部分に、プロセス名とPIDが表示されます。0.0.0.0:80 はすべてのIPv4アドレス、[::]:80 や *:80 はIPv6(環境によってはIPv4も含む)での待ち受けです。

プロセス名がわかったら、それがどのサービスに属しているかを確認します。

ps -o pid,ppid,user,cmd -p 1234
systemctl status 1234   # PID を渡すと、そのプロセスを起動した systemd のユニットがわかる

ここで見つかったプロセスが、次に説明する原因のどれに当てはまるかを見ていきます。

ステップ2:原因を可能性の高い順に確認する

原因1:Apache と Nginx が両方インストールされ、両方が80番を使おうとしている

もっとも多いのがこのパターンです。Debian や Ubuntu では、apache2 パッケージを入れると自動でサービスが起動し、80番を使います。あとから Nginx を入れたり、PHP 関連のパッケージの依存で Apache が入ったりすると、Nginx が起動できなくなります。

どちらか一方だけを使うなら、使わない方を停止し、自動起動も無効にします。

# Apache を止めて、再起動後も起動しないようにする(RHEL系はサービス名が httpd)
sudo systemctl disable --now apache2

# そのうえで Nginx を起動
sudo systemctl start nginx

両方を使いたい構成(Nginx を前段のリバースプロキシにし、裏で Apache が PHP を処理する、など)では、外向きの80/443は Nginx だけが持ち、Apache は別のポート(例:8080)やローカルアドレスだけで待ち受けるように変えます。Debian/Ubuntu の Apache なら /etc/apache2/ports.conf の Listen と、各バーチャルホストの <VirtualHost> のポートの両方を変える必要があります。片方だけ変えると、Apache が起動しないか、意図しないバーチャルホストが応答します。

# /etc/apache2/ports.conf(例:ローカルの8080番だけで待ち受ける)
Listen 127.0.0.1:8080

# /etc/apache2/sites-available/example.conf
<VirtualHost 127.0.0.1:8080>
    ServerName example.com
    DocumentRoot /var/www/example
</VirtualHost>

Apache 側の ports.conf には、SSLモジュールが有効なときに443番を待ち受ける設定も含まれていることがあります。Nginx でHTTPSを終端するなら、Apache で mod_ssl を使う必要がないか確認し、443番の Listen も残っていないかを見てください。

原因2:古い Nginx(または Apache)のプロセスが残っている

systemd を通さずに nginx コマンドを直接実行して起動した場合や、設定変更の途中で起動に失敗した場合に、古いマスタープロセスが残っていることがあります。この状態で systemctl start nginx を実行すると、自分自身の古いプロセスとポートが競合します。

ステップ1でプロセス名が nginx なのにサービスが「failed」になっている場合はこれを疑います。

# 残っている nginx プロセスを確認
ps -ef | grep [n]ginx

# まずは正常な停止を試みる
sudo nginx -s quit

# それでも残る場合だけ、マスタープロセスの PID を指定して停止する
sudo kill 1234

# systemd 経由で起動し直す
sudo systemctl start nginx

kill -9 で強制終了するのは、通常の停止で終わらない場合の最後の手段にとどめます。以後は起動・停止・再読み込みを systemctl に統一しておくと、同じ問題が起こりにくくなります。

原因3:Docker などのコンテナが80/443を公開している

Docker で -p 80:80 や ports: - "443:443" を指定したコンテナが動いていると、ホスト側の80/443が使われます。ステップ1でプロセス名が docker-proxy と表示される場合や、何も表示されないのに bind に失敗する場合は、コンテナを確認します。

docker ps --format 'table {{.Names}}\t{{.Ports}}'

ホストの Nginx とコンテナの Web サーバーを同時に使うなら、コンテナ側は 127.0.0.1:8080:80 のようにローカルの別ポートに公開し、ホストの Nginx からリバースプロキシで転送する構成にするのが一般的です。逆に、コンテナの中のリバースプロキシ(Traefik や Nginx のコンテナなど)に80/443を任せるなら、ホストの Nginx は止めます。

原因4:Certbot の standalone モードが80番を使おうとしている

Let's Encrypt の証明書を Certbot の --standalone で取得・更新している場合、Certbot が一時的に自前のWebサーバーを80番で起動します。すでに Nginx や Apache が80番を使っていると、「Could not bind TCP port 80 because it is already in use」のようなエラーで更新に失敗します。普段は動いているのに、証明書の更新時だけ失敗するのが特徴です。

Webサーバーが動いているなら、standalone ではなく、Webサーバーと連携する方法に切り替えるのが安定します。

# Nginx と連携する方法(python3-certbot-nginx などのプラグインが必要)
sudo certbot --nginx -d example.com

# 公開ディレクトリにファイルを置いて認証する方法
sudo certbot certonly --webroot -w /var/www/example -d example.com

# 更新のテスト(実際の証明書は変わらない)
sudo certbot renew --dry-run

どうしても standalone を使う場合は、--pre-hook "systemctl stop nginx" と --post-hook "systemctl start nginx" で、更新の前後にWebサーバーを止める方法もあります。ただし更新のたびに短時間サイトが止まるので、ほかの方法が使えないときの選択肢です。

原因5:設定ファイルの中で同じポートを重複して待ち受けている

別のプロセスがいないのに起動できない場合は、設定の重複を疑います。

  • Apache で Listen 80 が ports.conf とほかの設定ファイルの両方に書かれている
  • Nginx で、あるアドレスに listen 443 ssl を書き、別のファイルで同じアドレスに異なるオプション(reuseport や ipv6only など)付きの listen を書いている

Nginx の場合、オプションの重複は duplicate listen options というエラーになります。設定全体を一度に表示して、listen の行を洗い出すと見つけやすくなります。

# Nginx:読み込まれる設定をすべて表示して listen を抜き出す
sudo nginx -T 2>/dev/null | grep -n 'listen'

# Apache:Listen の重複を探す(Debian/Ubuntu の場合)
grep -rn '^\s*Listen' /etc/apache2/

また、sites-enabled に同じ設定ファイルのコピー(example.conf.bak など)が置かれていて、それも読み込まれているケースもよくあります。Nginx は include の指定によっては拡張子に関係なく読み込むので、バックアップは別のディレクトリに置いてください。

原因6:ほかのWebサーバーやパネル製品が動いている

Caddy、lighttpd、Node.js のアプリ、サーバー管理パネル付属のWebサーバーなど、インストールした覚えの薄いソフトが80/443を使っていることもあります。ステップ1で表示されたプロセス名をもとに、systemctl status <PID> でどのサービスかを確かめ、必要なものかどうかを判断してから止めます。管理パネルが自前でWebサーバーを管理している場合は、手動で止めるとパネル側の設定と食い違うことがあるので、パネルのドキュメントに沿って変更してください。

直したあとの確認

プロセスを止めたり設定を変えたりしたら、次の順に確認します。

sudo nginx -t && sudo systemctl restart nginx
sudo ss -ltnp '( sport = :80 or sport = :443 )'
curl -I http://example.com/
curl -I https://example.com/

ss の出力で、80/443を待ち受けているのが意図したプロセスだけになっていれば解消です。あわせて、サーバーを再起動しても同じ状態になるか(止めたはずのサービスが自動起動しないか)を、メンテナンスの時間帯に一度確かめておくと安心です。

なお、ポートを待ち受けているのにブラウザから接続できない場合は、競合ではなくファイアウォールやクラウドのセキュリティグループで遮断されている可能性があります。その場合はOS側(ufw、firewalld など)とクラウド側の両方で、80/443の受信が許可されているかを確認してください。

作業時の注意

本番サーバーでWebサーバーを止めると、その間はサイトが表示されません。作業はアクセスの少ない時間帯に行い、設定ファイルを変更する前には元のファイルをコピーしておきます。各ソフトのサービス名や設定ファイルの場所は、ディストリビューションやバージョンによって異なることがあるので(2026年10月現在)、手元の環境のパスに読み替えてください。

まとめ

  • 「98: Address already in use」は、80/443を別のソケットがすでに待ち受けていることを示します。「13: Permission denied」は権限やSELinuxの問題で、別物です
  • sudo ss -ltnp や lsof で、ポートを使っているプロセスとサービスを特定します
  • 多い原因は、Apache と Nginx の同居、古いプロセスの残り、Docker の公開ポート、Certbot の standalone モード、設定の重複の順です
  • 両方のWebサーバーを使うなら、外向きの80/443は一方だけが持ち、もう一方はローカルの別ポートで待ち受けます
  • 直したら ss と curl で確認し、再起動後も同じ状態になるかを確かめます

お気軽にご相談ください

お見積りへ お問い合わせへ
▲