このメモは

社内用資料を書くためのメモだったものを Qiita に UP しちゃえ程度に書いているので割と適当です。

前提

本体:

Redmine 2.6.5.stable

プラグイン:

Redmine Bitbucket plugin 1.0.0

https://bitbucket.org/steveqx/redmine_bitbucket

プラグイン導入時の前提として、一度 Redmine を実行しているユーザーから、bitbucket に

鍵認証でログインする必要がある。

(= SSH 鍵でログイン出来る状態にまで Redmine サーバー、Bitbucket の設定が必要。メモでは割愛)

Redmine 側の設定

  • 設定 → リポジトリタブの一番下、新しいリポジトリをクリック
  • バージョン管理システム git を選択
  • リポジトリのパスに git@bitbucket.org:ownername/[bitbucket のプロジェクト識別子].git

#例えば、git@bitbucket.org:yourname/projectname.git

Bitbucket 側の設定(フック)

  • BitBucket のプロジェクトの設定(左下の歯車アイコン)を開く
  • フックを選んで、Select a hook 欄から  POST  を選択
  • URL に http://[redmine サーバー]/hooks/bitbucket/[redmine のプロジェクト識別子]?key=[redmine の API キー(管理ページで作成する)] を入力

結果

BitBucket に push すると自動的に Redmine がレポジトリ内容を再取得しに行くようになる。

はじめに

この手順は検証されていません。なので、誤りが指摘しやすいようにできるだけ裏の考え方も記載していきます。個人がやるような、それほど大きくないインスタンスを前提に考えてみました。

閉鎖しようと思ったとき

まず、本当に閉鎖するのかどうかを考えましょう。

頭に血が登ったり、心が折れたりした状態であれば、発表は 2 日くらい待ちましょう。

勢いでインスタンスを閉鎖してもあまり良いことはありません。

閉鎖 or 移譲?

インスタンスの運営は、サーバーごと譲り渡すか、DB、.env ファイル、メディア、ドメイン等を譲渡することで移譲できます。が、移譲する相手が気に入らないユーザーもいる可能性があるので、

移行期間を設けて、移行期間はアカウント削除を可能にした上で移譲等、きめ細かい対応をする必要があるかもしれません。

(mstdn.jp は何度か移譲されているので参考になるかもしれません)

正直、運営者が変わるのであれば新しいインスタンスを別ドメインで立ててしまって、エクスポート/インポート+引っ越しを呼びかけた方が楽だと思います。

手順

閉鎖を決めたとき

閉鎖をアナウンスします。移転先がある場合(後継インスタンスがある場合)はそちらもアナウンスします。ここから、エクスポートが実行されまくるため DB、Sidekiq の負荷が上がるはずです。

規模によりますが 1 週間から長くても 2 週間くらい取れば OK だと思います。

あまり長くとってもお通夜モードが続いてしまうので。ただし、LTL メインで運用されているインスタンスの場合、エクスポート等はギリギリまで実行されない可能性が高いです。(エクスポートして他インスタンスに移ると LTL が見えなくなるため)

閉鎖日まで

エクスポートはお早めに!というアナウンスを続けます。そして閉鎖への準備を行います。

閉鎖のとき

Web へのアクセス停止

とりあえず、フロントのリバースプロキシ(nginx/apache)の設定を変更して、メディア以外へのアクセスに対して 410 Gone を返すように変更します。

この時点では、DB、Sidekiq、メディア、メールサーバー等は停止しません。

これらはまだ後続の処理で必要だからです。

閉鎖後のエクスポートの依頼

断っても良いですが、 tootctl account backup [accountname] を実行することで

管理者側から実行することもできます。出力完了後にメールが飛ぶのでそこからダウンロードが可能です。メール内にバックアップzipへのURLが記述されているのでそこからダウンロード可能。メディア(S3)サーバーが生きていればOKなのでこれで対応可能です。

閉鎖日以降

当日にやる必要はありません。翌日以降で十分です。

エクスポートジョブがないことを確認

閉鎖直前にエクスポートを実行したユーザーのエクスポートが完了していない可能性があるためです。エクスポートの実行には DB、Sidekiq が必要です。エクスポートされた圧縮ファイルの保存と配布にはメディアサーバーが必要です。

(S3 を使わない設定の場合は、nginx でメディアへのアクセスだけは通すようにする必要があります。

エクスポートが完了したタイミングでユーザーにはメールが送信されるのでメールサーバーも停止できません。

エクスポートの実行状況は、DB の backups テーブルを参照するとわかります。

select * from backups where processed <> 't'; を実行して 1 行でも帰ってきた場合は、まだ完了していないエクスポートがあります。完了するまで待ちましょう。

また、完了後もそのユーザーがエクスポートしたファイルをダウンロードする時間が必要なことを忘れないでください。

…といっても閉鎖までに間に合わなかったら諦めて。というポリシーもアリだとは思います。

自爆コマンドを投入する

tootctl self-destruct を Web サーバーで実行します。

おそらく、時間のかかる処理になると思われます。完了まで首を長くして待ちます。

(help に always interactive and requires confirmation twice と書かれているので、相当な確認があると思われます。)

とはいえ、410 Gone を返している時点でそのインスタンスは無くなったものとして扱われはじめるので、実行するしかありません。

使っている FQDN で再度 Fediverse に参加できるかどうかも怪しいです。

(サブドメイン違い等、いくらでも手はありますが。)

※ self-destruct していれば可能なはずだけれども、たまたま self-destruct 時にダウンしていたインスタンスがあった場合、同じ FQDN で何かのインスタンスを立てた場合問題が起きるでしょう

自爆後

  • 1~2 週間は 410 Gone を返し続けるようにします。nginx/apache のサーバー以外は停止できます。
  • DB のダンプはしばらくの間持っておいた方が良いかもしれません。(問い合わせ対応)
  • ドメインに関しては不要になったとしてもある程度の期間は寝かせたほうが良いです。(同じドメインでアダルトサイトが出来てしまうと悲しいので)

蛇足

某インスタンスの閉鎖に伴って色々と調べたのでその結果を出力しただけという説がある。

なにより検証していないので多分これで良いんじゃないか。というレベルだと思ってください。

self-destruct するのであれば 410 Gone を返す期間は短くてもよさそうな気がするし、このあたりはやってみないと色々とわからないことが多い気がする。

お引越しの告知とかを考えると、閉鎖を決めたあと一旦停止してその間に管理者以外のアカウントのログインを止めた状態でしばらく動かしたほうが良いような気もするし(ログインできちゃうと閉鎖ってなんなの?ってなっちゃうので)、閉鎖に関してはこれと行ったお作法がまだ確立してないし、確立することも無いのではないかなぁという感想。

環境

SpringBoot 1.5.4

Apache 2.4 (リバースプロクシとして)

問題点

フォームを GET で送信してしまうと、(これ自体が問題なんですが)

URL の文字数が 1000 文字を超えてしまうことがあります。その場合、題記のエラーが発生します。

本来は、アプリケーションを改修すべきですが、それまでの間に合わせとして設定変更で逃げる

場合の手法をメモします。

考え方

Request-URI Too Large エラーを出す所は二箇所あります。

それぞれに対して設定の変更が必要です。

1. Apache

  1. SpringBoot 内蔵の Tomcat

Apache の設定変更

http.conf に以下の行を加えます。

1
LimitRequestLine 81920

注意:この設定はメモリ使用量に直結するようです。また、長い URL をエラーにしているのは、

セキュリティ対策の部分があるようなので、設定変更時はご注意下さい。

Springboot 内蔵 Tomcat の設定変更

application.yml に以下の設定を追加します。

1
server.max-http-header-size:  81920

リミットの値は、Apache と Springboot 内蔵 Tomcat で合わせておくとよいでしょう。

以上です。

蛇足

そもそも、よほどの理由がなければ Form を GET するのはやめた方が無難です。

特に、データ数が可変な場合は実運用フェイズでいきなりこのエラーに遭遇するので、かなり最悪です。

はじめに

Spring Boot 1.2.5 を使いはじめてハマった事をメモします。

既にご存じかとは思いますが、以下の Qiita がとても良くまとまっているので

ご紹介します。

#1.2.8 でも同じようにハマれるのを確認しています

SpringBoot(with Thymeleaf)チートシート[随時更新]

http://qiita.com/uzresk/items/31a4585f7828c4a9334f

Whitelabel Error Page を置き換えたい

エラーメッセージだけを読むと、適当なコントローラーをつくって

/error のリクエストマッピングを作成すればよさそうに思えるが、

実際やってみると、マッピングが重複している的なエラーで起動すらできなくなる。

正解は、 /error をマッピングする Controller は ErrorController を

継承しなければならない。

こんな感じ。このコントローラーにエラーじゃないマッピングを含むことは OK。

当然だが、コンポーネントスキャンの範囲内に作らないとダメ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<code class="language-java">@Controller
public class ErrController implements ErrorController {

private static final String PATH = "/error";

@RequestMapping("/404")
String notFoundError() {
return "error/404"; // templates/error/404.html
}

@RequestMapping(PATH)
String home() {
return "error/general";
}

@Override
public String getErrorPath() {
return PATH;
}

}

実は

/template/error.html を作れば自動的にそれが使用される。

※ 少なくとも Springboot 1.3.5 で確認

2017/01/27 追記

コメントでご指摘頂きましたが、 error.html  を作成するとエラーページが置き換わるのは、Thymeleaf を

使用している時のみとのこと。 @syukai さんご指摘ありがとうございました。

独自の Formatter を追加したい

Formatter を作って、そのクラスに @Component を付けるだけ。

@ComponentScan 範囲にいれば、自動的に登録される。

ググると FormattingConversionServiceFactoryBean 使って登録みたいな

事が書いてあるが、Springboot では自動登録される。

#逆に、自動登録されては困るときは色々と考えないといけないんでしょう

Form Validation をしたいがフォーム View 表示の為に必要なデータがある

これ、意外とどこにも無くてハマったのですが、Form Validation は普通に

Springboot に付いてます。カスタムバリデーションも書けます。

それは良いけれど、フォーム画面を表示するのに model に何かをセットしないと

いけない場合の事は意外と書かれてません。これで正しいのかはわかりませんが、

フォーム表示時のメソッドを普通のメソッドとして呼び出せば上手くいきます。

親切なことに、フォームオブジェクト上のバリデーションに失敗した項目は

null が入っていますが、それを上書きして別の値を入れたとしても無視され、

入力した(結果エラーとなった値)が画面に表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Controller
// フォーム表示
@RequestMapping(value="", method = RequestMethod.GET)
String showForm(@ModelAttribute TestForm form, Model model) {
// フォームに初期値をセット
form.setValue("default");

model.addAttribute("dbdata", hoge.getData());
return "testview";
}

@RequestMapping(value="", method = RequestMethod.POST)
String formPost(@ModelAttribute TestForm form, BindingResult result,Model model) {

if (result.hasErrors()) {
// ここでmodel.addAttributeしないといけないが、
// 処理としては普通に画面を表示するときと同じ場合なので同じことを書きたくない

// 良さそうな例
// 普通にメソッドとして呼べば良い
return showForm(form, model);

// ダメだったパターン(リダイレクト)
return "redirect:/testForm"; // 入力エラーの値が引き継がれない

// ダメだったパターン2
return "redirect:testview"; // modelの値が引き継がれない(当然)

}

(略)
return "completeview";
}

1
2
3
4
5
6
7
8
<form method="post" th:action="@{/test}"
th:object="${testForm}">

<input type="text" name="value" class="form-control"
th:field="*{value}" />
エラー表示は省略。
</form>

ControllerAdvice で例外を拾って処理をしたらステータスコードが 405

@ResponseBody の付け忘れ。これが付いてないとテンプレートを探しに行って

しまっている模様。

1
`o.s.web.servlet.PageNotFound : Request method 'POST' not supported

これ、 @ResponseStatus を平然と無視するのでかなり焦った。

RestController で Ajax でリクエストする API を作ったが実装部より前で例外

CSRF フィルタに引っかかってないかチェック。

Java 8 Date and Time を JSON にシリアライズするとき例外

jackson JSR-310 を入れれば良い。

pom.xml に以下を追加

1
2
3
4
      <dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

バリデーションエラー時、 input type=”password” の項目の値が空になる

セキュリティ的にあえて復元しないようになっているのかもしれない。

回避するには、とりあえず、 input type=”text” としておいて、JS で切替。

1
2
3
$(document).ready(function () {
$("#password").attr("type", "password");
});

form をバインディングする際の検証エラーで処理が中断される

BindingResult を書いたつもりなのに、そこまで処理が来ない。

理由は簡単、BindingResult は @Valid なフォームの次に書かないと無効。

1
2
3
4
5
6
7
// これはダメ
@RequestMapping
String hoge(@Valid TestForm form, Model model, BindingResult result) {}

// これはOK
@RequestMapping
String hoge(@Valid TestForm form, BindingResult result, Model model) {}

デフォルトでは全ての Bean がシングルトン

Controller も、Service もシングルトン。

と言うことは、インスタンス変数に状態を保存すると他のリクエストの情報と混ざる可能性がある。

Service に @Scope(“prototype”) を指定すれば良いかというとそうではない。

prototype は要求されたら新しいインスタンスを生成して返す。という動作だが、そもそも

Controller が Signleton なので、最初に生成されたインスタンスがずっと使われ続ける。

基本的には Singleton で動作しても問題ないように作るべき。

※Singleton で動いても問題ない(=スレッドセーフ)に作る為にはどうすれば良いのか?

※ご参考:http://qiita.com/yoshi-naoyuki/items/507c5c3ea6027033f4bb

HttpSession に関しては特段の配慮がされているので、フィールドに入れて@Autowired しても OK

ファイルアップロードしようとしたらファイルが入ってこない

http://blog.okazuki.jp/entry/2015/07/17/202941

上記 URL のように正しく書いたつもりが、Form の MultiFile が null になる。

原因は簡単、 form タグに enctype=”multipart/form-data” を書き忘れるとこうなる。

ログを見ると、 String から MultiFile にコンバートできなかった的なエラーが出ている。

Thymeleaf で input type=”hidden”に値をセットしようとしたら入らない

th:field を使うと、form 内容と HTML 上のフォームの値が紐付いてしまう。

th:value で値を入れたい場合は、th:field ではなく、普通に name=”name”で名前を合わせる。

1
2
3
4
5
<!-- これはダメ -->
<input type="hidden" th:field="*{somefield}" th:value="${bean.value}" />

<!-- これならOK -->
<input type="hidden" name="somefield" th:value="${bean.value}" />

ビューを表示するたびに Velocity がエラーを吐く

hoge.vm が存在しません的なもの。Velocity のオートコンフィグをしないように

しないといけないらしい。

1
2
<code class="language-java">@SpringBootApplication
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class,VelocityAutoConfiguration.class })

logger 出力をフォーマットしたい

logger.debugFormat(“value of A is {0}”,A); みたいなの。

slf4j を使っているなら、次の通り。

1
<code class="language-java">logger.debugFormat("value of A is {}",A);

http://www.slf4j.org/faq.html#logging_performance

application.yml にゼロ埋めの数字を書くと 8 進数扱いされる

そのまんま。

1
testVal: 0030

なんて書いたりすると、その値が 8 進数扱いされてしまう。文字列あたりにするのが良い。

1
testVal: '0030'

jar にパッケージングした時だけ TemplateError が発生する

Thymeleaf のテンプレートのパスを指定する際に、 / から始めるとそうなる。

これは、 th:includeth:replace のパスについても同様。

SpringBoot 1.5.x でも修正されていない。(今後も修正されない模様)

https://github.com/spring-projects/spring-boot/issues/1744

何がタチ悪いかというと、IDE 上で動かしているときはファイルシステムからテンプレートを

読むため、普通に動いてしまう。 jar にパッケージングした際に突如に動かなくなる。

devtools を使う(1.3.0 以降)

pom.xml に以下を追記

詳しくは、http://qiita.com/IsaoTakahashi/items/f99d5f761d1d4190860d

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

ただし、LiveReload 機能と Spring-Loaded を一緒に使っても、LiveReload が動いてしまうので

排他利用になりそう。個人的には Spring-Loaded の方が好き。

でも、他にも便利機能があるので dev-tools の方がよいかなとは思った。

Request method ‘POST’ not supported

@RequestMapping がちゃんとあるか確認するのが第一。

ちゃんとあるのであれば、CSRF フィルタに引っかかっている可能性が大。

form を submit したのに CSRF フィルタにひっかかった

th:action がないと、CSRF トークンが埋め込まれない。Javascript で動的に変えるにしても

ダミーの URL を書いておく必要がある。

1
2
3
4
5
<form th:object="${HogeForm}">これはダメパターン</form>

<form th:action="@{'/dummy'} th:object="${HogeForm}">
こうすればOK。トークンが自動で埋め込まれる。
</form>

date: “2016-03-19 15:00:00 +0900”

何のためのメモ?

ある日あるとき、git のリポジトリを移行する必要に駆られてしまい、

色々と失敗したのでメモ。

pull して remote 変えて push じゃダメなのか?

基本的なソースはそれで OK。

ただし、それだけだと tag が消えたりするので、私は以下のコマンドをたたいた。

取得

1
git clone --mirror <RepositoryURL>

カレントディレクトリ以下に、リポジトリ名.git というディレクトリ名でクローンされる。

移動先に push

1
2
3
git remote remove origin
git remote add origin <NewRepositoryURL>
git push --mirror

まとめ

clone と push の時に –mirror オプションつけようね。っていうお話でした。

最初に

思いっきり勘違いして大騒ぎしたのでメモ

Springboot 1.3.5

問題(ではなかった)コード

結論を先に言うと、このコードは想定通り動きます。

1
2
3
4
5
6
7
8
9
@Controller
public class MenuController {
@Autowired
HttpSession session;
@RequestMapping(value = "/", method = RequestMethod.GET)
String method() {
return "somehtml";
}
}

何が問題だと勘違いしたか

くどいですが、以下のような問題は起きません。

  • Controller(prototype スコープ)に HttpSession(session スコープ)のインスタンスを DI しようとしている
  • Controller のフィールドに session を持っているので同時にアクセスが来たときに session を取り違えるのではないか?

簡単に検証しただけなのであまり詳しくは調べていませんが、DI されるインスタンスは HttpSession そのものではなく

適切に request に紐付いた session を触ってくれるようなプロクシみたいなもののようです。

そのため、上記 1,2 のどちらも発生しないようになっています。(Thread.sleep 入れて検証したので間違いないです)

所感

Spring 様はほんと偉大。

前提条件

  • Apache Maven 3.3.3

どんなときに嬉しいの?

ojdbc7.jar (Oracle JDBC ドライバ) って Maven のリポジトリにないけど、それをよしなに

扱う事ができます。しかもあんまり面倒ではない方法で

何をするか

ローカルに Maven リポジトリ(といってもただのディレクトリとファイル)を作ってそこを pom.xml から指定します。

後は普通に dependency で指定するだけ。

どんなコマンド打てばいいの?

プロジェクトのルートディレクトリにいる前提で以下のような感じのコマンドを打つ。見た目の為に改行してますが、実際は 1 行で打って下さい。

当然ですが、jar 一個に対して一回コマンドを実行する必要があります。

jar のバージョンアップがあったら、バージョンを変えてもう一回コマンド実行すればよさそうです。

1
2
3
4
5
6
7
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file
-Dfile=./lib/ojdbc7.jar
-DgroupId=com.oracle
-DartifactId=ojdbc7
-Dversion=1.0
-Dpackaging=jar
-DlocalRepositoryPath=./m2repo

上から解説します。

1 行目。実行してるだけなのでそのままで OK
2 行目。リポジトリに入れたい jar のパス
3 行目。グループ ID。好きに入れれば良いが、 pom.xml の dependency でも同じ値を指定する必要あり。
4 行目。アーティファクト ID。好きにして良いが以下同文
5 行目。バージョン。好きにして良いが以下同文
6 行目。このままで OK
7 行目。ローカルリポジトリのパス。このパスをそのままバージョン管理に入れてしまえばいい。

※この例では、プロジェクトルート/lib/ojdbc7.jar をローカルリポジトリに格納しようとしているが、
※格納後は lib/ojdbc7.jar ローカルリポジトリから参照されるので不要。
※./m2repo//ojdbc7.jar が使われるようになる。

pom.xml へのローカルリポジトリ追加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependencies>
<!-- ここの記述は追加時の記述に合わせる -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>localrepo</id>
<name>localrepo</name>
<!-- ここの記述はリポジトリのパスに合わせる -->
<url>file://${basedir}/m2repo</url>
</repository>
</repositories>

まとめ

これだけの事を調べるのに 1 時間くらい費やしてしまった。

この方法を使えば、最初の人だけが苦労するだけで後の人は何も考えずに開発できるのでオススメです。

でも、Oracle さんが jdbc ドライバを Maven Central に公開してくれればもっと楽なんですが…

まえがき

writefreely を docker で走らせてみた。

docker-compose.yml と、Dockerfile は以下で公開しています。

https://github.com/yakumo-saki/docker-writefreely

ライセンスはオリジナルに従い AGPL 3.0 としています。

なお、本文書は作業を行ってからしばらく立って記憶だけで書いているので

誤りがある可能性が高いです。誤りを見つけたら編集リクエスト等頂けるとありがたいです。

また、writefreely を production で走らせる場合、docker イメージはまだ出来てないよ的な記述があるのでご注意ください。

docker イメージ

yakumosaki/writefreely は、

https://hub.docker.com/r/writeas/writefreely/tags

に v0.10 のイメージがないので自分でビルドしたものです。

多少 Dockerfile に変更を入れていますが、影響はないと思います。

準備

リポジトリのクローン

必要なものはまとめてあるので、

git clone https://github.com/yakumo-saki/docker-writefreely writefreely

で、私のリポジトリからクローンして下さい。

config.ini

(クローンしたディレクトリ内で)

cp config.ini.example config.ini

config.ini ファイルを編集。 公式の config.ini.example に追加して、

1
2
[server]
bind = 0.0.0.0

としています。 リバースプロクシ等、この方が都合が良い場合が多いでしょう。

なお、config.ini でいうところの site name は blog の集合体としての writefreely のサイト名で

例えば、FC2 ブログ。とか livedoor ブログ。のようなレベルの名前です。

自分のブログの名前は Web UI から設定できます。この名前はあとで変えても良いので気楽に決めて下さい。

DB の準備

とりあえず、DB を準備します。残念ながらここは自動化できていません。

1
2
3
4
5
6
7
8
9
10
11
12
$ docker-compose run db bash
$ mysql -uroot

mysql> create user writefreely identified by 'writefreely';
mysql> create database writefreely DEFAULT CHARACTER SET utf8mb4;
mysql> grant all on writefreely.* to writefreely;
mysql> use writefreely
Database changed

writefreely> source /tmp/schema.sql
(出力がそれなりに出るが省略)
writefreely> quit

Web の準備

一時的に keys ディレクトリに誰でも書込ができるようにします。

1
chmod 777 ./keys
1
2
3
4
$ docker-compose run --entrypoint '' web ash
$ cmd/writefreely/writefreely --gen-keys
$ cmd/writefreely/writefreely # 起動テスト。 CTRL+C で抜ける
$ (CTRL+D)

パーミッションを戻しておきます

1
chmod 755 ./keys

実行

あとは普通に docker-compose up -d して下さい

おまけ

federation するには恐らく、https が必要です。

また、一度 federation した場合は、ドメインを変更すると ActivityPub からみたアカウントとドメインの整合性がとれなくなるので適当なドメインで試しに動かす場合は、federation しないように

した方がよいでしょう。

前提

  • Linux Mint 20 (Ubuntu 20.04LTS ベース)

前置き

https://wiki.archlinux.org/index.php/SANE

ここ見れば答えが書いてある感じ。

手順

準備

  • プリンタ本体の、セットアップ → 本体設定 →LAN 設定 → その他の設定 → プリンタ名設定 でプリンタ名を調べておく。
  • プリンタ名.local に ping して名前解決とネットワーク的疎通が取れることを確認する。
  • プリンタ名.local が使えない場合は、IP アドレスでも良い

設定

  • 一応 xsane をソフトウェアの管理 から入れておく
  • /etc/sane.d/pixma.conf に以下の行を追加。
1
2
3
4
# (末尾に追加)
bjnp://<printerName_Or_IPaddr>.local
# 例
bjnp://mg7530.local

スキャン

  • アプリケーションのドキュメントスキャナーを使ってスキャンをテストする。
  • xsane でもいいはずだが、使い方が難しそうなのでやめておいた。

環境

  • Raspberry-Pi 3
  • RASPBIAN JESSIE LITE 2016-11-25
  • Zabbix 3.2.4

参考にしたサイト

Raspberry Pi に Zabbix 3.0 をインストール

http://straightweeds.hatenablog.com/entry/2016/08/05/002649

正直、上記サイトの孫引きなので上記サイトを良く読めば OK。

手順

以下の手順はすべて  root として実行している。

1
sudo su -

前提パッケージのインストール

1
apt install make gcc libc6-dev libmysqlclient-dev libcurl4-openssl-dev libssh2-1-dev libsnmp-dev libiksemel-dev mysql-server libsqlite3-dev libopenipmi-dev fping php5-gd snmp libsnmp-base openjdk-7-jdk unixodbc unixodbc-dev libxml2 libxml2-dev snmp-mibs-downloader snmpd snmptt python-pywbem php5-ldap php5-mysql traceroute libldap2-dev apache2 php5 libapache2-mod-php5 gettext vim

zabbix パッケージの取得

wget を使って取得すれば OK。手順は省略。

tar xvf で展開可能。展開したディレクトリ内を と記述する

コンパイル

恐らく、この作業は時間がかかると思われるので、byobu(screen)を入れて SSH が切れても

処理が継続されるようにしておいた方が良いかもしれない。

1
2
3
cd <src>
./configure --enable-server --enable-agent --with-mysql --with-net-snmp --with-libcurl --with-openipmi --with-ssh2 --with-libxml2 --enable-ipv6 --with-unixodbc --with-openssl --enable-java --with-jabber --with-ldap
make install

Zabbix ユーザー追加

zabbix を root で動かすわけにはいかないので、ユーザーを追加。

1
adduser --system --home /usr/local/sbin --no-create-home zabbix

Zabbix サーバー設定

1
vi /usr/local/etc/zabbix_server.conf

変更ポイント

  • DBName=zabbix
  • DBUser=zabbix
  • DBPassword=zabbix
  • DBSocket=/var/run/mysqld/mysqld.sock

MySQL に zabbix のスキーマを作成

1
2
3
4
mysql -u root -p

SQL> create database zabbix;
SQL> grant all on zabbix.* to zabbix@localhost identified by 'zabbix';
1
2
3
4
cd <src>
mysql -u zabbix --password=zabbix zabbix < ./schema.sql
mysql -u zabbix --password=zabbix zabbix < ./images.sql
mysql -u zabbix --password=zabbix zabbix < ./data.sql

とりあえず zabbix_server 起動

1
zabbix_server

起動しても何もでない。 /tmp/zabbix_server.log を見てエラーが出ていたら要修正。

zabbix frontend をセットアップ

PHP の設定

1
vi /etc/php5/apache2/php.ini

変更点

  • memory_limit = 128M
  • post_max_size = 16M
  • max_execution_time = 300
  • max_input_time = 300
  • date.timezone = Asia/Tokyo
  • always_populate_raw_post_data =-1

zabbix frontend を apache 公開ディレクトリに配置

1
2
3
mkdir /var/www/html/zabbix
cd <src>/frontends/php
cp -a . /var/www/html/zabbix/

ロケールとパーミッション関係

1
2
3
4
5
cd /var/www/html/zabbix/locale
./update_po.sh
./make_mo.sh

chown -R www-data /var/www/html/zabbix

ついでにリダイレクト設定

1
vi /var/www/html/index.html

内容

1
2
3
4
5
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="refresh" content="0;URL=/zabbix">
</head>
</html>

ロケール設定

1
dpkg-reconfigure locales
  • All locales
  • ja_JP.UTF8
  • 時間がかかる
  • 必要なロケールだけ選択した方がいいかもしれない

Apache 再起動&確認

1
systemctl restart apache2

Web ブラウザからアクセス  して、初期設定を行う。

自動起動登録

起動スクリプトをコピー

1
2
cp <src>/misc/init.d/debian/
cp * /etc/init.d/

コピー後、参考サイトにある LSB ヘッダを追加する。

1
2
systemctl enable zabbix-server
systemctl enable zabbix-agent

以上

追記

日本語を選択すると、グラフ内にも日本語が使われるが、それが文字化けする(豆腐 □ になる)

解決するには以下の Qiita の通りやれば OK

http://qiita.com/Hiroki_lzh/items/8aa1acc55921ddd9dfb0