あいつの日誌β

働きながら旅しています。

groonga/docker で http モードで Docker を起動して request を発行すると セマフォが出る

あらすじ

全文検索したくなったので久しぶりに Groonga 使いたいのですが、設定方法を思い出すの面倒なので Docker 化しておこうと思ったら何かがおかしかった。

再現手順

mkdir verify-groonga-dokcer && cd $_
mkdir -p groonga/db
touch docker-compose.yml
touch groonga/Dockerfile

create docker-compose.yml

version: "3" 
services:
  groonga:
    build: "./groonga"
    ports:
      - 10041:10041:wqq

create groonga/Dockerfile

FROM groonga/groonga:latest

RUN mkdir -p /app/groonga/db
WORKDIR /app/groonga

EXPOSE 10041

ENTRYPOINT ["groonga", "--protocol", "http", "-s", -n "./db/groonga.db"]

実行する

% docker-compose build --no-cache 
% docker-compose up --force-recreate
Recreating verifygroongadokcer_groonga_1 ... 
Recreating verifygroongadokcer_groonga_1 ... done
Attaching to verifygroongadokcer_groonga_1

上記の状態で http://localhost:10041/ にアクセスすると GUI の管理画面が表示されるので、そこにで適当に Table を作成して Table を参照しようとすると 139 で groonga が終了してしまう

verifygroongadokcer_groonga_1 exited with code 139

調べていたらこのような issue を発見

どうやら python3.6 manage.py runserver で SIGFAULT が出てるらしい。

https://github.com/docker-library/python/issues/211

そして以下のようにして修正ができるらしい。実際に修正できた。

https://github.com/jubel-han/dockerfiles/blob/master/common/stack-fix.c

解決策: patch を用意して Dockerfile build 時にその patch を適用する

前述の issue と repository を参考に stack-fix.cを用意

#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>

// THIS IS TO AVOID A SIGFAULT WHEN RUNNING python3.6 manage.py runserver
// This should be fixed at some point by Alpine and/or Python
// Check this issue for more info
// https://github.com/docker-library/python/issues/211
typedef int (*func_t)(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) {

    pthread_attr_t local;
    int used = 0, ret;

    if (!attr) {
        used = 1;
        pthread_attr_init(&local);
        attr = &local;
    }
    pthread_attr_setstacksize((void*)attr, 2 * 1024 * 1024); // 2 MB

    func_t orig = (func_t)dlsym(RTLD_NEXT, "pthread_create");

    ret = orig(thread, attr, start_routine, arg);

    if (used) {
        pthread_attr_destroy(&local);
    }

    return ret;
}

Dockerfile を以下のようにする

FROM groonga/groonga:latest

# Add the patch fix
COPY stack-fix.c /lib/

# Prepare the libraries packages
RUN set -ex \
    && apk add --no-cache  --virtual .build-deps build-base \
    && gcc  -shared -fPIC /lib/stack-fix.c -o /lib/stack-fix.so \
    && apk del .build-deps

# export the environment variable of LD_PRELOAD
ENV LD_PRELOAD /lib/stack-fix.so

RUN mkdir -p /app/groonga/db
WORKDIR /app/groonga

EXPOSE 10041

CMD ["--protocol", "http", "-s", "-n", "./db/groonga.db"]

再び実行して groonga がセマフォを起さない事を確認しました。

% docker-compose build --no-cache 
% docker-compose up --force-recreate

 ところで

こういう問題はすでに解決しているのか、していないのかどこに報告すべきなのかが分かっていませんので有識者の方がいらしたら何卒アドバイスをお願いします。