Приложение Redis и flask, веб-контейнер не хочет запускать ошибку индекса: всплывающее окно из пустого списка

#docker #docker-compose #dockerfile #devops

Вопрос:

Я пытаюсь решить задание колледжа, запустив приложение, написанное на flask redis. Для этого мне нужно использовать докер. Использование docker-compose up redis запускается правильно, однако приложение flask выдает ошибки, и я действительно не знаю, почему.

Некоторый код приложения flask, если я правильно понимаю, мне нужно объявить переменные среды в файле Dockefile, потому что именно из них приложение получит ip-адрес и порт Redis

 app = Flask(__name__)
redis = redis.Redis(host=os.environ.get('REDIS_HOST'),
                    password=None,
                    port=os.environ.get('REDIS_PORT'),
                    db=0)
 

Мой Док-файл

 ARG PYTHON_VERSION=3.7-alpine

FROM python:${PYTHON_VERSION}

ENV REDIS_HOST 127.0.0.1 
    REDIS_PORT 6379

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "main:app"]
 

И докер-сочиняй

 version: "3"

services:
  web:
    build: .
    container_name: "python_app"
    ports:
      - "8000:8000"
    depends_on:
      - redis
  
  redis:
    image: "redis:alpine"
    container_name: "redis"
    ports: 
      - "6379:6379"
 

докер-создание сборки

 Creating network "tt_default" with the default driver
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
Digest: sha256:fa785f9bd167b94a6b30210ae32422469f4b0f805f4df12733c2f177f500d1ba
Status: Downloaded newer image for redis:alpine
Building web
Sending build context to Docker daemon  10.75kB
Step 1/7 : ARG PYTHON_VERSION=3.7-alpine
Step 2/7 : FROM python:${PYTHON_VERSION}
 ---> a436fb2c575c
Step 3/7 : ENV REDIS_HOST 127.0.0.1     REDIS_PORT 6379
 ---> Running in ad3a17ce15e9
Removing intermediate container ad3a17ce15e9
 ---> 937330185f34
Step 4/7 : COPY requirements.txt .
 ---> d81cbb22f113
Step 5/7 : RUN pip install -r requirements.txt
 ---> Running in 1c0bac282a92
Collecting Flask==1.1.2
  Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting redis==3.4.1
  Downloading redis-3.4.1-py2.py3-none-any.whl (71 kB)
Collecting gunicorn<20,>=19
  Downloading gunicorn-19.10.0-py2.py3-none-any.whl (113 kB)
Collecting itsdangerous>=0.24
  Downloading itsdangerous-2.0.1-py3-none-any.whl (18 kB)
Collecting click>=5.1
  Downloading click-8.0.1-py3-none-any.whl (97 kB)
Collecting Jinja2>=2.10.1
  Downloading Jinja2-3.0.1-py3-none-any.whl (133 kB)
Collecting Werkzeug>=0.15
  Downloading Werkzeug-2.0.1-py3-none-any.whl (288 kB)
Collecting importlib-metadata
  Downloading importlib_metadata-4.8.1-py3-none-any.whl (17 kB)
Collecting MarkupSafe>=2.0
  Downloading MarkupSafe-2.0.1.tar.gz (18 kB)
Collecting typing-extensions>=3.6.4
  Downloading typing_extensions-3.10.0.2-py3-none-any.whl (26 kB)
Collecting zipp>=0.5
  Downloading zipp-3.5.0-py3-none-any.whl (5.7 kB)
Building wheels for collected packages: MarkupSafe
  Building wheel for MarkupSafe (setup.py): started
  Building wheel for MarkupSafe (setup.py): finished with status 'done'
  Created wheel for MarkupSafe: filename=MarkupSafe-2.0.1-py3-none-any.whl size=9761 sha256=43b5e0d8ef8bcbadc8e8d6845f85b770ad2b918760d7541b8c3f9c403ab04b14
  Stored in directory: /root/.cache/pip/wheels/1a/18/04/e3b5bd888f000c2716bccc94a565239f9defc47ef93d9e7bea
Successfully built MarkupSafe
Installing collected packages: zipp, typing-extensions, MarkupSafe, importlib-metadata, Werkzeug, Jinja2, itsdangerous, click, redis, gunicorn, Flask
Successfully installed Flask-1.1.2 Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 gunicorn-19.10.0 importlib-metadata-4.8.1 itsdangerous-2.0.1 redis-3.4.1 typing-extensions-3.10.0.2 zipp-3.5.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
Removing intermediate container 1c0bac282a92
 ---> 6dddf2a4ad27
Step 6/7 : COPY . .
 ---> 37bd8f541844
Step 7/7 : CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "main:app"]
 ---> Running in f19c3226fff2
Removing intermediate container f19c3226fff2
 ---> 861a5c53a545
Successfully built 861a5c53a545
Successfully tagged tt_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating redis ... done
Creating python_app ... done
Attaching to redis, python_app
 

Часть журналов, которые я получаю после использования docker-составьте

  Attaching to redis, python_app
    redis    | 1:C 27 Sep 2021 14:36:16.063 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis    | 1:C 27 Sep 2021 14:36:16.063 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
    redis    | 1:C 27 Sep 2021 14:36:16.063 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    redis    | 1:M 27 Sep 2021 14:36:16.064 * monotonic clock: POSIX clock_gettime
    redis    | 1:M 27 Sep 2021 14:36:16.065 * Running mode=standalone, port=6379.
    redis    | 1:M 27 Sep 2021 14:36:16.065 # Server initialized
    redis    | 1:M 27 Sep 2021 14:36:16.065 # 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:M 27 Sep 2021 14:36:16.065 * Ready to accept connections
    python_app | [2021-09-27 14:36:16  0000] [1] [INFO] Starting gunicorn 19.10.0
    python_app | [2021-09-27 14:36:16  0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
    python_app | [2021-09-27 14:36:16  0000] [1] [INFO] Using worker: sync
    python_app | [2021-09-27 14:36:16  0000] [8] [INFO] Booting worker with pid: 8
    python_app | [2021-09-27 14:36:16  0000] [9] [INFO] Booting worker with pid: 9
    python_app | [2021-09-27 14:36:16  0000] [8] [ERROR] Exception in worker process
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1179, in get_connection
    python_app |     connection = self._available_connections.pop()
    python_app | IndexError: pop from empty list
    python_app | 
    python_app | During handling of the above exception, another exception occurred:
    python_app | 
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 586, in spawn_worker
    python_app |     worker.init_process()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 135, in init_process
    python_app |     self.load_wsgi()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    python_app |     self.wsgi = self.app.wsgi()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    python_app |     self.callable = self.load()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
    python_app |     return self.load_wsgiapp()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    python_app |     return util.import_app(self.app_uri)
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 350, in import_app
    python_app |     __import__(module)
    python_app |   File "/main.py", line 21, in <module>
    python_app |     redis.set('sessionvisitors', 0)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 1766, in set
    python_app |     return self.execute_command('SET', *pieces)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 875, in execute_command
    python_app |     conn = self.connection or pool.get_connection(command_name, **options)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1181, in get_connection
    python_app |     connection = self.make_connection()
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1220, in make_connection
    python_app |     return self.connection_class(**self.connection_kwargs)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 502, in __init__
    python_app |     self.port = int(port)
    python_app | TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
    python_app | [2021-09-27 14:36:16  0000] [8] [INFO] Worker exiting (pid: 8)
    python_app | [2021-09-27 14:36:16  0000] [10] [INFO] Booting worker with pid: 10
    python_app | [2021-09-27 14:36:16  0000] [9] [ERROR] Exception in worker process
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1179, in get_connection
    python_app |     connection = self._available_connections.pop()
    python_app | IndexError: pop from empty list
    python_app | 
    python_app | During handling of the above exception, another exception occurred:
    python_app | 
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 586, in spawn_worker
    python_app |     worker.init_process()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 135, in init_process
    python_app |     self.load_wsgi()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    python_app |     self.wsgi = self.app.wsgi()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    python_app |     self.callable = self.load()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
    python_app |     return self.load_wsgiapp()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    python_app |     return util.import_app(self.app_uri)
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 350, in import_app
    python_app |     __import__(module)
    python_app |   File "/main.py", line 21, in <module>
    python_app |     redis.set('sessionvisitors', 0)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 1766, in set
    python_app |     return self.execute_command('SET', *pieces)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 875, in execute_command
    python_app |     conn = self.connection or pool.get_connection(command_name, **options)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1181, in get_connection
    python_app |     connection = self.make_connection()
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 1220, in make_connection
    python_app |     return self.connection_class(**self.connection_kwargs)
    python_app |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 502, in __init__
    python_app |     self.port = int(port)
    python_app | TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
    python_app | [2021-09-27 14:36:16  0000] [9] [INFO] Worker exiting (pid: 9)
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 203, in run
    python_app |     self.manage_workers()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 548, in manage_workers
    python_app |     self.spawn_workers()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 620, in spawn_workers
    python_app |     time.sleep(0.1 * random.random())
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 245, in handle_chld
    python_app |     self.reap_workers()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 528, in reap_workers
    python_app |     raise HaltServer(reason, self.WORKER_BOOT_ERROR)
    python_app | gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
    python_app | 
    python_app | During handling of the above exception, another exception occurred:
    python_app | 
    python_app | Traceback (most recent call last):
    python_app |   File "/usr/local/bin/gunicorn", line 8, in <module>
    python_app |     sys.exit(run())
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 61, in run
    python_app |     WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 223, in run
    python_app |     super(Application, self).run()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 72, in run
    python_app |     Arbiter(self).run()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 232, in run
    python_app |     self.halt(reason=inst.reason, exit_status=inst.exit_status)
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 345, in halt
    python_app |     self.stop()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 396, in stop
    python_app |     time.sleep(0.1)
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 245, in handle_chld
    python_app |     self.reap_workers()
    python_app |   File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 528, in reap_workers
    python_app |     raise HaltServer(reason, self.WORKER_BOOT_ERROR)
    python_app | gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
 

Ответ №1:

Ошибка приложения, которую вы видите, вызвана тем, что соединение Redis не открывается, если вы внимательно посмотрите на трассировку стека. Причина неудачного подключения заключается в том, что REDIS_HOST 127.0.0.1 в вашем файле Dockerfile неверно установлено значение. Чтобы исправить это, значения для REDIS_HOST и REDIS_PORT должны на самом деле передаваться в контейнер приложения docker-compose, так как именно этот слой фактически знает, где живет Redis. Ваш файл настройки предназначен только для контейнера приложения, который зависит от Redis, но не имеет представления, где он может работать.

Поскольку compose делает службы доступными по именам хостов, равным имени службы по умолчанию , Redis должен быть доступен по адресу just tcp://redis:6379 , поэтому я бы дал этим значениям шанс для начала:

   web:
    build: .
    container_name: "python_app"
    ports:
      - "8000:8000"
    depends_on:
      - redis
    environment:
      REDIS_HOST: redis
      REDIS_PORT: 6379