IBM Cloud Object Storage内のコンテンツを静的Webサイトとして公開する

# はじめに
IBM Cloud Object Storage(ICOS)に配置した静的コンテンツをWebサイトとして公開する方法です。
ICOSにはWebホスティング機能がない（以下参照）ため、Nginxを前段にたててリバースプロキシとして利用しています。

IBM Cloud Docsより引用 （https://console.bluemix.net/docs/services/cloud-object-storage/iam/public-access.html#static-website-hosting ）
>IBM Cloud Object Storage does not support automatic static website hosting, but it is possible to manually configure a web server and use it to serve publically accessible content hosted in Object Storage. For more information, see this tutorial.

実はこのページ（https://www.ibm.com/blogs/bluemix/2017/03/static-websites-cloud-object-storage-cos/ ）にやり方が書いてあるのですが、情報が古くなっていたので今の環境でやってみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/242688/de031b5a-6a7e-0b32-7f9e-fc361a5e4ca2.png)

なお、記事のなかでは"Bluemix Containers"というサービスを使っているのですが、現在はなくなってIBM Cloud Kubernetes Service（IKS）になっていますので、こちらを使います。

# 前提
- IBM Cloudのアカウント
    - Kubernetesクラスターを作るためにはクレジットカード登録をしたPAYGアカウントが必要です。
- IBM Cloud CLI
    - IKSを操作する際に必要となります。
- s3cmd
    - ICOSを操作する際に使います。
    - 導入についてはここに詳しく書いてあります（https://cloud.ibm.com/docs/services/cloud-object-storage/basics/multipart.html#using-s3cmd-cli- )
- Docker
- Kubernetes CLI(kubectl)
    - Nginxコンテナを作成する際に必要です。


# ICOSのファイルのパブリック公開
IBM Cloudのカタログ（https://cloud.ibm.com/catalog/services/cloud-object-storage ）からサービスを作成します。ライト・プランでOKです。

## バケットの作成
サービスが作成できたらバケットを作成します。「回復力」と「ロケーション」はお好きにどうぞ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/242688/49ceab81-5fe3-620b-94e5-d5be969bd097.png)

## Credential情報の生成
「サービス資格情報」から、新規資格情報を追加します。
あとからs3cmdで操作するために必要なので、オプションのところに{"HMAC":true} と記述するのを忘れないようにしてください。
これを記入することでアクセスキーとシークレットキーが生成されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/242688/d0143e76-18bb-4043-e845-2eed917a6a93.png)

資格情報が作成できたので表示してみると、たしかにアクセスキーとシークレットキーが作られています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/242688/45762c80-0ada-5307-a831-83d1032b8623.png)

## s3cmdの設定
ここからはコマンドでの操作です。
s3cmdでICOS上のファイルを扱えるようにするためにまずは```~/.s3cfg```ファイルを修正します。

以下のコマンドを叩くとアクセスキーやシークレットキー、リージョン、エンドポイントなどを入力していきます。

```
$ s3cmd --configure
```
以下はサンプルの設定例です。
https://gist.githubusercontent.com/greyhoundforty/a4a9d80a942d22a8a7bf838f7abbcab2/raw/05ad584edee4370f4c252e4f747abb118d0075cb/example.s3cfg

エンドポイントは選択した回復力、ロケーションによって異なりますのでご注意を。
ICOSの詳細画面の「エンドポイント」から確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/242688/f2bf529c-0ac2-fd0b-e587-b2ea08318d35.png)

```$ s3cmd ls```とか叩いて作成したバケット一覧が表示されればOKです。

### 新規オブジェクトをアップロードしてPublic公開する
適切なディレクトリで以下のコマンドを叩いてください。ファイル名は必要に応じて変更します。
後半の部分は```s3://バケット名/オブジェクト名```です。

```
$ s3cmd --acl-public put index.html s3://MyBucket/index.html

upload: 'index.html' -> 's3://MyBucket/index.html'  [1 of 1]
 508 of 508   100% in    1s   323.45 B/s  done
Public URL of the object is: http://s3.us-south.objectstorage.softlayer.net/MyBucket/index.html
```

これでICOSへのアップロード&Public公開ができました。最後に書いてあるPublic URLにアクセスすれば
ファイルを見ることができるようになっています（記事内のアドレスはダミーです）。
https://s3.us-south.objectstorage.softlayer.net/MyBucket/index.html

ちなみに、すでにアップロード済みのオブジェクトをPublic公開に変更する場合は以下ようなコマンドになります。

```
s3cmd setacl --acl-public s3://MyBucket/index.html
```

# Nginxをリバースプロキシとして構成する
Nginxはコンテナで作り、それをIKS上で動かします。

## Nginxのコンテナを作成
まずはDockerfileを書きます。

```Dockerfile
FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
```

次にdefault.confファイルを以下のように作ります。

```default.conf
server {
listen 80 default_server;

add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Xss-Protection "1";

location / {
set $s3_bucket 's3.us-south.objectstorage.softlayer.net/MyBucket/index.html';

index index.html;

proxy_http_version 1.1;
proxy_set_header Host $s3_bucket;
proxy_set_header Authorization ”;
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_buffering off;
proxy_intercept_errors on;
resolver 8.8.8.8 valid=300s;
resolver_timeout 10s;

proxy_pass https://$s3_bucket;
}
}
```

2つのファイルが完成したらdocker buildします。

```
$ docker build --tag XXXXXX/my-nginx .
```

ビルドできたらDocker Hubへプッシュ

```
$ docker push XXXXXX/my-nginx
```

## IKS上にコンテナをデプロイ
サクッと公開したいだけなのでyamlファイルは書かずにコマンドで済ませちゃいます。
まずはDeploymentを作成します。

```
$ kubectl run nginx-deployment --image=XXXXXX/my-nginx
```

次に、Serviceのエクスポートです。
元記事ではカスタムドメインを持ち込んでいるので、本来であればIngressでの公開・・といきたいところなのですが諸事情によりNodePortでの公開となります。

```
$ kubectl expose deployment/nginx-deployment --type=NodePort --port=80 --name=nginx-service --target-port=80
```

# 動作確認
IKSのPublic IPとNodeportで公開されているポートを確認してアクセスしてみます。

```
# クラスターのPublic IPの確認
$ ibmcloud ks workers クラスタ名

# NodePortのポート確認
$ kubectl get svc
```

出てきた```http://<IP_address>:<NodePort>```にアクセスすれば、Nginx経由でICOSのファイルが公開されていることが確認できると思います。