Ubuntuで本番用のMetabaseをインストールする方法

このチュートリアルでは、**Alibaba Cloud ECS Ubuntu 16.04**サーバに**Metabase**をインストールし、データの可視化を実現します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/database-visualization-using-metabase-part-1---install-metabase-on-ubuntu-1604_592155)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[Alibaba Cloud Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT) 執筆、Liptan Biswas。[Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)は、技術的な知識やベストプラクティスをクラウドコミュニティ内で共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

Metabaseは、データベースを可視化し、そこから洞察を得るためのオープンソースアプリケーションです。Metabaseは、SQL文を書かずにデータベース上でクエリを実行するための、直感的で使いやすいWebベースのインターフェースを提供します。MySQL/MariaDB、Postgres、Mongo、SQL Server、Druid、H2、SQLite、Oracleなど、ほとんどすべての[一般的なデータベース](https://www.alibabacloud.com/product/apsaradb-for-rds?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)で動作します。データは、テーブル、グラフやチャートで取得することができます。

このチュートリアルは2つのパートに分かれています。チュートリアルの最初の部分では、Ubuntu 16.04サーバにMetabaseをインストールします。Metabaseデータベースをホストするために[PostgreSQL](https://www.alibabacloud.com/blog/how-to-setup-postgresql-server-for-metabase_594913?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)を使用します。また、リバースプロキシとしてNginxを設定し、Let's Encrypt SSLを使用してMetabaseインスタンスを保護します。

[チュートリアルの第二部](https://www.alibabacloud.com/blog/database-visualization-using-metabase-part-1---install-metabase-on-ubuntu-1604_592155)では、プラットフォームの使い方の基本を学びます。また、プラスを設定するためのメールの設定も行います。

###必要な要件
- [Alibaba Cloud ECSインスタンス](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT&biz_params=%7B%22intl%22:%22%7B%5C%22referralCode%5C%22:%5C%22fmj2og%5C%22%7D%22%7D)にUbuntu 16.04 64ビットがインストールされていること。
- ポート「80」、「443」を許可するように構成されたファイアウォールまたはセキュリティグループのルール。
- [ECSインスタンスを指す](https://www.alibabacloud.com/help/doc-detail/58077.htm?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)必要がある[ドメイン名](https://www.alibabacloud.com/domain?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT&biz_params=%7B%22intl%22:%22%7B%22referralCode%22:%22fmj2og%22%7D%22%7D)。

インスタンスを作成し、インスタンスに接続するための手順については、「[クイックスタートガイド](https://www.alibabacloud.com/help/doc-detail/25422.htm?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)」に従ってください。このチュートリアルでは、Alibabaインスタンスを作成し、「192.168.0.101」がUbuntuインスタンスに割り当てられたパブリックIPアドレスであることを前提としています。また、「[metabase.example.com](http://metabase.example.com/?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)」がUbuntuインスタンスを指すように設定しています。インスタンスにSSHで接続したら、以下のコマンドを実行してリポジトリキャッシュとベースシステムを更新します。

`apt update && apt -y upgrade & apt -y autoremove`

###Javaのインストール
MetabaseはJavaで書かれているため、Metabaseを実行するにはJavaランタイムをインストールする必要があります。MetabaseはOracle Java 8とOpenJDK 8の両方をサポートしています。このチュートリアルでは、OpenJDKのJavaランタイムバージョン8をインストールします。

`apt -y install openjdk-8-jre`

java -versionを実行して、Javaが正常にインストールされているかどうかを確認します。

```
root@aliyun:~# java -version
openjdk version "1.8.0_162"
OpenJDK Runtime Environment (build 1.8.0_162-8u162-b12-0ubuntu0.16.04.2-b12)
OpenJDK 64-Bit Server VM (build 25.162-b12, mixed mode)
```

システムにJavaがインストールされているディレクトリを探します。

`readlink -f /usr/bin/java | sed "s:/jre/bin/java::”`

以下のような出力が表示されるはずです。

```
root@aliyun:~# readlink -f /usr/bin/java | sed "s:/jre/bin/java::"
/usr/lib/jvm/java-8-openjdk-amd64
```

ここで、Javaのインストール先のパスに応じて、環境変数JAVA_HOMEを設定します。

```
echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64" | tee -a /etc/profile
source /etc/profile
```

echo $JAVA_HOMEを実行して、JAVA_HOME変数が設定されているか確認してください。と表示されるはずです。



```
root@aliyun:~# echo $JAVA_HOME
/usr/lib/jvm/java-8-openjdk-amd64
```

###ApsaraDB for PostgreSQLを設定する
デフォルトでは、MetabaseはH2データベースを使用するように設定されています。H2データベースはフラットファイルベースのデータベースであり、実行するために特別なソフトウェアを必要としません。しかし、マルチユーザーの本番環境でH2データベースを使用することは、アプリケーションのパフォーマンスを悪化させるため、推奨されません。このチュートリアルでは、Metabaseデータベースをホストするために[ApsaraDB for RDS](https://www.alibabacloud.com/product/apsaradb-for-rds?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)のPostgreSQLサーバを使用します。[https://rdsnew.console.aliyun.com](https://rdsnew.console.aliyun.com/?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)にアクセスし、[RDS instance for PostgreSQL](https://www.alibabacloud.com/blog/how-to-install-postgresql-for-sonarqube-on-ubuntu-16-04_594904?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)を新規作成します。サブスクリプションの種類を選択し、リージョンを選択します。ECSインスタンスがあるリージョンと同じリージョンにRDSインスタンスを作成することで、ECSやRDSインスタンスはイントラネットのプライベートアドレスを使用して通信することができるなど、多くのレバレッジが得られます。インターネットアドレスの申請は不要で、イントラネットのデータ転送は無料です。今回のチュートリアルでは、ECSインスタンスもあるムンバイリージョンにRDSインスタンスを作成しました。

DB EngineをPostgreSQLとして選択し、バージョン9.4を選択します。ECSインスタンスが配置されているゾーンとVPCを選択します。インスタンスの種類と容量を選択します。インスタンスの種類と容量は、必要に応じて後から増やすことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/9dcd5661-d12f-f593-511d-bd1d0af7e675.png)



インスタンスの購入後、インスタンスがアクティブになるまで数分かかります。インスタンスがアクティブになったら、"管理 "リンクをクリックして、"セキュリティ "タブに切り替えます。ここで新しいホワイトリストグループを追加し、新しいグループに名前を付けて、ECSインスタンスのプライベートまたはイントラネットのIPアドレスを入力します。ECSインスタンスをホワイトリスト化しただけなので、データベースサーバーはECSインスタンスからのみアクセス可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/daa9d716-6e30-b6d4-a746-1e15c7a031ba.png)

さて、"Accounts "タブに切り替えて、ユーザ名 "postgres "でPostgreSQLサーバ用の新しいマスターアカウントを作成します。このマスターアカウントは、PSQLシェルから新しいユーザとデータベースを作成するために使用されます。

最後に、接続オプションタブに移動して、RDSインスタンスに割り当てられたイントラネットのアドレスとポートを見つけます。チュートリアルで後で必要になるので、イントラネットのアドレスとポートをメモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/25e8b494-bef5-9acb-bc04-959d6124d92d.png)

PostgreSQLサーバインスタンスの準備ができたので、Metabaseのインストールに移りましょう。

###Metabaseのインストール
Metabaseはクロスプラットフォームで、ターミナルで簡単に実行できるJava実行ファイルを提供しています。[Metabaseのダウンロードページ](https://www.metabase.com/start/jar.html?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)でアプリケーションの最新リリースへのリンクを見つけ、以下のコマンドを使ってMetabaseをダウンロードしてください。

`wget http://downloads.metabase.com/v0.28.6/metabase.jar`

Metabase Java実行ファイルを実行するための新しい非特権ユーザーを作成します。Metabase実行ファイルは内蔵のJettyウェブサーバーも起動するので、システムのセキュリティを確保するためにも非特権ユーザーを使用することをお勧めします。

`adduser --home /var/metabase --gecos="Metabase User" --disabled-login --disabled-password metabase`

ダウンロードした実行ファイルを "metabase "ユーザーのホームディレクトリに移動します。

`mv metabase.jar /var/metabase`

Metabaseサービスを開始する前に、ECSインスタンスからリモートRDSインスタンスに接続できるかどうかを確認してみましょう。また、Metabase用のデータベースとデータベースユーザを作成する必要があります。

PostgreSQLクライアントをインストールします。

`apt -y install postgresql-client`

以下のコマンドを使用して、作成したリモートPostgreSQLインスタンスに接続します。イントラネットアドレスを、インスタンスに割り当てられた実際のアドレスに置き換えてください。プロンプトが表示されたら、先に作成した "postgres "マスタユーザのパスワードを入力します。

`psql -h rm-6gjlyl343w252w65g.pgsql.ap-south-1.rds.aliyuncs.com -p 3433 -U postgres -d postgres`

接続が成功すると、"psql "シェルにログインして、データベースサーバ上でクエリを実行することができます。チュートリアルに正しく従っていれば、接続に問題はないはずです。以下のような出力が得られます。

```
root@aliyun:~# psql -h rm-6gjlyl343w252w65g.pgsql.ap-south-1.rds.aliyuncs.com -p 3433 -U postgres -d postgres
Password for user postgres: 
psql (9.5.12, server 9.4.10)
Type "help" for help.

postgres=> 
```

ここで、Metabase用の新しいデータベースユーザーを作成します。StrongPasswordを非常に強いパスワードに置き換えます。

`CREATE USER metabase WITH PASSWORD ‘StrongPassword'`

データベースを作成します。

`CREATE DATABASE metabasedb.`

データベース "metabasedb "に対して、"metabase "ユーザーにすべての権限を付与します。

`GRANT ALL PRIVILEGES ON DATABASE metabasedb to metabase;`

qコマンドを入力してrootユーザのシェルにログアウトします。MetabaseでデフォルトのH2データベースの代わりにPostgreSQLをデータベースサーバとして使用しているので、PostgreSQLサーバを使用するようにMetabaseを設定する必要があります。Metabaseは環境変数から設定パラメータを読み込みます。Metabaseを本番用にインストールしているので、アプリケーションを実行するためにsystemdサービスユニットをセットアップします。systemdサービスはファイルから環境変数を読み込むことができます。Metabaseの環境変数を格納するための新しいファイルを作成します。

`nano /var/metabase/metabase.env`

以下の内容でファイルを埋めてください。設定や好みに応じて値を変更してください。パラメータの説明はコメントとして記載しています。

```
# Password complexity for Metabase user, allowed values <weak|normal|strong>
MB_PASSWORD_COMPLEXITY=normal
# Password length for Metabase user
MB_PASSWORD_LENGTH=8

# Host and Port on which the inbuilt jetty server listens, 
# Leave it unchanged
MB_JETTY_HOST=localhost
MB_JETTY_PORT=3000

# Provide Intranet or Private IP address of PostgresSQL server
MB_DB_TYPE=postgres
MB_DB_HOST=rm-6gjlyl343w252w65g.pgsql.ap-south-1.rds.aliyuncs.com
MB_DB_PORT=3433

# Provide the database name
MB_DB_DBNAME=metabasedb
# Provide the username of database user
MB_DB_USER=metabase
# Provide the password of database user
MB_DB_PASS=StrongPassword

# Setting it true will include emojis in logs, to disable set it to false
MB_EMOJI_IN_LOGS=true
```

ファイルを保存し、エディタを終了します。ファイルの所有権を「metabase」ユーザーに提供します。

`chown metabase:metabase -R /var/metabase`

systemdサービスを介してMetabaseを管理することで、アプリケーションの起動と停止のプロセスが簡素化されます。また、システムの再起動やプロセスの障害時にアプリケーションが自動的に起動することを保証します。新しいsystemd単位のファイルを作成します。

`nano /etc/systemd/system/metabase.service`

以下の内容でファイルを埋めてください。

```
[Unit]
Description=Metabase server
After=syslog.target
After=network.target

[Service]
EnvironmentFile=/var/metabase/metabase.env
User=metabase
Group=metabase
Type=simple
ExecStart=/usr/bin/java -jar /var/metabase/metabase.jar
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=metabase

[Install]
WantedBy=multi-user.target
```

実行することで起動できます。

`systemctl start metabase`

起動時にMetabaseサーバーが自動的に起動するようにするには、実行します。

`systemctl enable metabase`

実行することでサービスの状態を確認することができます。

`systemctl status metabase`

Metabaseサーバの初回起動時に、アプリケーションはPostgreSQLサーバにデータベースを書き込みます。初めてアプリケーションが初期化されるまでに数分かかる場合があります。以下のコマンドでsyslogを確認することで、アプリケーションの状態を監視することができます。

`journalctl -f -e -u metabase`

ログに以下の行が表示されれば、アプリケーションの準備は完了です。

`Apr 23 21:30:34 aliyun metabase[30486]: 04-23 21:30:34 INFO metabase.core :: Metabase Initialization COMPLETE`

###Nginxをインストールする
Metabaseにはアプリケーションにサービスを提供するためのJetty Webサーバーが組み込まれていますが、本番環境では、このようなWebサーバーをインターネット上に公開することは推奨されていません。最良の方法は、NginxやApacheなどのプロダクショングレードのWebサーバーをフロントにセットアップし、リクエストをJettyサーバーにプロキシすることです。このチュートリアルでは、MetabaseサーバへのリバースプロキシとしてNginxウェブサーバをインストールします。

Nginxウェブサーバをインストールします。

`apt -y install nginx`

Nginxを起動し、起動時にサーバーが自動的に起動するようにします。

```
systemctl start nginx
systemctl enable nginx
```

また、ログインやその他の重要なデータは、ブラウザのセッションからウェブサーバーに送信され、その逆も同様に送信されるため、SSL/TLSによる暗号化でウェブサーバーを保護することも重要です。交換されるデータが暗号化されていない場合、ネットワーク内のデータを盗聴されてしまう可能性があります。このチュートリアルでは、Let's Encrypt CAの無料SSL証明書を使用します。よりプロダクションフレンドリーで信頼性の高いSSLを使用したい場合は、[アリババからSSL証明書を購入](https://www.alibabacloud.com/product/certificates?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)することができます。

Let's Encryptでは、証明書のリクエストや生成を簡単に行えるツール「Certbot」を提供しています。Certbotのリポジトリを追加し、Certbotをインストールします。


```
apt -y install software-properties-common
add-apt-repository --yes ppa:certbot/certbot
apt update
apt -y install certbot
```

Certbotがドメインの所有権を検証するためには、ドメインがECSインスタンスに向けられていることが重要です。そうでない場合、ドメインの証明書は生成されません。Certbotを使用して証明書を要求します。

`Certbot certonly --webroot -w /var/www/html -d metabase.example.com`

証明書が生成されると、以下のような出力が表示されます。

```
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for metabase.example.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
```

注意事項：

```
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/metabase.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/metabase.example.com/privkey.pem
   ...
```

証明書の有効期限が切れる前に自動更新するためのcronジョブを作成します。

`{ crontab -l; echo '36 2 * * * * /usr/bin/certbot renew --post-hook "systemctl reload nginx"'; } } | crontab -l`

Metabase用リバースプロキシのNginxサーバーブロック設定を新規作成します。

`nano /etc/nginx/sites-available/metabase`

エディタで以下の設定を入力します。例のドメインのすべての出現を実際のドメインに置き換えます。

```
server {
    listen 80;
    server_name metabase.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443;
    server_name metabase.example.com;

    ssl_certificate           /etc/letsencrypt/live/metabase.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/metabase.example.com/privkey.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    gzip  on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
    gzip_buffers 16 8k;
    gzip_disable “MSIE [1-6].(?!.*SV1)”;
    
    access_log  /var/log/nginx/metabase.access.log;
    
location / {
    proxy_pass            http://localhost:3000;        
    proxy_set_header    host $host;
    proxy_http_version  1.1;
    proxy_set_header upgrade $http_upgrade;         
    proxy_set_header connection "upgrade";     
    } 
}
```

実行して設定ファイルを有効化します。

`ln -s /etc/nginx/sites-available/metabase /etc/nginx/sites-enabled/metabase`

nginx -t を実行することで、設定ファイルにエラーがないかどうかを確認できます。

```
root@aliyun:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

設定の変更を適用できるように、Nginxウェブサーバーを再起動します。

`systemctl restart nginx`

これで、お気に入りのブラウザから「[https://metabase.example.com](https://metabase.example.com/?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)」をブラウズして、Metabaseインスタンスにアクセスできるようになりました。Metabaseからのウェルカム画面が表示されるはずです。管理者アカウントと組織に関する基本情報を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/944550a4-9611-c8a1-28b4-c36a3af2d6a6.png)


最初の実行時にデータベースを追加するように促されます。新しいデータベースの追加はスキップしてください。Metabaseにログインすると、同様のダッシュボードが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d43cecbf-7055-ed7d-1832-70920d0fe399.png)

###結論
この詳細なチュートリアルでは、Ubuntu 16.04サーバにMetabase Webアプリケーションをインストールしました。[ApsaraDB for RDS](https://www.alibabacloud.com/product/apsaradb-for-rds?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)上にPostgreSQL RDSインスタンスを作成する方法を見てきました。Nginxをリバースプロキシとして設定し、Let's Encrypt SSLでセキュリティを確保しました。これで、Metabaseインスタンスを組織で使用する準備が整いました。

チュートリアルの[第二部](https://www.alibabacloud.com/blog/database-visualization-using-metabase-part-2---use-metabase-to-get-insights_592508?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)では、サンプルデータベース上でサンプルクエリを実行しながら、Metabaseの基本的な使い方を学んでいきます。また、MetabaseでEメールをセットアップし、パルスを作成する方法を学びます。Metabaseの使用方法については、[公式ユーザーガイド](https://www.metabase.com/docs/latest/users-guide/start.html?spm=a2c65.11461447.0.0.1e0c17a2MfqgQT)を参照してください。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*