以前↓の記事でnextcloudサーバーをRaspberry Pi 4上に構築しました。
ただ、これだとRaspberry PiにOSを入れ直すたびに全工程をやり直す必要があり、面倒です。
ラズパイで遊ぶ人はわかると思いますが、意外にOSを入れ直す機会は多いです🖥
そこで、今回はそれを解決するための1手段として、Dockerコンテナ上に↑と同じスペックのnextcloudサーバーを簡単に立てられるようにします。
Dockerやコンテナじゃないとできないというわけではないので、念のため。
この記事はDockerfileでコンテナ環境を構築しています。
docker-compose.ymlでの構築はこちらになります。
システム構成
こんな構成にしました。
データバックアップを考慮して、nextcloud本体とデータディレクトリはホストのディレクトリをマウントするようにしています。
Dockerfileを作ってみた
Dockerfileを作って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