Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】viteのreactアプリをdockerで立ち上げた後にローカルで起動しようとすると権限エラーが出る

2025年09月28日に「Qiita」が公開したITニュース「viteのreactアプリをdockerで立ち上げた後にローカルで起動しようとすると権限エラーが出る」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

DockerでViteとReactのアプリを動かした後、ローカルで実行しようとすると権限エラーが出る問題について、その原因と解決策を解説。Dockerコンテナとホスト間のファイルアクセス権限の不一致が主な原因で、システムエンジニアを目指す初心者が知っておくべきトラブルシューティングだ。

ITニュース解説

Webアプリケーション開発において、開発環境を効率的に管理するためにDockerを利用する場面は多い。Dockerはアプリケーションとその実行に必要なものをまとめて「コンテナ」という独立した環境で動かす技術であり、開発者のPC環境(ホスト環境と呼ぶ)に依存せずに同じ動作を再現できる利点がある。しかし、このDockerの便利さの裏側で、しばしば開発者を悩ませる問題の一つが「ファイル権限エラー」だ。特に、DockerでReactアプリケーション(Viteのようなビルドツールを使用する場合)を起動した後、同じプロジェクトファイルをホスト環境で編集しようとすると、アクセス権限がないというエラーに遭遇することがある。これはなぜ起こり、どのように解決すれば良いのだろうか。

このエラーの根本原因は、Dockerコンテナ内部とホスト環境との間で、ファイルやディレクトリの「所有者」が異なることにある。LinuxなどのUnix系OSでは、ファイルやディレクトリには必ず所有者(ユーザー)とグループ、そしてそれらに対する読み取り、書き込み、実行のアクセス権限が設定されている。

Dockerコンテナ内でnpm installのようなコマンドを実行すると、アプリケーションの依存関係がnode_modulesディレクトリとしてコンテナ内部に作成される。このとき、これらのファイルの所有者は、特に指定がなければコンテナ内部のrootユーザー(最高権限を持つユーザー)となることが多い。なぜなら、多くのDockerfileはrootユーザーでコマンドを実行するように構成されているためだ。

一方で、あなたの開発用PC(ホスト環境)で普段利用しているユーザーは、rootユーザーではない一般ユーザーであることがほとんどだろう。このホストの一般ユーザーが、Dockerコンテナのrootユーザーが所有するファイルやディレクトリにアクセスしようとすると、システムは「所有者が異なるため、書き込みや削除などの操作は許可しない」と判断し、権限エラーとして処理する。特に、Docker Volumeを使ってホストとコンテナ間でファイルを共有している場合にこの問題が顕著に現れる。Docker Volumeはホストとコンテナ間で同じディレクトリを共有する仕組みだが、共有されるファイルの実体はホストのファイルシステム上に存在し、その所有権はコンテナ内部での操作によって変更されてしまうことがあるのだ。

この問題に対する一つの解決策は、npm installなどのファイル生成後に、明示的にファイルの所有権をホストのユーザーに合わせる方法だ。JavaScriptプロジェクトでは、package.jsonファイルに定義できるscriptsセクションにpostinstallフックという機能がある。これはnpm installが完了した直後に自動的に実行されるスクリプトだ。

ここにchownコマンド(change ownerの略で、ファイルやディレクトリの所有者を変更するコマンド)を設定することで、node_modulesディレクトリやその他の生成ファイルの所有者を変更できる。具体的には、"postinstall": "sudo chown -R $(id -u):$(id -g) node_modules"のようなスクリプトをpackage.jsonに追加する。

このコマンドの意味は次の通りだ。sudoはスーパーユーザー権限でコマンドを実行する。Dockerコンテナ内ではrootユーザーで実行されるため、実質的にrootでchownを実行する。chown -Rはディレクトリとその中の全てのファイル・サブディレクトリの所有者を変更する。$(id -u)はホスト環境の現在のユーザーのユーザーID(UID)を取得する。$(id -g)はホスト環境の現在のユーザーのプライマリグループID(GID)を取得する。node_modulesは所有者を変更する対象のディレクトリを指す。

この方法により、コンテナ内でnpm installが実行され、ファイルが生成された直後に、そのファイルの所有者がホストのユーザーIDとグループIDを持つユーザーに変更される。結果として、ホスト環境からこれらのファイルにアクセスする際に権限エラーが発生しなくなる。この方法は比較的簡単に導入でき、即効性があるというメリットがあるが、ビルドプロセスの一部として毎回所有権の変更が走るため、わずかながらオーバーヘッドが生じる可能性もある。

より根本的な解決策として、Dockerコンテナ内部でアプリケーションをビルド・実行する際に、最初からホスト環境のユーザーIDとグループIDを持つユーザーを作成し、そのユーザーで作業を行う方法がある。これにより、コンテナ内で生成されるファイルの所有者が最初からホストのユーザーと同じになるため、所有権の問題そのものを回避できる。

この方法では、Dockerfileを少し修正する必要がある。まず、Dockerfileのビルド時にホストのユーザーID(UID)とグループID(GID)を引数として受け取れるようにする。

1# Dockerfileの例 (簡略化)
2FROM node:22.20.0
3ARG UID
4ARG GID
5WORKDIR /code
6COPY package.json /code/
7# ホストのUID/GIDを持つユーザーを作成
8RUN groupadd -g $GID appgroup && useradd -u $UID -g appgroup -s /bin/bash -m appuser
9# 作成したユーザーに切り替えてnpm installを実行
10USER appuser
11RUN npm install
12COPY . /code/

そして、docker-compose.ymlのようなオーケストレーションツールでDockerをビルドする際に、ホストのUIDとGIDをbuild.argsとして渡す。

1# docker-compose.ymlの例 (簡略化)
2web:
3    build:
4        context: .
5        args:
6            UID: ${UID:-1000}  # ホストのUIDを渡す。デフォルト値は1000
7            GID: ${GID:-1000}  # ホストのGIDを渡す。デフォルト値は1000
8    # ...その他の設定

UID: ${UID:-1000}のように記述することで、環境変数UIDが設定されていればその値を使い、なければデフォルトで1000を使用するという意味になる。ホストのUIDやGIDは、id -uid -gコマンドで確認できる。多くのLinuxシステムでは一般ユーザーのUID/GIDは1000から始まることが多い。

この設定により、Dockerビルド時にコンテナ内部にホストのユーザーと同じIDを持つappuserというユーザーが作成され、そのユーザーとしてnpm installが実行される。結果として、node_modulesディレクトリやその他の生成ファイルは、最初からホストの一般ユーザーが所有する形で作成されることになる。これにより、ホスト環境からアクセスする際の権限エラーは発生しなくなる。この方法は、ファイルの所有権問題に対するよりクリーンで堅牢な解決策と言える。

Dockerを使った開発では、コンテナ内部とホスト環境との間でファイルの所有権が異なることによって引き起こされる権限エラーは頻繁に遭遇する問題の一つだ。この問題は、コンテナがrootユーザーでファイルを生成し、ホストの一般ユーザーがそのファイルにアクセスしようとすることで発生する。解決策としては、npm install後にpackage.jsonpostinstallフックを使ってchownコマンドで所有権を変更する方法と、Dockerfileのビルド時にホストのユーザーIDとグループIDを持つユーザーをコンテナ内に作成し、そのユーザーで作業を行う方法の二つが有効だ。前者は手軽に導入できるが、後者はより根本的な解決であり、最初から正しい所有者でファイルが生成されるため、権限に関する問題をより確実に取り除ける。これらの知識は、Dockerを活用したモダンなWebアプリケーション開発において、開発効率を高める上で非常に重要となる。

関連コンテンツ

関連IT用語