💽

Synology NASでコンテナベースのWebサービスを提供してみる

2023/09/11に公開

筆者は家庭用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上に構成してみる。

image

やることは下記の通り。

  • ドメイン設定
  • リバースプロキシ設定
  • SSL証明書の取得と設定
  • Private Registryの構築
  • Dockerイメージのビルド、プッシュ
  • Container Managerへのプロジェクトの作成

ドメイン設定

SynologyはDDNSサービスを提供しているため、そちらを使ってもよいが、筆者は既に別の目的で利用しているため、今回はワイルドカードが使えるDDNS Nowでサブドメインを取得して設定してみる。

なお、独自ドメインを使う場合も基本的なやり方は同じである。

コントロールパネルを開き、外部アクセス>DDNSと辿って、 [プロバイダのカスタマイズ] をクリックする。

image

DDNS NowにHTTPリクエストで更新する方法が記載されているので、それに沿ってDDNS NowをDS223jに登録する。

  • サービスプロバイダ: DDNSNow
  • Query URL: https://f5.si/update.php?domain=__USERNAME__&password=__PASSWORD__

image

コントロールパネルを開き、外部アクセス>DDNSと辿って、 [追加] をクリックする。

image

必要事項を入力し、 [OK] をクリックする。

  • サービスプロバイダ: *DDNSNow
  • ホスト名: hogee
  • ユーザー名: hogee
  • パスワード: (パスワード)

image

リバースプロキシ設定

DS223jには標準でnginxによるリバースプロキシ機能が搭載されているのでそちらを設定する。

ログインポータル>詳細設定と辿って、 [リバースプロキシ] をクリックする。

image

[作成] をクリックする。

image

HTTPでアクセスされた場合の設定を行う。

これは次に行うSSL証明書の取得のために必要となる。送り先のポート番号は80にする。

image

合わせてHTTPSでアクセスされた場合の設定を行う。送り先のポート番号は40001にする。

image

上記を含め、計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

image

SSL証明書の取得と設定

次にSSL証明書を取得する。

セキュリティ>証明書と辿って、 [追加] をクリックする。

image

出てきたモーダルダイアログで 新しい証明書を追加してください を選択する。
続いて、 Let's Encryptからの証明書をお受け取りください を選択する。

ドメイン名とサブジェクトの別名を入力する。

  • ドメイン名: hogee.f5.si
  • サブジェクトの別名: registry.hogee.f5.si;todo.hogee.f5.si;todo-api.hogee.f5.si

image

しばらく待つと、証明書が取得されるので、続けて [設定] をクリックする。

image

リバースプロキシで設定したものが表示されるので、作成した証明書を選択して [OK] をクリックする。

image

Private Registryの構築

認証情報の作成

Private Registryは外部公開する必要があるため、Dockerイメージを使用して認証情報を作成する。

以下はLinuxでdockerコマンドを使って認証情報のファイルを作成する例である。 testusertestpassword になっている部分は適宜書き換える。

$ docker run --rm --entrypoint htpasswd httpd -Bbn testuser testpassword > htpasswd

Registry用のディレクトリの準備

次に、File StationからPrivate Registry用、データベース用、プロジェクト用のディレクトリを作成しておく。合わせて、先ほど作成した htpasswd ファイルもアップロードしておく。

image

Container Managerを起動し、レジストリを開き、 registry と検索窓に入力すると、一番上に registry が表示される。それを選択して、すぐ上の [ダウンロード] ボタンをクリックするとタグの選択が出てくるので、そのまま [適用] をクリックする。

image

画面がイメージに切り替わり、イメージのダウンロードが始まるので、終わるのを待つ。

image

ダウンロードが終わったら、コンテナに切り替え、 [作成] をクリックする。

image

設定画面が出てくるため、下記を入力して [次へ] をクリックする。

  • イメージ: 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

image

そのまま [完了] をクリックすると、Registryが起動する。

image

アクセスでき、jsonが返却されることを確認する。
testuser:testpassword の部分は作成した認証情報に書き換える)

$ curl https://testuser:testpassword@registry.hogee.f5.si/v2/_catalog
{"repositories":[]}

Dockerイメージのビルド、プッシュ

今回はアプリケーションの開発が主旨ではないので、他の方が作成されたアプリをお借りする。

https://github.com/el10savio/TODO-Fullstack-App-Go-Gin-Postgres-React/

DS223jのCPUアーキテクチャはarm64 (aarch64)のため、amd64 (x86_64)などのCPUを使っている場合はクロスコンパイルする必要がある。

サーバーアプリのビルド

Dockerfileを書き換える。

TODO-Fullstack-App-Go-Gin-Postgres-React/backend/Dockerfile
-FROM golang:alpine AS builder
+FROM --platform=linux/arm64 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 --from=builder /go/bin/build /go/bin/build
 COPY --from=builder /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

データベースがローカルを参照しているところがあるため書き換える。

TODO-Fullstack-App-Go-Gin-Postgres-React/backend/api/api.go
 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からホスティングする設定に書き換える。

TODO-Fullstack-App-Go-Gin-Postgres-React/frontend/Dockerfile
-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 --from=builder /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.sqlhogee.f5.si のルートディレクトリにアップロードしておく。

image

Container Managerへのプロジェクトの作成

レジストリの登録

プロジェクトでは、docker login ができないことにより認証付きのPrivate Registryから直接イメージをpullできないため、予めイメージをpullしておく必要がある。

画面をレジストリに切り替え、 [設定] をクリックし、更に [追加] をクリックする。

image

用意したPrivate Registryを登録する。

  • サイト情報
    • レジストリ名: hogee.f5.si
    • レジストリURL: https://registry.hogee.f5.si
  • ログイン情報
    • ユーザー名: (htpasswdを作成するときに指定したユーザー名)
    • パスワード: (htpasswdを作成するときに指定したパスワード)

image

[適用] をクリックしたら、追加された行を選択して [使用] をクリックすると✔がつく。

image

pushしたイメージ2つが表示されるので、どちらもダウンロードしておく。

image

プロジェクトの登録

最後に、プロジェクトを作成する。

画面をプロジェクトに切り替え、 [作成] をクリックする。

image

出てきたモーダルに必要情報を入力する。

  • プロジェクト名: 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

image

あとは特に変更せず、 [次へ] をクリックして完了させる。
暫く待つと構築が完了して使用可能になる。

おわりに

https://todo.hogee.f5.si/ にアクセスすると、TODOアプリが使えるようになっている。

image

単なるストレージとしてだけではなく、幅広く活用できそうなプロダクトだと感じた。

Discussion