質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.45%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

1566閲覧

Dockerに立てたコンテナ内のMySQLに、ホストのMySQLのインストール有無に依存せず接続する方法が知りたい

akira_kano1101

総合スコア25

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

ORM

ORM(オブジェクト関係マッピング)はオブジェクト指向のシステムとリレーショナルデータベースの間でマッピングを行う技術です。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

1クリップ

投稿2022/05/27 14:28

編集2022/05/28 03:39

こんにちは。

Dockerに立てたMySQLコンテナに対して、ホストからORマッパーを使いデータベースにアクセスしデータの永続化を実現する機能を持ったソフトウェアを作ろうとしています。

使っている言語はRustです。

console

1$ sw_vers 2ProductName: macOS 3ProductVersion: 12.4 4BuildVersion: 21F79 5$ cargo --version 6cargo 1.61.0 (a028ae42f 2022-04-29)

実現したいこと

問題は、クライアントのホストPCにmysqlのインストールを強いるような実装は控えたい、しかしORマッパー(diesel)を使ってDockerコンテナのmysqlへ接続がしたいというときのコードの書き方がわからないということです。

ホストPCにMySQLがインストールされていれば、下記の要領で問題なくコンテナ内のMySQLにもアクセスできることはわかっています。

console

1$ docker-compose up -d 2mysql_container is up-to-date 3$ mysqladmin ping -h127.0.0.1 -P3316 -uroot -prootpass 4mysqladmin: [Warning] Using a password on the command line interface can be insecure. 5mysqld is alive

ユーザが使うローカルPCにはWindowsやMacといったOSなど実行環境に依存させない(インストーラを環境別に作ることを防ぎたい)ためにMySQLをインストールしたくありません。
※わかりにくい表現だったので訂正します。

今回はそうではありません。

DockerだけでMySQLを完結させたいです。

なお、実装に際し部分的にこちらのサイトも参考にしています。

docker-compose.yml

yml

1version: "3" 2 3services: 4 mysql: 5 image: mysql/mysql-server:5.7.28 6 container_name: mysql_container 7 command: --default-authentication-plugin=mysql_native_password 8 environment: 9 MYSQL_ROOT_PASSWORD: rootpass 10 MYSQL_DATABASE: sakila 11 TZ: "Asia/Tokyo" 12 volumes: 13 - ./my.cnf:/etc/mysql/conf.d/my.cnf 14 - ./init:/docker-entrypoint-initdb.d 15 ports: 16 - "3316:3306"

実行したコマンド

ローカルにMySQLがインストールされていない状況を再現するためbrew uninstallでMySQLをアンインストールしました。

console

1$ brew list -l | grep mysql 2drwxr-xr-x 3 a.kano admin 96 May 27 21:48 mysql 3drwxr-xr-x 3 a.kano admin 96 May 27 21:48 mysql-client 4$ mysql.server restart 5Shutting down MySQL 6. SUCCESS! 7Starting MySQL 8. SUCCESS! 9$ brew uninstall mysql 10Uninstalling /opt/homebrew/Cellar/mysql/8.0.29... (311 files, 295MB) 11$ brew uninstall mysql-client 12Uninstalling /opt/homebrew/Cellar/mysql-client/8.0.29... (129 files, 149.0MB)

次に、docker-compose up -dを実行してMySQLのコンテナを立てます。

console

1docker-compose up -d 2Starting mysql_container ... done

コンテナに入り、MySQLが生きているか確認します。

console

1$ docker ps 2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 39db1d950c858 mysql/mysql-server:5.7.28 "docker-entrypoint.s…" About a minute ago Up 11 seconds 33060/tcp, 0.0.0.0:3316->3306/tcp, :::3316->3306/tcp mysql_container 4$ docker exec -it 9db1d950c858 bash 5root@9db1d950c858:/# mysqladmin ping -uroot -prootpass 6mysqladmin: [Warning] Using a password on the command line interface can be insecure. 7mysqld is alive

生きていることが確認できました。

しかし、ここへRustのORマッパー(dieselを使用)からアクセスする方法がわかりません。

未完成のソースコード

RustでMySQLへのコネクションを確立するコードは現状以下のように書いています。

rust

1// mysql.rs 2pub use diesel::prelude::*; 3pub use diesel::MysqlConnection; 4use dotenv::dotenv; 5use std::env; 6 7pub fn establish_connection() -> MysqlConnection { 8 dotenv().ok(); 9 10 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); 11 MysqlConnection::establish(&database_url) 12 .expect(&format!("Error connecting to {}", database_url)) 13}

rust

1// main.rs 2mod mysql; 3use crate::mysql::establish_connection; 4 5fn main() { 6 establish_connection(); 7}

toml

1[package] 2name = "mysql-docker" 3version = "0.1.0" 4edition = "2021" 5 6[dependencies] 7dotenv = "0.15.0" 8diesel = { version = "1.4.8", features = ["mysql"] }

上記dotenvで読み込む環境変数DATABASE_URLは.envに次のように設定しています。

DATABASE_URL=mysql://root:rootpass@127.0.0.1:3316/sakila

そして実行します。

console

1$ cargo run 2 Finished dev [unoptimized + debuginfo] target(s) in 0.03s 3 Running `target/debug/mysql-docker` 4dyld[43490]: Library not loaded: /opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib 5 Referenced from: /Users/a.kano/development/mysql-docker/target/debug/mysql-docker 6 Reason: tried: '/opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib' (no such file), '/Users/a.kano/development/mysql-docker/target/debug/deps/libmysqlclient.21.dylib' (no such file), '/Users/a.kano/development/mysql-docker/target/debug/libmysqlclient.21.dylib' (no such file), '/Users/a.kano/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib/libmysqlclient.21.dylib' (no such file), '/Users/a.kano/.rustup/toolchains/stable-aarch64-apple-darwin/lib/libmysqlclient.21.dylib' (no such file), '/Users/a.kano/lib/libmysqlclient.21.dylib' (no such file), '/usr/local/lib/libmysqlclient.21.dylib' (no such file), '/usr/lib/libmysqlclient.21.dylib' (no such file) 7zsh: abort cargo run

このエラーもホストPCにmysqlがインストールされていれば正常終了することは試してわかっているのですが、やはりホストPCにmysqlはインストールしないと実行できないというのでは意味がないと思います。

解決策はありますか?

もし解決策がないなら、繰り返しになりますがユーザのPCに余計にMySQLのインストールをしなければならない制約を課すことになるため、Docker本来の仮想環境の利点が活かされず、Dockerをわざわざ使う意味がありません。インストールに要するコマンドが増えるなど仕様もわかりにくくなります。正しい解決方法が存在していて、私が見つけられていないだけでしょうか?

Sequel AceなどのようなアプリケーションでもコンテナMySQLの接続にホストにmysqlがインストールされている必要があるか試してみたのですが、予想通りMySQLがホストにインストールされていないと接続できないようでした。

至らない内容で恐縮ですが、ご存知の方、いらっしゃいますでしょうか。

ご教示いただけると助かります。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akira_kano1101

2022/05/28 02:59

hoshi-takanori様 ご提案ありがとうございます。 ちょっと調べてみようかと思います。
hoshi-takanori

2022/05/28 03:07

> ユーザが使うローカルPCにはWindowsやMacといったOSなど実行環境に依存させない(インストーラを環境別に作ることを防ぎたい) ユーザーに docker を入れてもらうと言う想定な時点で、だいぶ無理がある気が…。
akira_kano1101

2022/05/28 03:55

> ユーザーに docker を入れてもらうと言う想定な時点で、だいぶ無理がある気が…。 実は、確かに私もそんな気はしています。 今回はこのシステムの対象ユーザが身内だけですのでそこは私自身立ち会えば良いと考えていたので問題に思っていませんでしたが、そうですよね。 もしDockerを使わないでも済むようなベストプラクティスがあるなら教えてほしいです。 ただ単にローカルにmysqlをインストールしていただくようにする方が実際簡単に済むものなのでしょうか。
hoshi-takanori

2022/05/28 10:21

身内と言っても、ご家族なのか会社や学校や研究室の人なのかで変わってきますね。また、パソコンの所有者や管理形態、ユーザーの PC スキル、当該システムの利用目的などによっても。 いちばん簡単なのは Web アプリにする (ユーザーはブラウザさえあればいい) ってことかと。
akira_kano1101

2022/05/28 11:16 編集

兄弟のお店で使うシステムです。Windowsなのですが、Dockerも私が直接出向いてWSL2と共にインストールする予定でいます。このシステム、元々はExcelで作ったものでしたが使っていくうちにデータが多くなってきて動作が遅くなり(マクロや関数を多用するつくりな上、PCも低スペックだから)、改善を求められたのがことの始まりです。 Webアプリもその次に試していて、herokuを利用する形でRailsで少し作ってみたことはあるのですが、ブラウザ上でだと動作がデータの更新のたび少しですが待ちが生じたので、それならいっそネイティブにしようかとなりRustを選定をしました。今はWASMが気にはなっていますが手を出せないままにいます。 いまだにExcelで工夫して使ってもらっているので改善してあげたいです。 色々とご助言ありがとうございます。
hoshi-takanori

2022/05/28 11:27 編集

なるほど。それならインストールや管理は全手動で構いませんね。PC が低スペック (どのくらい低スペックかによりますが、もしかして 32bit OS だったりしますか?) だと docker は辛いと思うので、Windows 上で mysql を直接動かせば良いのでは…。
akira_kano1101

2022/05/28 12:29

ちょっと失念しましたが数年前に3万円台で購入したCHUWI製のノートPCで、そんなに昔のものではないので64bit OSであることは間違いないと思います。 どこまで低スペックだったかは、また確認してみますが、Dockerが辛ければやっぱりWindowsにMySQLを入れるのが最善の手になりそうでしょうかね?Dockerはある程度軽量だと認識していたのでそうなると残念ですが…。
hoshi-takanori

2022/05/28 13:07

ちょっと調べたら数万円で Celeron 4 コア、メモリ 8GB なんてのが手に入るんですね。私の「低スペック PC」に関する認識が古かったかも…。
akira_kano1101

2022/05/29 02:48 編集

10万円以内で整備済M1 Macbook Airも買えるので、時代も変わってきていますよね。 今後の方針として、アプリはインメモリで動かしデータの保存にクラウドを利用するというような仕組みで作ろうと考えているので結局AWSかherokuは利用する予定で、そこにDockerも必要になるだろうなと思っています。最終的にホストPCにはDockerは入れないで済むようにし、身内に限らず裾野を広げて一般ユーザにも簡単に使えるよう改善したいという考えですので、そのうちWebアプリに近い仕組みもまた用意することにはなりそうです。
guest

回答2

0

ベストアンサー

Dieselを使用する場合

やはりホストPCにmysqlはインストールしないと実行できないというのでは意味がないと思います。

DieselでMySQLに接続する際は、ホストPCにlibmysqlclientというMySQLのクライアント・ライブラリーがインストールされている必要があります。(MySQLサーバーのインストールは必要ありません)

DieselはRustのmysqlclient-sysクレートに依存しています。libmysqlclientが必要なことは、そのクレートのREADMEの冒頭に書かれています。

Building

For this crate to build, libmysqlclient must be installed on your system (brew install mysql on macOS, apt-get install libmysqlclient-dev on Ubuntu, included with the server distribution on Windows). Additionally, either pkg-config or mysql_config must be present and able to successfully locate libmysqlclient.

上ではbrew install mysqlと書かれていますが、サーバーは不要なので、brew install mysql-clientで十分なのではないかと思います。(試してません)

Dieselを使用している限り、MySQLに接続するにはlibmysqlclientが必須になります。インストール時の利便性を考えるなら、いま開発されているツールを各OSのパッケージシステムを使ってインストールできるようにするのが良いかもしれません。macOS向けにHomebrewのパッケージ、Ubuntu向けにdebパッケージ、といったものを用意し、libmysqlclientを依存ライブラリーとして記述しておけば、brewaptが自動的にインストールしてくれます。

Dieselの代わりにSQLxなどを使用する場合

他には、Dieselの代わりに SQLxクレートや、SeaORMクレートを使う方法もあります。

SQLxはO/Rマッパーではなく、SQLライブラリーですが、libmysqlclientのようなネイティブ・ライブラリーなしでMySQLに接続できます。(MySQL、PostgreSQL、MSSQLに対応しており、pure Rustで実装されています)

SeaORMはSQLx上に構築されたO/Rマッパーですので、同様にlibmysqlclientが不要になります。

SQLxはRustの非同期に対応しており、最近利用が増えている印象があります。

SeaORMの方は、まだ開発が始まって日が浅いことがあり、それに関する記事を見たことはありません。

SQLxなら安心して使えそうに思えます。

投稿2022/05/31 05:19

tatsuya6502

総合スコア2035

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akira_kano1101

2022/06/01 11:19

tatsuya6502様 ご回答いただきありがとうございます。 dieselはmysqlclient-sysクレートというものに依存していたんですね。 一人で調査していただけではそれがlibmysqlclientを要求することには全く気づきませんでした。 今、色々な方法をご提示いただきましたが、今回はDockerをやめて各OS向けにインストーラを用意し、それぞれでパッケージマネージャを使い分けてmysql-clientをインストールしていただくという方針にしようと思います。 sqlxクレートは気になったのですがマルチスレッド処理を要するコードにしていないため、必要になった時に見直したいと思います。 あと、まだWindowsのパッケージマネージャがwingetを使えばできるのかな?という解決のゴールは曖昧ですが、本題から逸れるのでこの質問ではここまでにしたいと思います。 本当にありがたい情報、わかりやすかったです。 丁寧にありがとうございました。
guest

0

ユーザが使うローカルPCにはWindowsやMacといったOSなど実行環境に依存させない(インストーラを環境別に作ることを防ぎたい)

このやりたいことそのものが、根本的に無理な相談ではないかと考えます。

Rustはコンパイル型の言語ですので、ユーザーに配布する実行形式はOSごとのコンパイルが必要となります。

投稿2022/05/28 00:06

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akira_kano1101

2022/05/28 03:48 編集

maisumakun様 ご回答ありがとうございます。 OS別にコンパイルが必要とのことですが、存じ上げております。 cargoのcross機能(クロスコンパイル)を利用して、同じRustコードをGitHub Actionsのmatrixを使うことでOS別にアプリケーションをビルドし、現在は暫定的にOS別のリリースの実験を試みています。 そして、そのうちOSに合わせてユーザにより適切に選択、ダウンロードされたバイナリ実行ファイルが実行される中でDockerコンテナのMySQLにアクセス(ホストPCの環境に依存せず)し、データベース永続化の処理を実装したいということですが、わかりにくいでしょうか。 なお、ただ、一番の論点はOS別にコンパイルが…という部分ではないです。 例えOSがMac向けのみであったとしても、Dockerに立てたMySQLコンテナのデータベースにアクセスするために、ローカル(ホストPC)にもmysqlが`brew install`などでインストールされている必要があるかと思います。 この、「ホストにmysqlがインストールされていないといけない」というところに問題を感じていて、それならばDockerのMySQLコンテナをわざわざ立てるメリットがないなというのが私の思うところなのです。 ※本文がわかりにくいと感じたので一部訂正しています。
maisumakun

2022/05/28 08:11 編集

docker-composeで複数のコンテナを立てて、RustのコードもMySQLライブラリを揃えたDocker内で実行する、という手段も考えられますが、RustはDocker外に置かないといけない、というのはどのような必要性からの条件でしょうか。
akira_kano1101

2022/05/28 11:35 編集

お返事ありがとうございます。 GUIのためにeguiというクレートを利用しようと考えていて、Dockerにこれを置いて起動することはできないと思っているからです。(この考えはまだ試していないので間違っているかもしれないとも思っているので、ご指摘いただけるとありがたいです) システムのつくりはClean Architectureで、いくつかにコンポーネントを分割して作っています。 gatewaysコンポーネントを含むシステムの一部をAPIコンテナにし、MySQLコンテナに接続するというように二つコンテナを立てて外部からそのAPI叩けばできるかもしれないとは思っているところで模索段階です。 まだわかっていないことが多いため、ご助言ください。よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.45%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問