nextcloudサーバーをDockerコンテナで動かす

Docker



以前↓の記事でnextcloudサーバーをRaspberry Pi 4上に構築しました。



ただ、これだとRaspberry PiにOSを入れ直すたびに全工程をやり直す必要があり、面倒です。
 ラズパイで遊ぶ人はわかると思いますが、意外にOSを入れ直す機会は多いです🖥

そこで、今回はそれを解決するための1手段として、Dockerコンテナ上に↑と同じスペックのnextcloudサーバーを簡単に立てられるようにします。
 Dockerやコンテナじゃないとできないというわけではないので、念のため。

この記事はDockerfileでコンテナ環境を構築しています。
docker-compose.ymlでの構築はこちらになります。

システム構成

こんな構成にしました。
データバックアップを考慮して、nextcloud本体とデータディレクトリはホストのディレクトリをマウントするようにしています。

Dockerfileを作ってみた

Dockerfileを作ってgithubに置いてみました。

GitHub - kurofuku/nextcloud-container
Contribute to kurofuku/nextcloud-container development by creating an account on GitHub.



順に解説していきます。

FROM, ENV

FROM		debian:latest

ENV		GID=1000 \
		GROUPNAME=__GROUPNAME__ \
		USERNAME=__USERNAME__ \
		PASSWORD=__PASSWORD__ \
		HOME=/home/__USERNAME__



ベースのイメージはdebianとしています。
自分がUbuntuのaptなどに慣れているのでdebianを選んだだけで、RUNで使っているコマンドやインストールするパッケージが使えるのであればarchやalpineでもいいと思います。

また通常Dockerコンテナではrootユーザーのみですが、それだとセキュリティ的にどうなんだという指摘もあると思いますので、一般ユーザーを作ります。
UIDとGIDはとりあえず1000と決め打ちにしました。

Dockerfile内でユーザー名やグループ名を__USERNAME__や__GROUPNAME__などとしているのは、このDockerfileをgithubに置きたいけどユーザー名やグループ名、パスワードなどをDockerfileに書きたくなかったからです。
後述しますが、sudo docker buildするときにこの辺りの文字列をsedで置換することで、個別の環境に適応させることを狙っています。

RUN

これ移行はイメージ構築のためのRUNですが、長いのでまとまりごとに解説します。

システム更新、ユーザー追加、ロケール設定

RUN			\
# Update to latest
apt -y update && \
apt -y upgrade && \
# Install general packages
apt -y install htop sudo wget ssh apache2 && \
# Add user
groupadd -g ${GID} ${GROUPNAME} && \
useradd -g ${GROUPNAME} -m -s /bin/bash ${USERNAME} && \
echo "${USERNAME}:${PASSWORD}" | chpasswd && \
echo "${USERNAME}  ALL=(ALL)       ALL" >> /etc/sudoers && \
# Configure locale
apt -y install locales && \
sed -i -E 's/# (en_US.UTF-8)/\1/' /etc/locale.gen && \
locale-gen && \
echo "export LANG=en_US.UTF-8" >> ${HOME}/.bashrc && \



まずはお決まりのapt update/upgrade。
その後は独断でよく使うパッケージを入れています。
 htop/sudo/wget/ssh/apache2
nextcloudはapache上にデプロイしていて、apache2も入れます。

お次はユーザー作成です。
対話形式でやりたくないのでuseraddを使っています。

最後はロケール生成と.bashrcへの設定です。
英語のみ実施していますが、日本語など別言語もほしい方は適宜やってみてください。

setup.shの実行

# Setup dotfiles
wget -O setup.sh https://raw.githubusercontent.com/kurofuku/dotfiles/master/setup.sh && \
bash ./setup.sh raspi && \
rm -f ./setup.sh && \



ここではヤッチ独自のセットアップスクリプトであるsetup.shを走らせています。
興味のある方は↓の記事を読んでみてください。



nextcloudに必要なパッケージの追加、HTTPS設定

# Setup packages for nextcloud
apt -y install libapache2-mod-php php-sqlite3 php-zip php-xml php-mbstring php-gd php-curl && \
# Setup HTTPS
sed -i -E 's/#ServerName www.example.com/ServerName __DOMAIN_NAME__/' /etc/apache2/sites-available/000-default.conf && \
apt -y install certbot python-certbot-apache && \



ここでは

nextcloudを動かすために必要なパッケージを入れ、
apacheにサーバー名を設定し、
HTTPS化で使っているLet's Encryptを使うためのパッケージを入れる、

ということをやっています。

データベースはsqliteを使っています。
最初はmysqlで考えていましたが、初期設定及びコンテナを動かすところでmysqldをどう動かそうか悩んでしまい、だったらいっそのことsqliteの方が楽になるんじゃないか、ってことで。

sqliteならデータベースの実態は1つのファイルなので、バックアップなど取り扱いが簡単です。

業務用ならmysqlやpostgresql、SQL Serverを選びたくなりますが、個人用なのでsqliteで十分と判断しました。

mod-securityインストール、設定

# Setup mod-security2
apt -y install libapache2-mod-security2 && \
cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf && \
# Exclude PUT in nextcloud
echo "<Directory /var/www/html/nextcloud/>" > /etc/modsecurity/nextcloud.conf && \
echo "	SecRuleRemoveById 911100" >> /etc/modsecurity/nextcloud.conf && \
echo "</Directory>" >> /etc/modsecurity/nextcloud.conf && \



ここではmod-securityを入れています。
具体的な設定内容などは↓の記事でまとめていますが、ルール911100はnextcloudのソースコードで使っているPUTメソッドの禁止であり、平常動作でも衝突してしまうので、nextcloudのディレクトリではPUTメソッドを許可するようにしています。

SSH設定

# Enable password authentication for SSH
sed -i -e 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
echo "Build complete." 



ここではSSHの設定をしています。
最後に「Build complete.」を表示して終了です。

ENTRYPOINT

ここからはENTRYPOINTです。

ENTRYPOINT	\
# SSHとapache起動
service ssh restart && \
service apache2 restart && \

# HTTPS用証明書取得
certbot run -n --apache --email "__MAIL_ADDRESS__" --agree-tos --domains "__DOMAIN_NAME__" && \

# HTTPS用証明書をwww付ドメイン名に対応させる
certbot certonly -n --expand --webroot -w /var/www/html \
-d "__DOMAIN_NAME__" -d "__WWW_DOMAIN_NAME__" && \

# 暗号スイートを強度高いもののみに制限させる
sed -i -E 's/SSLCipherSuite (.*)/SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:\
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:\
ECDHE-ECDSA-AES128-SHA256/' \
/etc/letsencrypt/options-ssl-apache.conf && \

# SSLとTLS1.0/1.1を禁止させる
sed -i -E 's/SSLProtocol (.*)/SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1/' \
/etc/letsencrypt/options-ssl-apache.conf && \

# apache再起動
service apache2 restart && \
/bin/bash --login



ENTRYPOINTでは

HTTPSに必要な証明書の取得とapacheへの設定をcertbotコマンドで実行し、
暗号スイートを強度の高いものだけに制限し、
apacheを再起動する、

を実行しています。

ENTRYPOINTでHTTPS用の証明書取得を行っているため、コンテナを何ヶ月も動かし続けていると証明書が切れるのでは、と思う方もいると思います。
 Let’s Encryptの証明書期限は3ヶ月だったような気がする。
これは実際そうで、ヤッチが「こっちの方が楽そうだ」と思ったからこのスタイルにしています。

といいますのも、
ヤッチがこのコンテナを動かすと数日で死ぬことが多く、その都度コンテナを再起動します。
コンテナが死ぬ理由はわかっていないですが、ひとまずはコンテナが死ぬことを前提に考える必要がありそうだったので、この運用としました。

コンテナ内でcronするのが本当はいいのでしょうけど、今後の課題とします。

sudo docker build

イメージをビルドするときはこうします。
イメージ名のnextcloud-imageは適宜変更可能です。たぶん。

sedでユーザー名やグループ名、パスワードやドメイン名などを置換し、最後にsudo docker buildに「-」で標準入力から渡します。

# 前やったときのゴミがあれば削除しておく
sudo rm -rf nextcloud && unzip -q latest.zip && sudo chown -R www-data:www-data nextcloud && \
sudo rm -rf nextcloud_data && mkdir nextcloud_data && sudo chown www-data:www-data nextcloud_data && \

# ユーザー名やパスワードをsedで置換し、最後にsudo docker build実行
sed 's/__GROUPNAME__/myuser/' docker-file/Dockerfile.template | sed 's/__USERNAME__/mygroup/' | \
sed 's/__PASSWORD__/mypassword/' | sed 's/__DOMAIN_NAME__/mydomain\.com/' | \
sed 's/__WWW_DOMAIN_NAME__/www\.mydomain\.com/' | sed 's/__MAIL_ADDRESS__/abcde@hotmail\.com/' | \
sudo docker build -t nextcloud-image -



sudo docker run

コンテナ走らせるときはこうします。
nextcloud本体を/var/www/html/nextcloud、nextcloudのデータディレクトリを/var/www/nextcloud_dataに設定しています。
また、–restart=alwaysを指定することで、コンテナが死んだときや電源入れ直し時に自動起動するようにしています。
イメージ名であるnextcloud-imageは適宜変更します。

sudo docker run -dit \
-v `pwd`/nextcloud:/var/www/html/nextcloud \
-v `pwd`/nextcloud_data:/var/www/nextcloud_data \
--restart=always \
-p 80:80 -p 443:443 -p 22:22 \
nextcloud-image



終わりに

いかがでしたか。

各々の好みの問題もありますので、まるまるコピーして使うのは難しいかもです。

ところどころつまみ食いしながら使ってもらえると嬉しいです!

SNSなどでコメントもらえると喜びます!

Comments

タイトルとURLをコピーしました