web-dev-qa-db-ja.com

セロリとFlask同じdocker-compose

docker-composeを使用してFlask/Celery/Redisサービスを生成しようとしています。

これが私のdocker-compose.ymlです:

flask:
    build: .
    command: "python3 app.py"
    ports:
        - '5000:5000'
    links:
        - redis
    volumes:
        - .:/usr/src/app:ro

celery:
    build: .
    command: "celery -A app.celery worker --loglevel=info"
    volumes:
        - .:/usr/src/app:ro

redis:
    image: redis
    ports:
        - '6379:6379'

このdocker-composeを実行すると、FlaskとRedisの両方が正常に起動し、期待どおりに機能します。Celeryに関して、Dockerは次のように報告します:flaskcelery_celery_1 exited with code 1、他の情報はありません。

Dockerなしで3つのサービスを実行し、celery -A app.celery worker --loglevel=infoでCeleryを起動すると、アプリは正常に機能します。

必要に応じて、さらにいくつかの情報:

Dockerfile :(このイメージはビルドにもrequirements.txtをインストールします)

FROM python:3.5-onbuild
EXPOSE 5000

要件.txt:

flask==0.11.1
celery==3.1.23

docker-compose up出力:

Starting flaskcelery_celery_1
Starting flaskcelery_redis_1
Starting flaskcelery_flask_1
Attaching to flaskcelery_celery_1, flaskcelery_redis_1, flaskcelery_flask_1
redis_1  |                 _._                                                  
redis_1  |            _.-``__ ''-._                                             
redis_1  |       _.-``    `.  `_.  ''-._           Redis 3.2.3 (00000000/0) 64 bit
redis_1  |   .-`` .-```.  ```\/    _.,_ ''-._                                   
redis_1  |  (    '      ,       .-`  | `,    )     Running in standalone mode
redis_1  |  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
redis_1  |  |    `-._   `._    /     _.-'    |     PID: 1
redis_1  |   `-._    `-._  `-./  _.-'    _.-'                                   
redis_1  |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis_1  |  |    `-._`-._        _.-'_.-'    |           http://redis.io        
redis_1  |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis_1  |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis_1  |  |    `-._`-._        _.-'_.-'    |                                  
redis_1  |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis_1  |       `-._    `-.__.-'    _.-'                                       
redis_1  |           `-._        _.-'                                           
redis_1  |               `-.__.-'                                               
redis_1  | 
redis_1  | 1:M 23 Aug 10:23:08.409 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1  | 1:M 23 Aug 10:23:08.409 # Server started, Redis version 3.2.3
redis_1  | 1:M 23 Aug 10:23:08.409 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1  | 1:M 23 Aug 10:23:08.409 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1  | 1:M 23 Aug 10:23:08.409 * The server is now ready to accept connections on port 6379
flaskcelery_celery_1 exited with code 1
flask_1  |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
flask_1  |  * Restarting with stat
flask_1  |  * Debugger is active!
flask_1  |  * Debugger pin code: 196-119-737
18
Juicy

私の問題を解決しました。最終的に、Dockerイメージでコマンドプロンプトを取得できることがわかりました。

docker build -t <image name> .
docker run -it <image name> /bin/bash

次に、コンテナ内でceleryを実行しようとすると、問題が明らかになりました。

root@4a6edc5d7372:/usr/src/app# celery -A app.celery worker --loglevel=info
Running a worker with superuser privileges when the
worker accepts messages serialized with pickle is a very bad idea!

If you really want to continue then you have to set the C_FORCE_ROOT
environment variable (but please think about this before you do).

User information: uid=0 euid=0 gid=0 egid=0

Dockerは通常rootとして実行されますが、Celeryはセキュリティ上の理由からrootとして実行することを好みません(pickleの逆シリアル化でコードを実行できると思います)。より安全な解決策は、celeryコンテナをnobodyとして実行するように設定することでした。働くdocker-compose.yml

flask:
    build: .
    command: "python3 app.py"
    ports:
        - '5000:5000'
    links:
        - redis
        - celery
    volumes:
        - .:/usr/src/app:ro

celery:
    build: .
    command: "celery -A app.celery worker --loglevel=info"
    user: nobody
    links:
        - redis
    volumes:
        - .:/usr/src/app:ro

redis:
    image: redis
    ports:
        - '6379:6379'
18
Juicy

docker-composeを扱いたくなく、dockerのみを使用したい場合は、これが役立つ場合があります。まず、以下のような「監視対象」ファイルを作成する必要があります。

[supervisord]
nodaemon=true

[program:python]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=python flask_api.py

[program:celeryworker]
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
command=celery -A flask_api worker -c 2

これで、Dockerファイルは次のようになります。明らかに、これは単なるテンプレートであり、必要に応じて変更できます。

FROM ubuntu:16.04
RUN apt-get update -y
RUN apt-get install -y python-pip python-dev build-essential libpq-dev git postgresql-9.5 postgresql-contrib
RUN apt-get install -y supervisor
RUN pip install --upgrade pip
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
WORKDIR /app
CMD ["supervisord"]

このようにして、flaskアプリケーションとセロリワーカーを同じDockerコンテナーで実行できます。

3
Mehmet nuri