データバックアップサーバ

データのバックアップサーバを作った。これまでは各マシンに外付け HDD をつけてそこにバックアップしてたけど、バックアップサーバに一元化することにした。バックアップサーバには新しく買った 6TB の外付け HDD を取り付けた。

バックアップの方法はこれまで通り rsync を使うんだけど、ネットワーク越しにバックアップサーバにバックアップすることになる。

具体的な手順は過去記事に譲ろう。

順次バックアップ設定を変えていって、バックアップサーバに集約する。

とすると、さて、外付け HDD が4つ余ることになるんだけど、どうしようか……。

rsyncで別のマシンにファイルをバックアップする

ファイルのバックアップというと、今までは同じマシンの外付けハードディスクに rsync でコピーしていた。こんな感じ。

rsync -av --delete /home/takatoh/sulaiman/ /media/opabinia/backup/sulaiman

これをスクリプトにして cron で自動的にバックアップしていたわけだ。

さて、先日、PC が1台余ったってことを書いた。何に使おうか考えていたんだけどファイルのバックアップサーバにしようと思う。

そこで今日はその前段階として、コピー元のマシン(wplj)から別のマシン(apostrophe)に rsync でファイルをバックアップすることを試してみる。↓このページが参考になった。

 cf. いますぐ実践! Linux システム管理 / Vol.009

前提条件

  • バックアップ元マシン:wplj、ユーザ:takatoh、ディレクトリ:~/sulaiman
  • バックアップ先マシン:apostrophe、ユーザ:sulaiman、ディレクトリ:~/backup/sulaiman

バックアップの方法

別のマシンにバックアップをするのは難しいかと思ったけど、大したことはない。ユーザ名とホスト名を指定してやればいいだけだ。

takatoh@wplj $ rsync -azv -e ssh --delete ~/sulaiman/ sulaiman@apostrophe:~/backup/sulaiman

-z は転送時にファイルを圧縮するオプション。-e ssh は ssh を利用するオプションだ。これで無事にバックアップできる。

ただし、このままでは実行するたびにパスワードを入力しなきゃならない。cron を使って自動でバックアップするには使えない。

sshの鍵を利用

パスワードを入力しないで済むようにするには、あらかじめ両方のマシンに ssh の鍵を仕込んでおけばいい。今回は新たにバップアップ用の鍵を作ることにしよう。

takatoh@wplj $ ssh-keygen -f ~/.ssh/synckey -N ""

これで ~/.ssh ディレクトリに synckey と synckey.pub というファイルができる。前者が秘密鍵、後者が公開鍵だ。この公開鍵をバックアップ先のマシン(apostrophe)にコピーする。

takatoh@wplj $ scp ~/.ssh/synckey.pub sulaiman@apostrophe:~/.ssh/

そして、バップアップ先のマシンで、コピーされた公開鍵(~/.ssh/synckey.pub)を ~/.ssh/authorized_key ファイルに追加する。

sulaiman@apostrophe:~$ cd .ssh
sulaiman@apostrophe:~/.ssh$ cat synckey.pub >> authorized_keys
sulaiman@apostrophe:~/.ssh$ chmod 600 authorized_keys
sulaiman@apostrophe:~/.ssh$ rm synckey.pub

これでパスワードなしでバックアップできるようになったはずだ。つぎのようにする。

takatoh@wplj $ rsync -azv -e "ssh -i ~/.ssh/synckey" --delete ~/sulaiman/ sulaiman@apostrophe:~/backup/sulaiman

OK、うまくいった。これをスクリプトにしてやれば cron で自動化することができる。

DELL製PCにCentOS7をインストールしてもブートできない

昨日の話。サーバにしていた PC がダメになった。しばらく前から異音がしていて、これはもうヤバげだな、という感じではあったんだけど、昨日リブートしてみようと思い立ってそうしてみたら、ダメになった。余計なことはするもんじゃない。

もう少し正確に言うと、OS (CentOS7だ)は起動する。Nginx も起動する。けど、肝心の web アプリが起動しない、という状態。リブートしただけなので、何も変わっていないはずなんだけど、起動しないものは起動しない。そもそも上に書いたとおりハード的にもヤバそうだったので、早々に諦めて、新しいPCに移行することにした。実は、しばらく前から異音が発生していたので新しい PC を買ってあったのだ。

新しい PC は、DELL 製の OptiPlex 3060 Micro という機種。これに CentOS7 をインストールしようというわけだ。BIOS (というか最近のは UEFI というらしい)の設定を変更して外付け DVD ドライブからブートするようにしてインストール。インストール自体は特につまづくこともなく終了(過去記事を見てほしい)。

ところが、DVD を抜いてリブートしてもできない。ブータブルなメディアが見つからない、とかなんとかそんなことを言われる。そんなこと言われても、インストールできたんだからなんとかなるだろう、と思って UEFI の設定を変更しようと試みるも、UEFI というのは Windows 向けの設定になっているし(変更しようにもファイルシステムが見つからないと言われる)、レガシーな BIOS (インストール時にはこちらに設定した)には内部のハードディスクからブートするという選択肢がない。ように見える。

BIOS に内部ハートディスクからブートする機能がないとすると、UEFI を使うしか無いんだけど、どうもググった限りで分かったのは CentOS7 は UEFI に対応していないらしいということと、Ubuntu は対応しているらしい、ということ。

そこで、Ubuntu (18.04 の日本語REMIX版)をインストールしてみた。結果、今度はちゃんとブートするようになった。まだ OS をインストールしただけで、web アプリの構築とかしてないんだけど、今のところ大丈夫そうだ。

というところまでが、昨日の話。今日は web アプリを構築して早くサーバとして復帰させたい……んだけど、今日は時間がないんだよなぁ。

[追記]

何とか、最低限の復旧は果たした。

あと、ホスト名は unclemeat にした。

UbuntuにRMagickをインストール

環境

takatoh@apostrophe $ cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.5 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.5 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
takatoh@apostrophe $ ruby -v
ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]

↓このページによると、ImageMagick がバージョン7以降だと RMagick は使えないらしい。

 cf. RMagickのインストールで奈落に落ちた – Qiita

takatoh@apostrophe $ convert -version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2018-09-28 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib

6.8.9 だ、ラッキー。

依存パッケージとRMagickのインストール

まずは依存パッケージから。

takatoh@apostrophe $ sudo apt install libmagickcore-dev libmagickwand-dev

そして、RMagick。

takatoh@apostrophe $ sudo gem install rmagick
Building native extensions. This could take a while…
Successfully installed rmagick-2.16.0
Parsing documentation for rmagick-2.16.0
Installing ri documentation for rmagick-2.16.0
Done installing documentation for rmagick after 4 seconds
1 gem installed

完了。

Gem in a Boxでオレオレgemサーバをたてる

自分でしか使わない、外部には公開できないような gem がいくつかあるので、gem サーバをたてることにした。Gem in a Box (geminabox)は、プライベートな gem サーバだ。gem コマンドでインストールして、ちょっと設定ファイルを書くだけで使えるようになる。

じゃ、いってみよう。

環境

  • Ubuntu 16.04 LTS
  • Ruby 2.3.1p112

インストールと設定

前述したように gem コマンドでインストールできる。

takatoh@wplj $ sudo gem install geminabox

~/geminabox ディレクトリを作って、設定ファイルを書く。

takatoh@wplj $ mkdir ~/geminabox
takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ vim config.ru

設定ファイルはこんな感じ、っていうかこれだけ。

require "geminabox"

Geminabox.data = "/home/takatoh/geminabox/data"
run Geminabox::Server

gem ファイルが格納される data ディレクトリを作る。

takatoh@wplj $ mkdir data

これで Gem in a Box 自体のインストールと設定は完了。

Supervisord で管理

さて、これをデーモンにする必要があるんだけど、昨日 Supvervisord を試したので今日も同じようにしてみる。設定ファイル /etc/supervisord.d/geminabox.ini をつぎのように書いた。

[program:geminabox]
command=/usr/local/bin/rackup -p 9999
process_name=geminabox
user=takatoh
directory=/home/takatoh/geminabox
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/geminabox/geminabox.log
stdout_logfile_maxbytes=1M
stdout_logfile_backups=7
stdout_capture_maxbytes=1M
redirect_stderr=true

これで OK のはず。動かしてみよう。

takatoh@wplj $ supervisorctl reload
Restarted supervisord
takatoh@wplj $ supervisorctl status
geminabox RUNNING pid 26835, uptime 0:00:08
sulaiman RUNNING pid 26836, uptime 0:00:08

ちゃんと動いてるようだ。

Nginxのバーチャルホスト設定

gembox というホスト名でアクセスできるように Nginx を設定する。/etc/nginx/sites-available/gembox が設定ファイルだ。

upstream geminabox {
    server 127.0.0.1:9999;
}

server {
    # port
    listen      80;

    # server name
    server_name gembox;

    # document root
    root        /home/takatoh/geminabox;

    # index
    #index       index.php index.html index.htm;

    # log files
    access_log /var/log/nginx/gembox/access.log combined;
    error_log  /var/log/nginx/gembox/error.log  warn;

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

 
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://geminabox;
    }
}

/etc/nginx/sites-enabled/gembox にリンクをはる。

takatoh@wplj $ sudo ln -s /etc/nginx/sites-available/gembox sites-enabled/gembox

ログファイル用のディレクトリを作成。

takatoh@wplj $ sudo mkdir /var/log/nginx/gembox

そして、Ngixn をリロード。

takatoh@wplj $ sudo systemctl reload nginx

これで完了。ほかのマシンからブラウザで http://gembox/ にアクセスすると、期待どおり Gem in a Box のページにアクセスできた。

[追記]

アクセスはできたけど、試しに gem ファイルを1つアップロードしてみたら「uninitialized constant Gem::Util」というエラーが出てしまった。なんだこりゃ?

[追記2]

解決編。rubygems 自体が古いのが原因だったようだ。

takatoh@wplj $ sudo gem update --system
takatoh@wplj $ gem -v
3.0.1

念のため、データ置き場を作りなおす。

takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ rm -rf data
takatoh@wplj $ mkdir data

リスタート。

takatoh@wplj $ supervisorctl restart geminabox
geminabox: stopped
geminabox: started

これで無事、オレオレgemをアップロードできるようになった。

Supervisorで自作プログラムをデーモン化

自作のプログラムやスクリプトをデーモン化したい場合がある。でも、デーモンとして動作するようには作っていない……そういう時には Supervisor の出番だ。

Supervisor は Python 製のツールで、デーモンとして動作するように作られていないプログラムでもデーモン化できる。Supervisor 自体は root 権限でデーモンとして動かす必要があるけど、その下にぶら下がるプログラムはユーザー権限で管理できるのがいい点だ。

今日は、Ubuntu マシンの wplj に Supervisor をインストールして、以前 Go で作った画像アップローダを動かしてみる。

環境

  • Ubuntu 16.04 LTS
  • Python 2.7.12

Supervisorのインストールといろいろ下準備

Supervisor 自体は pip でインストールできる。

takatoh@wplj $ sudo pip install supervisor

/etc/supervisord.conf にデフォルトの設定ファイルを生成。

takatoh@wplj $ sudo echo_supervisord_conf > /etc/supervisord.conf
-bash: /etc/supervisord.conf: 許可がありません

あれ、sudo つけてるのになんでだ?よくわからないけど sudo -s してからやってみよう。

takatoh@wplj $ sudo -s
root@wplj # echo_supervisord_conf > /etc/supervisord.conf

今度はできた。つぎ、include 設定ファイル用のディレクトリを作成。

root@wplj # mkdir /etc/supervisord.d

supervisord 自体のはくログ周りの設定。デフォルトでは /tmp/supervisord.log に吐き出すことになっているので、設定ファイル /etc/supervisord.conf を修正して /var/log/supervisord.log に吐くようにする。

[supervisord]
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisord.log

PID ファイルの設定。/var/run 以下に置くように変更。

;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid

/etc/supervisord.d 以下のファイルを include するように変更。これで設定ファイルの修正は終了。

[include]
files = supervisord.d/*.ini

supervisord自体のサービス登録

/etc/systemd/system/supervisord.service ファイルを作成する。

[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org/
After=network.target

[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s

[Install]
WantedBy=multi-user.target

起動と自動起動の登録

root@wplj # systemctl start supervisord
root@wplj # systemctl enable supervisord.service
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /etc/systemd/system/supervisord.service.

自作プログラムの配置

Go で作った画像アップローダ sulaiman を配置する。こんなふうにした。

takatoh@wplj $ tree ~/sulaiman
/home/takatoh/sulaiman
├── config.json
├── photos
│   ├── img
│   └── thumb
├── static
│   ├── css
│   │   └── style.css
│   ├── html
│   │   └── index.html
│   └── js
│   └── sulaiman.js
└── sulaiman

試しに動かしてみる。

takatoh@wplj $ ./sulaiman
_ _ / // /
/ // / \/ _ \
//__////_/ v3.3.5
High performance, minimalist Go web framework
https://echo.labstack.com
_________________________________O/_

O\
⇨ http server started on [::]:9099

大丈夫そうだ。

プロセス管理登録と起動確認

配置したプログラムを supervisord の管理下に登録する。/etc/supervisord.d 以下に設定ファイル sulaiman.ini を作る。

[program:sulaiman]
command=/home/takatoh/sulaiman/sulaiman
process_name=sulaiman
user=takatoh
directory=/home/takatoh/sulaiman
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/sulaiman/sulaiman.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=7
stdout_capture_maxbytes=1MB
redirect_stderr=true

これで OK のはずだ。確認してみよう。

takatoh@wplj $ supervisorctl start sulaiman
error: , [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 228

はぁ?どういうこと?

問題解決

ソケット周りでエラーが出てるようだ。権限がないとかいってる。supervisord の設定ファイルを眺めてみると、ソケットファイルのモードを設定する項目が見つかった。これを変更してみよう。

[unix_http_server]<br>file=/tmp/supervisor.sock   ; the path to the socket file<br>;chmod=0700                 ; socket file mode (default 0700)<br>chmod=0777

supervisord をリロード。

takatoh@wplj $ sudo systemctl reload supervisord

確認。

takatoh@wplj $ supervisorctl status sulaiman
sulaiman RUNNING pid 19356, uptime 0:00:22

こんどは OK。

これで、プログラムやスクリプトを簡単にデーモン化できるようになった。

参考ページ

 cf. Supervisorで簡単にデーモン化 – Qiita

UbuntuでBitbucketからgit cloneできなくなったのはIPv6のせいらしい

一昨日の問題、解決した。どうも IPv6 で Bitbucket に接続しようとしていたかららしい。↓このページが役に立った。

 cf. 突然Bitbucketにgitで接続できなくなったらIPv6関連を疑ってみるとよいかも 2016/07/20 – Qiita

IPv4 で接続するようにするには、下のような ~/.ssh/config ファイルを作ってやればいい。

これで bitbucket.org には IPv4 で接続するようになる。

takatoh@apostrophe $ git clone git@bitbucket.org:takatoh/grp.git
Cloning into 'grp'...
remote: Counting objects: 638, done.
remote: Compressing objects: 100% (392/392), done.
remote: Total 638 (delta 382), reused 343 (delta 229)
Receiving objects: 100% (638/638), 509.65 KiB | 658.00 KiB/s, done.
Resolving deltas: 100% (382/382), done.
Checking connectivity... done.

できた。

UbuntuでBitbucketからgit cloneできなくなった

今朝試したら、SSH での git clonegit pull ができなくなっていた。HTTPS では clone できる。git push は試してない。
また、Windows マシンでは SSH で問題なく clone できる。

SSH の鍵を変えたわけでも、他の設定を変えたわけでもない。確か先週は普通にできたはずだ。
GitHub では問題ない。

SSH の鍵を登録しなおしてもダメ。どうすりゃいいんだ?

症状はこんな感じ。Bitbucket。

takatoh@apostrophe $ git clone git@bitbucket.org:takatoh/grp.git
Cloning into 'grp'...
Connection to bitbucket.org closed by remote host.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Github は大丈夫。

takatoh@apostrophe $ git clone git@github.com:takatoh/jscale.git
Cloning into 'jscale'...
remote: Enumerating objects: 39, done.
remote: Counting objects: 100% (39/39), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 274 (delta 19), reused 36 (delta 19), pack-reused 235
Receiving objects: 100% (274/274), 34.27 KiB | 0 bytes/s, done.
Resolving deltas: 100% (115/115), done.
Checking connectivity... done.

Ubuntu:ホスト名を変更

hostnamectl コマンドを使う。
引数無しで使うと、現在の情報を表示してくれる。

takatoh@envelopes $ hostnamectl
   Static hostname: envelopes
         Icon name: computer-desktop
           Chassis: desktop
        Machine ID: 51e97893a0e54d888a7bc435e3cb10be
           Boot ID: 528cc17f21ef4185b0697228e4d092b5
  Operating System: Ubuntu 16.04.5 LTS
            Kernel: Linux 4.4.0-133-generic
      Architecture: x86-64

hostnamectl set-hostname コマンドでホスト名変更。

takatoh@envelopes $ sudo hostnamectl set-hostname apostrophe
[sudo] takatoh のパスワード:

確認。

takatoh@envelopes $ hostnamectl
   Static hostname: apostrophe
         Icon name: computer-desktop
           Chassis: desktop
        Machine ID: 51e97893a0e54d888a7bc435e3cb10be
           Boot ID: 528cc17f21ef4185b0697228e4d092b5
  Operating System: Ubuntu 16.04.5 LTS
            Kernel: Linux 4.4.0-133-generic
      Architecture: x86-64

ちゃんと変わっている。

/etc/hosts ファイルを編集。

ネットワークの再起動。

takatoh@envelopes $ sudo service networking restart

これでOK。プロンプトのホスト名が変わっていないけど、これは端末を起動し直すと直る。