Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerコンテナを立ち上げる際にビルドエラーが発生する #2206

Closed
1 of 3 tasks
gigi434 opened this issue Aug 6, 2024 · 14 comments · Fixed by #2239
Closed
1 of 3 tasks

Dockerコンテナを立ち上げる際にビルドエラーが発生する #2206

gigi434 opened this issue Aug 6, 2024 · 14 comments · Fixed by #2239

Comments

@gigi434
Copy link
Contributor

gigi434 commented Aug 6, 2024

不具合の内容

Docker Composeコマンドを使用してDockerコンテナを作成する際にビルドエラーが発生する。
理由は、エラー文を読むと、npmとNode.jsのバージョンが必須要件に一致しないから
プロジェクトのルートに配置されている.node-versionファイルを確認すると、Node.jsのバージョンは20.12.2を必要としている

現象・ログ

エラー文

developer@DESKTOP-BD9AG8V:~/voicevox$ docker compose up -d --build
WARN[0000] /home/developer/voicevox/docker-compose.yml: `version` is obsolete 
[+] Building 6.2s (13/13) FINISHED                                                                                                                         docker:default
 => [test internal] load build definition from Dockerfile                                                                                                            0.0s
 => => transferring dockerfile: 352B                                                                                                                                 0.0s
 => [test internal] load metadata for docker.io/library/node:18.13.0                                                                                                 1.3s
 => [test internal] load .dockerignore                                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                                      0.0s
 => [test internal] load build context                                                                                                                               2.3s
 => => transferring context: 58.08MB                                                                                                                                 2.3s
 => [test 1/9] FROM docker.io/library/node:18.13.0@sha256:d871edd5b68105ebcbfcde3fe8c79d24cbdbb30430d9bd6251c57c56c7bd7646                                           0.0s
 => CACHED [test 2/9] WORKDIR /opt                                                                                                                                   0.0s
 => CACHED [test 3/9] RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup_install.sh                                                             0.0s
 => CACHED [test 4/9] RUN chmod 755 rustup_install.sh                                                                                                                0.0s
 => CACHED [test 5/9] RUN echo 1 | sh rustup_install.sh -y                                                                                                           0.0s
 => CACHED [test 6/9] RUN cargo install typos-cli                                                                                                                    0.0s
 => [test 7/9] COPY . /work                                                                                                                                          0.4s
 => [test 8/9] WORKDIR /work                                                                                                                                         0.0s
 => ERROR [test 9/9] RUN npm ci                                                                                                                                      2.1s
------
 > [test 9/9] RUN npm ci:
2.105 npm ERR! code EBADENGINE
2.106 npm ERR! engine Unsupported engine
2.106 npm ERR! engine Not compatible with your version of node/npm: voicevox@999.999.999
2.106 npm ERR! notsup Not compatible with your version of node/npm: voicevox@999.999.999
2.107 npm ERR! notsup Required: {"node":">=20.12.2 <21","npm":">=10.5.0 <11"}
2.107 npm ERR! notsup Actual:   {"npm":"8.19.3","node":"v18.13.0"}
2.108 
2.108 npm ERR! A complete log of this run can be found in:
2.108 npm ERR!     /root/.npm/_logs/2024-08-06T12_11_15_853Z-debug-0.log
------
failed to solve: process "/bin/sh -c npm ci" did not complete successfully: exit code: 1

再現手順

フォークの後、下記手順で確認できる

git clone
cd voicevox/
docker compose up -d --build

期待動作

VOICEVOXのバージョン

この問題にはバージョンの影響なし

OSの種類/ディストリ/バージョン

  • Windows
  • macOS
  • Linux

Ubuntu-24.04

その他

・Dockerfileのベースイメージを18.13.0から20.12.2に変更することで正常にビルドが完了することを確認した
・OSSへの貢献は初めてです。DISTRIBUTION.mdは読みました。

関連 Issue

@Hiroshiba
Copy link
Member

issue作成ありがとうございます!!
ビルドエラーの報告もありがとうございます!

実はdocker composeとdockerfileはあまりメンテされておらず、今後もdockerをサポートするかどうか検討しようと思っていたところでした。
というのも、おそらくdocker上でelectronが動かないので実機チェックできないというのと、起動するためにdocker実行経路とローカル実行経路の2つをメンテする必要があるので、どうしようかなと。

dockerをサポートするかどうかについて皆さんから気軽に意見をいただけると嬉しいです!


@gigi434
あ、もしよければなのですが、せっかくなのでdockerfile等をアップデートするプルリクエスト送ってみませんか 👀
このissueの決定によっては消えてしまうかもなのですが、プルリクエスト作成やOSSコミュニケーションの練習にちょうど良いのかなと思い提案してみた次第です・・・!

@sevenc-nanashi
Copy link
Member

個人的には:

  • 今のままならDockerfile周りは消していいと思います
  • そういえばVRTをCI経由でしか走らせられないのは不便
    • VRTをDocker内のUbuntuで走らせるようにしたい感(OS違いはUser-Agentを変えればMac用レイアウトとして認識されるはず)

@gigi434
Copy link
Contributor Author

gigi434 commented Aug 7, 2024

#2206 (comment)

個人的には:

  • 今のままならDockerfile周りは消していいと思います

私はDocker関連の削除に反対です。
なぜなら、新参にとって環境構築をdocker compose up -dなどで済ませられることにメリットを感じるからです。
例えば、Dockerfileを見るにGoをインストールしてタイポ検証にtypos-cliを入れていますし、nvmなどを使用してNode.jsのバージョン切り替えなどせずに環境構築できます。

#2206 (comment)

おそらくdocker上でelectronが動かないので実機チェックできないというのと、起動するためにdocker実行経路とローカル実行経路の2つをメンテする必要があるので、どうしようかなと。

あと、おそらくDocker上でelectronが動作できます。Qiitaの記事ですが、下記のサンプルアプリケーションをもとにWSL2 + Dockerで試したところElectronのアプリケーションが動作しました。
https://qiita.com/aismszy/items/ffb8cf734a7f51299d41
https://github.com/gigi434/fork-electron
image

ローカルとDocker両方サポートするのが難しいのは確かです。最終的な判断はお任せいたします。

@Hiroshiba
Copy link
Member

ご意見ありがとうございます!!

確かにワンコマンドで環境が構築できるのは魅力的だと感じました!
ただdockerを考慮すると、やはりdocker用の環境とそうじゃない環境の2つを整備する必要がありそうです。
(あとdocker+electronは昔やろうとしたことあるんですが、いろいろ不安定で結局ホストOSに直接乗っけるのが楽だと感じた経験が個人的にあります。)

この2つの条件を満たす形として、例えばコマンド1つで色々環境が構築できるスクリプトファイルを作るのとかどうでしょう・・・?
dockerをよく使う際はイマイチかもですが、まあdocker内でそのコマンドを実行すればある程度までは環境構築できそうかも。
あとCI/CD環境でも同じスクリプトを用いれるので、いろいろ共通化できて便利になるかもです。


コマンド1つで開発の準備が万端になるのが嬉しい、という発想が全く思いつきませんでした。
コメントありがとうございます!!! @gigi434

(そういえばタイポチェックとかは自動テストがGithub上で回るので、あまりローカルでは実行していませんでした。
この辺もREADME等で案内したいなとと思いました。)

@sevenc-nanashi
Copy link
Member

コマンド一つで環境構築

それならdevcontainerとして提供するべきな気がします(devcontainerにわかなのであまりよくわかってませんが...)

@gigi434
Copy link
Contributor Author

gigi434 commented Aug 8, 2024

#2206 (comment)

この2つの条件を満たす形として、例えばコマンド1つで色々環境が構築できるスクリプトファイルを作るのとかどうでしょう・・・? dockerをよく使う際はイマイチかもですが、まあdocker内でそのコマンドを実行すればある程度までは環境構築できそうかも。 あとCI/CD環境でも同じスクリプトを用いれるので、いろいろ共通化できて便利になるかもです。

であれば、今後の変更としては下記を行うつもりですが、私が着手してもよろしいでしょうか?
・Windows, Mac, Linuxに応じた環境構築を行うシェルスクリプトを用意して動作を確認する
・Docker関連のファイルを削除する

#2206 (comment)

コマンド一つで環境構築

それならdevcontainerとして提供するべきな気がします(devcontainerにわかなのであまりよくわかってませんが...)

確かにまとめて提供できそうですね。ローカル一本に話がまとまったため�Docker周りのファイルは削除する予定です。

@Hiroshiba
Copy link
Member

環境構築ができるスクリプトを用意するの、是非お願いしたいです!!

ただちょっと、ものによってはメンテナンスが難しいかも感じました。
例えばwindowsで動く汎用的なシェルスクリプトを書こうとするとPowerShellとかになると思うのですが、読み書きできる人はとても少ないかもしれません・・・。

そういえば7zというツールがVOICEVOX内のコードで必要なのですが、ダウンロードスクリプトはnode.jsで書かれていて、postinstallで勝手にダウンロードされるようになっています。

"postinstall": "electron-builder install-app-deps && node build/download7z.js",

こんな感じでnode.js用のコードを書くと全 OS 共通にできる&メンテナンス性が高い&型の恩恵を受けられるかも・・・?

ご不明な点や提案などあればぜひお気軽に何でもお聞きください!!

@gigi434
Copy link
Contributor Author

gigi434 commented Aug 10, 2024

@Hiroshiba
#2206 (comment)

そういえば7zというツールがVOICEVOX内のコードで必要なのですが、ダウンロードスクリプトはnode.jsで書かれていて、postinstallで勝手にダウンロードされるようになっています。

"postinstall": "electron-builder install-app-deps && node build/download7z.js",

こんな感じでnode.js用のコードを書くと全 OS 共通にできる&メンテナンス性が高い&型の恩恵を受けられるかも・・・?
ご不明な点や提案などあればぜひお気軽に何でもお聞きください!!

ありがとうございます。シェルスクリプトで考えていました。
Typescriptで書くのであれば下記のようなファイルをプロジェクトルートにおいて、postInstallでnpm ciの後に実行されることを考えています。

./setup.ts

import { exec, execSync } from 'child_process';
import { promisify } from 'util';
import { platform } from 'os';

// OSのコマンドを非同期関数として処理させるために必要な関数
const execAsync = promisify(exec);

// コマンド実行とメッセージ出力を行うヘルパー関数
async function runCommand(command: string, description: string) {
  console.log(`実行中: ${description} ...`);
  try {
    const { stdout, stderr } = await execAsync(command);
    if (stdout) console.log(stdout);
    if (stderr) console.error(stderr);
  } catch (error) {
    console.error(`エラーが発生しました: ${error.message}`);
    throw error;
  }
}

// 共通の環境セットアップを行う関数
async function setupEnvironment() {
  await runCommand('curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs -o rustup_install.sh', 'Rustのインストールスクリプトのダウンロード');
  await runCommand('chmod 755 rustup_install.sh', 'インストールスクリプトに実行権限を付与');
  await runCommand('sh rustup_install.sh -y', 'Rustのインストール');

  await runCommand('echo "source $HOME/.cargo/env" >> ~/.bashrc', '.cargo/envをシェルの設定ファイルに追加');

  console.log('現在のシェルセッションに即座に反映中 ...');
  execSync('. $HOME/.cargo/env', { shell: '/bin/bash' });

  await runCommand('cargo install typos-cli', 'typos-cliのインストール');
}

// Debian系のLinuxディストリビューションに必要なパッケージをインストールする関数
async function installDebian() {
  await runCommand('sudo apt-get update', 'APTパッケージリストの更新');
  await runCommand('sudo apt-get install -y curl build-essential', '必要なパッケージのインストール');
  await setupEnvironment();
}

// Red Hat系のLinuxディストリビューションに必要なパッケージをインストールする関数
async function installRedHat() {
  await runCommand('sudo yum update -y', 'YUMパッケージリストの更新');
  await runCommand('sudo yum groupinstall -y "Development Tools"', '開発ツールのグループインストール');
  await runCommand('sudo yum install -y curl', '必要なパッケージのインストール');
  await setupEnvironment();
}

// macOSに必要な環境をセットアップする関数
async function installMacOS() {
  await setupEnvironment();
}

// Windowsに必要な環境をセットアップする関数
async function installWindows() {
  await setupEnvironment();
}

// OSを確認して適切なインストール関数を呼び出す関数
async function installDependencies() {
  const os = platform();

  try {
    switch (os) {
      case 'linux':
        if (await isDebian()) {
          await installDebian();
        } else if (await isRedHat()) {
          await installRedHat();
        } else {
          throw new Error('サポートされていないLinuxディストリビューションです');
        }
        break;
      case 'darwin':
        await installMacOS();
        break;
      // Windowsであるとwin32という値が返る
      case 'win32':
        await installWindows();
        break;
      default:
        throw new Error('サポートされていないOSです');
    }

    console.log('依存関係が正常にインストールされました。');
  } catch (err) {
    console.error(`エラーが発生しました: ${err.message}`);
  }
}

// Debian系のLinuxディストリビューションかどうかを確認する関数
async function isDebian(): Promise<boolean> {
  try {
    await execAsync('cat /etc/debian_version');
    return true;
  } catch {
    return false;
  }
}

// Red Hat系のLinuxディストリビューションかどうかを確認する関数
async function isRedHat(): Promise<boolean> {
  try {
    await execAsync('cat /etc/redhat-release');
    return true;
  } catch {
    return false;
  }
}

// 依存関係をインストール
installDependencies();

しかし、rustup_install.shと同様にトランスパイルのファイルとしてプロジェクトルートにsetup.jsが出力されてしまいます。
これは./buildディレクトリに格納してもよいのでしょうか?削除しようとするとWindowsとLinuxディストリビーションでコマンドが違うのでスクリプトが複雑になってしまいます。
また、ブランチ切って作業を始めてもよろしいでしょうか?

@Hiroshiba
Copy link
Member

Hiroshiba commented Aug 10, 2024

おー!!!! 便利そうで良い感じに思いました!!!
ぜひブランチ切ってプルリクエストいただければ!!

現状でコメントできる点をコメントしてみました!


プロジェクトルートにsetup.jsが出力されてしまいます。

ちょっと開発環境が微妙になっちゃうかもですが、最初から.jsで書くのはどうでしょう。
たぶん頑張れば.tsで良い感じに実行できるのですが、すごい調べないといけなそうな雰囲気なので・・・。

1行目に// @ts-check入れるある程度チェックしてくれると思います。
あと関数の型もちょっとややこしいですが付けられそうでした。(VSCodeだと良い感じに補完してくれました)

// 元がこうだとすると
// async function runCommand(command: string, description: string): Promise<void>

/**
 * コマンド実行とメッセージ出力を行うヘルパー関数
 * @param {string} command
 * @param {string} description
 * @returns {Promise<void>}
 */
async function runCommand(command, description) {

typos

cargo経由よりも直接バイナリをダウンロードするほうがグローバルな環境に影響がなくて嬉しい方多いかも?
確認した感じdownload7z.jsはバージョン固定でそんな感じでした!

@sevenc-nanashi
Copy link
Member

sevenc-nanashi commented Aug 10, 2024

個人の感想ですが、なんか大量に環境を汚しまくってるのはさすがに微妙な気がします...
しかもpostinstallなら「npm iしたらなんか環境が変わった!」ってなって、個人的にはとても嫌ですね...(~/.profileとかを最小にして起動速度をチューニングしている人もいる、npm iがグローバルに環境を変化させるのを想定できる人はいないと言ってもいいはずなので)

(個人的には明確に反対です)

ちなみにですが、.tsファイルを実行するならtsxがおすすめです

@Hiroshiba
Copy link
Member

Hiroshiba commented Aug 10, 2024

たしかに、グローバルな環境にインストールするコードがpostinsallで実行されるのは、予想外の動きと感じる方多いかもですね。。
download7zと同じくbuild/vendored/とかのディレクトリにバイナリダウンロードして、npm run typosとかでダウンロードしたバイナリを実行する形とかきれい・・・・・かも・・・?

ちなみにですが、.tsファイルを実行するならtsxがおすすめです

tsxやts-node導入するならいっそのことDeno導入もありに感じてます。
tsconfig.jsonとかの設定やnode_modulesの流用がどれくらいややこしくなるのか次第ですが。

@sevenc-nanashi
Copy link
Member

sevenc-nanashi commented Aug 10, 2024

ここでのDenoはきついと思いますね、主にLSの設定がつらみになると思います。>Deno

typosをその形でやるなら自分は大丈夫だと思います>npm run typos

@gigi434
Copy link
Contributor Author

gigi434 commented Aug 12, 2024

バイナリデータでの実行方法などあるのですね。ずっと管理パッケージマネージャー経由で管理していたので初めて知りました。
お二人の下記方法を試した結果うまくいきました。方法としてはいかがでしょうか
・typosはcargoからではなく7zと同じように./build/verndor/typosディレクトリ下に最新バージョンのバイナリデータをダウンロードするjsファイルを./buildに置く。(7zは即時実行関数で実行されているが、どのタイミングで実行されているか要確認)
・npm run typosで./build/vendor/typosからバイナリデータを実行する。
・Docker周辺は削除する

@Hiroshiba
Copy link
Member

おー!!!めちゃくちゃ良いと思います!!!

gigi434 added a commit to gigi434/voicevox that referenced this issue Aug 24, 2024
gigi434 added a commit to gigi434/voicevox that referenced this issue Aug 24, 2024
gigi434 added a commit to gigi434/voicevox that referenced this issue Aug 26, 2024
gigi434 added a commit to gigi434/voicevox that referenced this issue Aug 26, 2024
gigi434 added a commit to gigi434/voicevox that referenced this issue Sep 1, 2024
gigi434 added a commit to gigi434/voicevox that referenced this issue Sep 9, 2024
…ocディレクトリとREADME.mdを削除するスクリプトを追加した
Hiroshiba added a commit to gigi434/voicevox that referenced this issue Sep 13, 2024
Hiroshiba added a commit that referenced this issue Sep 13, 2024
* [add] #2206 typosのバイナリをダウンロードするスクリプトが必要なため

* [fix] #2206 windowsにてTyposのバイナリデータがダウンロードと解凍・削除されない不具合を修正した

* [fix] #2206 cross-envを使用しているためプラットフォームの違いを吸収するコマンドに修正した

* [fix] #2206 ダウンロードしたいバイナリがすでにある時に再度ダウンロードされるのではなく、スキップされるように修正した

* [fix] #2206 もしバイナリが既に存在する場合、ダウンロードをスキップするように修正した

* [fix] #2206 macosのCPUアーキテクチャの違いを考慮し最適なバイナリをダウンロードするように修正した

* [document] #2206 cargoを通したインストールではなくなったためそれに応じたドキュメントに修正した

* [delete] #2206 Docker関連のファイルは使用しないため

* [fix] #2206 バイナリをダウンロードする際に使用する渡すURLのオブジェクトを文字列にすることで無駄な処理を削減した

* [fix] #2206 Github以外に公開している場合のバイナリにも対処し、かつ、ダウンロードする処理を共通化して冗長な部分を削除した

* [fix] #2206 空行を入れていなかったため修正した

* [delete] #2206 typosは手動で行うため削除する

* [fix] #2206 linuxで.tar.gzファイルが解凍されない不具合を修正した

* [fix] #2206 タイポがあったため修正した

* [fix] #2206 定数であるのにコンスタントケースになっていないため修正した

* [fix] #2206 条件を間違えていたため修正した

* [fix] #2206 typosのCIが実行できていないため追加した

* [fix] #2206 TYPOS_URLSがstringまたはobjectを返すことになるため、型ガードを追加しなければならないことを修正した

* [fix] #2206 curlコマンドがない環境のためにnode-fetchを使用する方法に修正した

* [fix] #2206 変数であるのに定数として定義していたため修正した

* [fix] #2206 markdownlintのCIでエラーが出るため、typosのmarkdownファイルが存在するdocディレクトリとREADME.mdを削除するスクリプトを追加した

* Apply suggestions from code review

* Apply suggestions from code review

---------

Co-authored-by: Hiroshiba <hihokaruta@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants