Synology NASでコンテナベースのWebサービスを提供してみる
筆者は家庭用NASとしてSynology製のDS218jを長らく愛用していたが、 この度SynologyからDS223jがリリースされたため、買い替えて遊んでみることにした。
Synology NASについて
Synologyは様々なタイプのNASをリリースしている。特に家庭向けとしてはタワー型のDisk Station(DS)が扱いやすい。
家庭向けのシリーズとしては大きくPlus, Value, Jの3シリーズがある。
シリーズ | モデル | 2ベイ現行機種(2023/9/9現在) |
---|---|---|
Plus | ハイエンド | DS224+ |
Value | スタンダード | DS223 |
J | エントリー | DS223j |
特にDS223jは、エントリーモデルでありながら、スタンダードモデルと比べても遜色ない性能に仕上がっている点が気に入り、今回買い換えることにした。
以下に簡単な比較を載せておく。
- | DS218j | DS223j | DS223 |
---|---|---|---|
CPU | Marvell Armada 385 88F6820 | Realtek RTD1619B | Realtek RTD1619B |
CPUアーキテクチャ | 32bit ARMv7 | 64bit ARMv8 | 64bit ARMv8 |
CPU性能 | 2コア 1.3GHz | 4コア 1.7GHz | 4コア 1.7GHz |
メモリ | DDR3 512MB | DDR4 1GB | DDR4 2GB |
Btrfs対応 | x | o | o |
Container Manager | x | o | o |
Webサービス提供のためにやること
どんなシステム構成にするかで、DS223jで使うパッケージが変わる。
Web Station
下記のシステム構成で事足りる場合は、Web Stationを使うだけで実現可能。
- 静的コンテンツ(HTML, JS, CSS)のみの配信
- PHP7, PHP8, Perlを使った動的ページの配信
- データストアにMySQLを使ったサービスの提供
メリットは下記の通り。
- Synologyパッケージだけで完結できるためセットアップが比較的簡単
Container Manager
Web Stationでは選べるシステム構成に制約があるため、自由にシステムを構成したい場合はContainer Managerを使った方法になる。
メリットは下記の通り。
- Dockerイメージで動かせるものなら何でも動くため、柔軟にシステムを構成することが可能
なお、Container Managerを使う場合、Dockerイメージの利用方法についても2種類ある。
- (A) DS223j上でDockerイメージを作成して使用する
- (B) DS223j以外の環境で作成したDockerイメージをpullして使用する
Aの方法はBの方法に比べ簡単だが、DS223jの性能はパソコンに比べ大幅に劣るため、Dockerイメージを作成するのに非常に時間がかかる。そこで、今回はBの方法でやってみる。
システム構成図
今回はチュートリアルでよくあるTODO管理サービスを提供してみる。下記のシステムをDS223j上に構成してみる。
やることは下記の通り。
- ドメイン設定
- リバースプロキシ設定
- SSL証明書の取得と設定
- Private Registryの構築
- Dockerイメージのビルド、プッシュ
- Container Managerへのプロジェクトの作成
ドメイン設定
SynologyはDDNSサービスを提供しているため、そちらを使ってもよいが、筆者は既に別の目的で利用しているため、今回はワイルドカードが使えるDDNS Nowでサブドメインを取得して設定してみる。
なお、独自ドメインを使う場合も基本的なやり方は同じである。
コントロールパネルを開き、外部アクセス>DDNSと辿って、 [プロバイダのカスタマイズ]
をクリックする。
DDNS NowにHTTPリクエストで更新する方法が記載されているので、それに沿ってDDNS NowをDS223jに登録する。
- サービスプロバイダ:
DDNSNow
- Query URL:
https://f5.si/update.php?domain=__USERNAME__&password=__PASSWORD__
コントロールパネルを開き、外部アクセス>DDNSと辿って、 [追加]
をクリックする。
必要事項を入力し、 [OK]
をクリックする。
- サービスプロバイダ:
*DDNSNow
- ホスト名:
hogee
- ユーザー名:
hogee
- パスワード: (パスワード)
リバースプロキシ設定
DS223jには標準でnginxによるリバースプロキシ機能が搭載されているのでそちらを設定する。
ログインポータル>詳細設定と辿って、 [リバースプロキシ]
をクリックする。
[作成]
をクリックする。
HTTPでアクセスされた場合の設定を行う。
これは次に行うSSL証明書の取得のために必要となる。送り先のポート番号は80にする。
合わせてHTTPSでアクセスされた場合の設定を行う。送り先のポート番号は40001にする。
上記を含め、計7つを設定する。
Target プロトコル |
Target ホスト名 |
Target ポート |
送り先 プロトコル |
送り先 ホスト名 |
送り先 ポート |
---|---|---|---|---|---|
HTTP | hogee.f5.si | 80 | HTTP | localhost | 80 |
HTTP | registry.hogee.f5.si | 80 | HTTP | localhost | 80 |
HTTPS | registry.hogee.f5.si | 443 | HTTP | localhost | 40001 |
HTTP | todo.hogee.f5.si | 80 | HTTP | localhost | 80 |
HTTPS | todo.hogee.f5.si | 443 | HTTP | localhost | 40002 |
HTTP | todo-api.hogee.f5.si | 80 | HTTP | localhost | 80 |
HTTPS | todo-api.hogee.f5.si | 443 | HTTP | localhost | 40003 |
SSL証明書の取得と設定
次にSSL証明書を取得する。
セキュリティ>証明書と辿って、 [追加]
をクリックする。
出てきたモーダルダイアログで 新しい証明書を追加してください
を選択する。
続いて、 Let's Encryptからの証明書をお受け取りください
を選択する。
ドメイン名とサブジェクトの別名を入力する。
- ドメイン名:
hogee.f5.si
- サブジェクトの別名:
registry.hogee.f5.si;todo.hogee.f5.si;todo-api.hogee.f5.si
しばらく待つと、証明書が取得されるので、続けて [設定]
をクリックする。
リバースプロキシで設定したものが表示されるので、作成した証明書を選択して [OK]
をクリックする。
Private Registryの構築
認証情報の作成
Private Registryは外部公開する必要があるため、Dockerイメージを使用して認証情報を作成する。
以下はLinuxでdockerコマンドを使って認証情報のファイルを作成する例である。 testuser
と testpassword
になっている部分は適宜書き換える。
$ docker run --rm --entrypoint htpasswd httpd -Bbn testuser testpassword > htpasswd
Registry用のディレクトリの準備
次に、File StationからPrivate Registry用、データベース用、プロジェクト用のディレクトリを作成しておく。合わせて、先ほど作成した htpasswd
ファイルもアップロードしておく。
Container Managerを起動し、レジストリを開き、 registry
と検索窓に入力すると、一番上に registry
が表示される。それを選択して、すぐ上の [ダウンロード]
ボタンをクリックするとタグの選択が出てくるので、そのまま [適用]
をクリックする。
画面がイメージに切り替わり、イメージのダウンロードが始まるので、終わるのを待つ。
ダウンロードが終わったら、コンテナに切り替え、 [作成]
をクリックする。
設定画面が出てくるため、下記を入力して [次へ]
をクリックする。
- イメージ:
registry:latest
- コンテナ名:
registry
続けて、下記の通りコンテナの設定を行い、 [次へ]
をクリックする。
- ポート設定
-
40001
,5000
,TCP
-
- ボリューム設定
- フォルダ,
/hogee.f5.si/registry
,/var/lib/registry
,読み取り/書き込み
- ファイル,
/hogee.f5.si/htpasswd
,/auth/htpasswd
,読み取り専用
- フォルダ,
- 環境
-
REGISTRY_AUTH
,htpasswd
-
REGISTRY_AUTH_HTPASSWD_REALM
,Registry Realm
-
REGISTRY_AUTH_HTPASSWD_PATH
,/auth/htpasswd
-
そのまま [完了]
をクリックすると、Registryが起動する。
アクセスでき、jsonが返却されることを確認する。
(testuser:testpassword
の部分は作成した認証情報に書き換える)
$ curl https://testuser:testpassword@registry.hogee.f5.si/v2/_catalog
{"repositories":[]}
Dockerイメージのビルド、プッシュ
今回はアプリケーションの開発が主旨ではないので、他の方が作成されたアプリをお借りする。
DS223jのCPUアーキテクチャはarm64 (aarch64)のため、amd64 (x86_64)などのCPUを使っている場合はクロスコンパイルする必要がある。
サーバーアプリのビルド
Dockerfileを書き換える。
-FROM golang:alpine AS builder
+FROM golang:alpine AS builder
RUN apk update && apk add --no-cache git
RUN mkdir /build
WORKDIR /build
COPY . .
RUN go mod download
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -a -installsuffix cgo -o /go/bin/build
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -v -a -installsuffix cgo -o /go/bin/build
FROM scratch
COPY /go/bin/build /go/bin/build
COPY /build/wait-for-it.sh ./wait-for-it.sh
CMD ["chmod", "+x", "wait-for-it.sh"]
CMD ["./wait-for-it.sh", "db:5432", "--"]
ENTRYPOINT ["/go/bin/build"]
EXPOSE 8081
データベースがローカルを参照しているところがあるため書き換える。
func SetupPostgres() {
- // db, err = sql.Open("postgres", "postgres://postgres:password@postgres/todo?sslmode=disable")
+ db, err = sql.Open("postgres", "postgres://postgres:password@postgres/todo?sslmode=disable")
// when running locally
- db, err = sql.Open("postgres", "postgres://postgres:password@localhost/todo?sslmode=disable")
+ // db, err = sql.Open("postgres", "postgres://postgres:password@localhost/todo?sslmode=disable")
if err != nil {
fmt.Println(err.Error())
}
buildxを使ってビルドし、プッシュする。
[~/TODO-Fullstack-App-Go-Gin-Postgres-React]$ docker login registry.hogee.f5.si
[~/TODO-Fullstack-App-Go-Gin-Postgres-React]$ cd backend
[~/TODO-Fullstack-App-Go-Gin-Postgres-React/backend]$ docker buildx build --platform linux/arm64 --push -t registry.hogee.f5.si/todo-backend:1.0.0 .
フロントアプリのビルド
Dockerfileはdevモードで起動する設定になっているため、prodモードでビルドし、nginxからホスティングする設定に書き換える。
-FROM node:8
+FROM node:18 AS builder
WORKDIR /app
COPY . ./
RUN npm install --silent
+RUN npm run build
+
+FROM arm64v8/nginx
-EXPOSE 3000
+COPY /app/build /usr/share/nginx/html
-CMD ["npm", "start"]
+EXPOSE 80
また、 http://localhost:8081
とソースコードに書かれているところが4ヶ所あるため、全て https://todo-api.hogee.f5.si
に書き換える。
フロントエンドは通常通りビルドし、プッシュする。
[~/TODO-Fullstack-App-Go-Gin-Postgres-React/backend]$ cd ../frontend
[~/TODO-Fullstack-App-Go-Gin-Postgres-React/frontend]$ docker build --push -t registry.hogee.f5.si/todo-frontend:1.0.0 .
Private Registryに登録されていることを確認する。
$ curl https://testuser:testpassword@registry.hogee.f5.si/v2/_catalog
{"repositories":["todo-backend","todo-frontend"]}
データベースの設定
File Stationから TODO-Fullstack-App-Go-Gin-Postgres-React/database/psql_dump.sql
をhogee.f5.si
のルートディレクトリにアップロードしておく。
Container Managerへのプロジェクトの作成
レジストリの登録
プロジェクトでは、docker login
ができないことにより認証付きのPrivate Registryから直接イメージをpullできないため、予めイメージをpullしておく必要がある。
画面をレジストリに切り替え、 [設定]
をクリックし、更に [追加]
をクリックする。
用意したPrivate Registryを登録する。
- サイト情報
- レジストリ名:
hogee.f5.si
- レジストリURL:
https://registry.hogee.f5.si
- レジストリ名:
- ログイン情報
- ユーザー名: (htpasswdを作成するときに指定したユーザー名)
- パスワード: (htpasswdを作成するときに指定したパスワード)
[適用]
をクリックしたら、追加された行を選択して [使用]
をクリックすると✔がつく。
pushしたイメージ2つが表示されるので、どちらもダウンロードしておく。
プロジェクトの登録
最後に、プロジェクトを作成する。
画面をプロジェクトに切り替え、 [作成]
をクリックする。
出てきたモーダルに必要情報を入力する。
- プロジェクト名:
todo
- パス:
/hogee.f5.si/todo
- ソース: docker-compose.ymlを作成
- 下記を入力
version: "3"
services:
postgres:
image: postgres
environment:
POSTGRES_DB: todo
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- /volume1/hogee.f5.si/psql_dump.sql:/docker-entrypoint-initdb.d/psql_dump.sql:ro
ports:
- 5432
go-api:
image: registry.hogee.f5.si/todo-backend:1.0.0
ports:
- 40003:8081
depends_on:
- postgres
links:
- postgres
react-app:
image: registry.hogee.f5.si/todo-frontend:1.0.0
ports:
- 40002:80
あとは特に変更せず、 [次へ]
をクリックして完了させる。
暫く待つと構築が完了して使用可能になる。
おわりに
https://todo.hogee.f5.si/ にアクセスすると、TODOアプリが使えるようになっている。
単なるストレージとしてだけではなく、幅広く活用できそうなプロダクトだと感じた。
Discussion