Container Stations 中卡住的 App 讓整台 NAS 當機!

這種情況我已經遇過好幾次了:
我嘗試停止正在運行的容器,但它無法停止,也無法強制停止或終止。
發生這種情況時,Container Station 本身也無法停止,最後嘗試重啟 NAS 也失敗。一個失控的容器竟然能導致整個 NAS 無法回應,這完全無法接受。容器技術的目的就是要隔離並保護 NAS 作業系統免受故障容器的影響。但在 QNAP 的情況下,這似乎是已知問題。他們的容器引擎實作不夠健全。
僅供記錄;我當然已經嘗試過所有可能的方法來停止、取消、重啟和從 CLI 終止,但都無效。唯一且最終的解決方法就是硬重置。

我從來沒遇過這種情況……是在哪個容器發生的?

Home Assistant v2025.5.1

我使用 2025.5.3 版本,沒有遇到崩潰的問題

你能用 ssh 存取嗎?
如果可以,請執行 docker 的「docker ps」,然後「stop <container_name>」

請將日誌輸出在這裡
「cat /var/log/log_sys.log」和「cat /var/log/docker.log」或「docker logs <container_name>」

沒有日誌無法協助。

如我之前所說;我已經嘗試了所有可能(甚至不可能)的 CLI 指令,但都沒有成功。

你有開工單讓 QNAP 查看這個問題嗎?

你的貼文聽起來像這個 Container Station 的問題已經被廣泛討論,但這是我第一次聽說(除非這個問題沒有在常見的 reddit/社群等地方公開討論)。

我不得不強制重置 NAS 才能恢復運作。
是 ChatGPT 告訴我這是 CS 的已知問題。這也和我的經驗非常吻合。這不是我第一次遇到這種情況了。

我並不是質疑你遇到這個問題,但ChatGPT是一個非常糟糕的消息來源,因為它經常即興捏造事實(幻覺)……只要我在其他地方沒看到這些問題,那ChatGPT的資訊到底是從哪裡來的?(而且這些大型語言模型通常在最新資訊方面會落後好幾個月)

你還沒說你有沒有提交工單。

1個讚

您好,

我們已注意到此問題,並希望您能提供更詳細的環境資訊,以協助我們進行調查。請問您能否提供您的 NAS 型號、韌體版本、已安裝的應用程式或已啟用的服務等相關細節?

謝謝。

This has happened several times. Last time it happened, I took the time to analyse the log more deeply. My attention focused on this log entry:

homeass-1  |   File "/usr/src/homeassistant/homeassistant/core.py", line 1731, in _async_remove_listener
homeass-1  |     self._listeners[event_type].remove(filterable_job)
homeass-1  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
homeass-1  | ValueError: list.remove(x): x not in list
homeass-1  | 2025-06-11 14:50:20.239 WARNING (Thread-8 (_do_shutdown)) [homeassistant.util.executor] Thread[SyncWorker_1] is still running at shutdown: File "/usr/local/lib/python3.13/threading.py", line 1012, in _bootstrap
homeass-1  |     self._bootstrap_inner()
homeass-1  |   File "/usr/local/lib/python3.13/threading.py", line 1041, in _bootstrap_inner
homeass-1  |     self.run()
homeass-1  |   File "/usr/local/lib/python3.13/threading.py", line 992, in run
homeass-1  |     self._target(*self._args, **self._kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 93, in _worker
homeass-1  |     work_item.run()
homeass-1  |   File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 59, in run
homeass-1  |     result = self.fn(*self.args, **self.kwargs)
homeass-1  |   File "/usr/src/homeassistant/homeassistant/components/qnap/coordinator.py", line 82, in _sync_update
homeass-1  |     "volumes": self._api.get_volumes(),
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 142, in get_volumes
homeass-1  |     resp = self._get_url(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 79, in _get_url
homeass-1  |     self._get_url(url, False, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 76, in _get_url
homeass-1  |     result = self._execute_get_url(url, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 92, in _execute_get_url
homeass-1  |     resp = self._session.get(url, timeout=self._timeout, verify=self._verify_ssl)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 602, in get
homeass-1  |     return self.request("GET", url, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 589, in request
homeass-1  |     resp = self.send(prep, **send_kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 703, in send
homeass-1  |     r = adapter.send(request, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/adapters.py", line 667, in send
homeass-1  |     resp = conn.urlopen(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/urllib3/connectionpool.py", line 716, in urlopen
homeass-1  |     httplib_response = self._make_request(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/urllib3/connectionpool.py", line 463, in _make_request
homeass-1  |     httplib_response = conn.getresponse()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 1430, in getresponse
homeass-1  |     response.begin()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 331, in begin
homeass-1  |     version, status, reason = self._read_status()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 292, in _read_status
homeass-1  |     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
homeass-1  |   File "/usr/local/lib/python3.13/socket.py", line 719, in readinto
homeass-1  |     return self._sock.recv_into(b)
homeass-1  | 2025-06-11 14:50:21.220 WARNING (Thread-8 (_do_shutdown)) [homeassistant.util.executor] Thread[SyncWorker_1] is still running at shutdown: File "/usr/local/lib/python3.13/threading.py", line 1012, in _bootstrap
homeass-1  |     self._bootstrap_inner()
homeass-1  |   File "/usr/local/lib/python3.13/threading.py", line 1041, in _bootstrap_inner
homeass-1  |     self.run()
homeass-1  |   File "/usr/local/lib/python3.13/threading.py", line 992, in run
homeass-1  |     self._target(*self._args, **self._kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 93, in _worker
homeass-1  |     work_item.run()
homeass-1  |   File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 59, in run
homeass-1  |     result = self.fn(*self.args, **self.kwargs)
homeass-1  |   File "/usr/src/homeassistant/homeassistant/components/qnap/coordinator.py", line 82, in _sync_update
homeass-1  |     "volumes": self._api.get_volumes(),
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 142, in get_volumes
homeass-1  |     resp = self._get_url(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 79, in _get_url
homeass-1  |     self._get_url(url, False, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 76, in _get_url
homeass-1  |     result = self._execute_get_url(url, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/qnapstats/qnap_stats.py", line 92, in _execute_get_url
homeass-1  |     resp = self._session.get(url, timeout=self._timeout, verify=self._verify_ssl)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 602, in get
homeass-1  |     return self.request("GET", url, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 589, in request
homeass-1  |     resp = self.send(prep, **send_kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 703, in send
homeass-1  |     r = adapter.send(request, **kwargs)
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/requests/adapters.py", line 667, in send
homeass-1  |     resp = conn.urlopen(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/urllib3/connectionpool.py", line 716, in urlopen
homeass-1  |     httplib_response = self._make_request(
homeass-1  |   File "/usr/local/lib/python3.13/site-packages/urllib3/connectionpool.py", line 463, in _make_request
homeass-1  |     httplib_response = conn.getresponse()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 1430, in getresponse
homeass-1  |     response.begin()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 331, in begin
homeass-1  |     version, status, reason = self._read_status()
homeass-1  |   File "/usr/local/lib/python3.13/http/client.py", line 292, in _read_status
homeass-1  |     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
homeass-1  |   File "/usr/local/lib/python3.13/socket.py", line 719, in readinto
homeass-1  |     return self._sock.recv_into(b)
homeass-1  | 2025-06-11 14:50:22.019 ERROR (MainThread) [homeassistant.components.systemmonitor.coordinator] Unexpected error fetching System Monitor update coordinator data
homeass-1  | Traceback (most recent call last):
homeass-1  |   File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 380, in _async_refresh
homeass-1  |     self.data = await self._async_update_data()
homeass-1  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
homeass-1  |   File "/usr/src/homeassistant/homeassistant/components/systemmonitor/coordinator.py", line 135, in _async_update_data
homeass-1  |     _data = await self.hass.async_add_executor_job(self.update_data)
homeass-1  |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
homeass-1  |   File "/usr/src/homeassistant/homeassistant/core.py", line 878, in async_add_executor_job
homeass-1  |     task = self.loop.run_in_executor(None, target, *args)
homeass-1  |   File "/usr/local/lib/python3.13/asyncio/base_events.py", line 888, in run_in_executor
homeass-1  |     self._check_default_executor()
homeass-1  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
homeass-1  |   File "/usr/local/lib/python3.13/asyncio/base_events.py", line 554, in _check_default_executor
homeass-1  |     raise RuntimeError('Executor shutdown has been called')
homeass-1  | RuntimeError: Executor shutdown has been called

This error occurs in the Home Assistant core (core.py, line 1731) during the shutdown process. It happens when the system tries to remove an event listener from a list, but the listener isn’t found. This could be due to a bug or a race condition where the listener was already removed or never properly registered.

I suspect this is a bug in the QNAP Integration; QNAP - Home Assistant

Threads Still Running at Shutdown

The log shows warnings about threads (e.g., SyncWorker_1) still running when Home Assistant attempts to shut down. These threads are stuck in API calls to the QNAP NAS, specifically in the get_volumes() function (qnap_stats.py, line 142). The stack trace reveals that these threads are waiting for a response from the QNAP API over the network, which doesn’t arrive before the shutdown process begins.

Executor Shutdown Error

The final error occurs in the system monitor coordinator (systemmonitor/coordinator.py, line 135), where Home Assistant tries to fetch data after the executor (which manages background tasks) has already been shut down. This is a downstream effect of the incomplete shutdown caused by the above issues.
This error confirms that the shutdown sequence is disrupted, leaving some components in an inconsistent state.

Possible Causes

  • QNAP API Issues: The threads are stuck waiting for the QNAP API (get_volumes()), possibly due to network delays, timeouts, or an unresponsive API.
  • Home Assistant Bug: The ValueError suggests a potential issue in how Home Assistant manages listeners during shutdown.
  • Shutdown Sequence: The executor is shutting down prematurely, likely because hanging threads delay the process, leading to resource cleanup failures.

However, the error message:

ValueError: list.remove(x): x not in list  
Thread[SyncWorker_1] is still running at shutdown  
RuntimeError: Executor shutdown has been called

… indicates that Home Assistant is launching background threads (via the qnapstats-based QNAP integration) and, when it gets a SIGTERM from Container Station, those threads never cleanly exit. Because the default Docker “stop timeout” is only 10 seconds, Container Station gives up waiting for HA’s Python process to die and the container never goes down gracefully. (This same symptom has been reported on QNAP’s Community forums before, but QNAP staff hasn’t picked it up)
The QNAP integration in Home Assistant uses the qnapstats library, which spawns background threads to collect data from my QNAP NAS.
When Container Station sends a SIGTERM signal to stop the Home Assistant container, these threads do not terminate properly, preventing the Python process from shutting down gracefully.
Docker’s default stop timeout is only 10 seconds. If the container doesn’t stop within this window, Container Station forcibly terminates it, leading to the errors in the log.

Solution?

I am trying to solve this by adding stop_grace_period: 60s to the docker compose file for my Home Assistant container.
It remains to be seen if this has any effects.

Rgds

我剛剛也遇到同樣的問題。在 Container Station 嘗試啟動應用程式後,NAS 的網頁介面變得沒有回應。當我再次嘗試登入時,畫面卡在藍色的「Loading」畫面。我只好用 SSH 登入,殺掉所有 apache 程序,然後重啟 thttpd 服務。

更新:顯然這是因為我不小心把容器的 volume 掛載路徑設在非共享資料夾,導致 ram disk 被塞滿(可以用 SSH 執行「df /」指令檢查)。