【Linux】ネット環境がない(スタンドアロン)サーバーに、パッケージをインストールする方法

# はじめに
本番環境など、セキュリティの観点からグローバルネットワークに繋がっていない、
いわゆるスタンドアロンと言われるサーバーがあります。

そのようなサーバーにライブラリやパッケージを追加でインストールしたい時、
どのようにすればインストールできるのか。

以前の仕事ではまったことがあり、その時の解決方法を少しまとめた形にして記したいと思います。
どなたかの参考になれば、幸いです。

記事の最後に、この方法を自動実行するスクリプトを紹介しています。（Gif画像付き）
私個人が作成した物のため動作を保証するものではありませんが、もし機会があれば利用してみてください。

## 前提条件
記事に使用する単語を以下のように定義します。

|単語 |定義 |
|---|---|
|スタンドアロン環境|グローバルネットワークに繋がらないサーバー。インストール先。|
|ローカルPC|自分の作業用PC。ネットワークには繋がっている。|

## 使用環境
|名称 |OS |バージョン|備考|
|---|---|---|---|
|スタンドアロン環境|CentOS|7|`AWS EC2`(検証用)|
|ローカルPC|macOS|Catalina||
|Dockerコンテナ|CentOS|7||

## 全体の流れ
以下のような流れで行います。

1. ローカルPCでDockerコンテナを立ち上げる
2. Dockerコンテナでパッケージをダウンロード
3. ダウンロード先のフォルダをリポジトリとして作成する
4. 作成したリポジトリをスタンドアロン環境に移す
5. スタンドアロン環境でリポジトリの設定をする
6. スタンドアロン環境でインストールする

記事後半にて、上記の詳細な手順を説明していきます。

Docker環境がない場合、ローカルPCで実行しても可能かもしれません。
しかし、依存関係によってはうまく行かないケースが考えられます。
ほとんど何も入っていない、まっさらな環境を利用することをオススメします。


## 注意点
- スタンドアロン環境の状態によっては、依存関係でインストールに失敗することがあります。
- 依存関係が無く、単一のrpmになるパッケージに関しては、`rpm`コマンドでインストールした方が早いし楽です。
- この方法では、一度に必要なパッケージを全てインストールすることをオススメします。

# 詳細な手順
それでは実際にやっていきましょう！

## 0. スタンドアロン環境準備
検証環境に使用するため、AWS EC2をスタンドアロン環境のサーバーとして用意しました。
グローバルネットワークから隔離するため、ssh(22番ポート)以外の通信はできないようにしています。

↓ スタンドアロン環境で`yum update`を実行した結果
<img width="792" alt="スクリーンショット 2020-02-13 18.11.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533841/9259efea-a3fe-db3b-17a7-deb8703c3818.png">


## 1. ローカルPCでDockerコンテナを立ち上げる
スタンドアロン環境とできるだけ同じ環境のDockerコンテナを立ち上げます。
今回は、CentOS7のコンテナを立ち上げます。
立ち上がったら、そのコンテナの中にアクセスしましょう。

```
$ docker run -itd --name centos7 centos:centos7
$ docker exec -it centos7 bash
```

## 2. Dockerコンテナでパッケージをダウンロード
まずはパッケージのダウンロード先となるディレクトリを作成します。

```
# mkdir standalone_install
```


作成したディレクトリに、スタンドアロン環境に必要なパッケージをまとめてダウンロードします。
今回は、`git`と`iproute2`(ネットワーク系のコマンド詰め合わせ)をまとめてダウンロードします。

`--downloadonly`オプションを付けることで、インストールは行わないでダウンロードだけ実行することが可能です。

```
# yum install -y --downloadonly --downloaddir=standalone_install git iproute2
```

> yum install --downloadonly --downloaddir=\<directory> \<package> [^1]


ダウンロードしたディレクトリの中を見ると、大量の`rpm`ファイルが入っていることがわかります。

<img width="947" alt="スクリーンショット 2020-02-13 19.01.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533841/1ba61f4d-096a-fe8b-2227-7f5d0299e9da.png">


## 3. ダウンロード先のフォルダをリポジトリとして作成する
リポジトリ作成のコマンド`createrepo`をインストールします。

```
# yum install -y createrepo
```

早速インストールした`createrepo`コマンドを使用して、リポジトリを作成します。
ディレクトリを指定して実行するだけで、メタデータが作成されリポジトリとして機能するようになります。

```
# createrepo standalone_install
```

↓ `repodata`が`createrepo`コマンドによって作成されたメタデータです。
<img width="950" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533841/a9068da9-4f16-47e4-6f8c-debfab136753.png">

次の手順でスタンドアロン環境にファイルを移すので、必要であればファイル圧縮をしておきましょう。

## 4. 作成したリポジトリをスタンドアロン環境に移す
`createrepo`コマンドで作成したリポジトリのフォルダを、スタンドアロン環境に移動させます。
今回は、ちょっと面倒ですが以下の手順で移動させます。

1. Dockerコンテナから抜ける
2. DockerコンテナからローカルPCにフォルダをコピー
3. ローカルPCからスタンドアロン環境にフォルダをコピー

```
# exit  ←コンテナから抜けます。Ctrl+DでもOKです。
$ docker cp centos7:/standalone_install/ ./
$ scp -r standalone_install standalone_ec2:/home/centos/
```

## 5. スタンドアロン環境でリポジトリの設定をする
残るはスタンドアロン環境での作業のみとなります。

`.repo`ファイルを作成して、移したリポジトリを設定してあげます。
設定項目は以下になります。

|項目名 |設定項目 |
|---|---|
|name |リポジトリの名前|
|baseurl |リポジトリの実体があるディレクトリのパス|
|gpgcheck | ~~グッピグチェック~~ GPG署名を確認するか否か。 0=false,1=true |

```
$ sudo vi /etc/yum.repo.d/standalone_install.repo
```

```
[standalone_repo]
name=standalone_repo
baseurl=file:///home/centos/standalone_install/
gpgcheck=0
```

※ `file:///`の`/`は3本です。

## 6. スタンドアロン環境でインストールする
`--enablerepo`オプションでリポジトリを指定して、パッケージをインストールします。
その際、外のリポジトリを探しに行かないように`--disablerepo=*`を設定しています。
（`--disablerepo`オプションは、`--enablerepo`より前に設定する必要があります）

```
$ sudo yum install -y --disablerepo=* --enablerepo=standalone_repo git iproute2
```

検証環境(EC2)でもこの方法でインストールすることができました！
（この画像では全く証明になりませんが...笑）
<img width="525" alt="スクリーンショット 2020-02-15 23.08.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533841/90fd6b4d-87a0-eb60-575a-9c24ce13e5ae.png">


# まとめ・おまけ
このインストール方法のキーポイントは、以下になります。

- スタンドアロン環境と同じOS・バージョンのDockerコンテナを使用すること
- `--downloadonly`オプションを使って`rpm`ファイルをダウンロードすること
- `createrepo`コマンドでリポジトリを作成すること
- `.repo`ファイルを作ってリポジトリを設定すること
- `--enablerepo`でリポジトリを指定してインストールすること


記事の冒頭でも紹介しましたが、このインストール方法を自動実行するスクリプトを個人的に作成しました。
Readmeに利用方法を記載していますので、機会があれば利用してみてください。
https://github.com/hesma2/standalone_install

↓動作イメージ（手順1~3を1つのスクリプトで実行しています）
![demo](https://raw.githubusercontent.com/wiki/hesma2/standalone_install/images/standalone_install_demo.gif)


# 参考
- [yum を使用して、パッケージをインストールせずにダウンロードだけ行う](https://access.redhat.com/ja/solutions/395763)
- [yum｜yum リポジトリを作成する](https://kazmax.zpp.jp/linux_beginner/yum_createrepo.html)
- [6.3. YUM と YUM リポジトリの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/sec-configuring_yum_and_yum_repositories)

[^1]: [yum を使用して、パッケージをインストールせずにダウンロードだけ行う](https://access.redhat.com/ja/solutions/395763)