Compare commits

..
22 Commits
Author SHA1 Message Date
kun ec5e4c6256 更新 4600Pro/BookOrbit/.env 2026-09-26 01:09:55 +08:00
kun 3def817f7a fix: ignore local IDE workspace and generated caches 2026-09-26 01:07:00 +08:00
kun 8f65336fa7 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.idea/workspace.xml
2026-09-26 01:04:48 +08:00
kun bb826c05ce update 26.09.26 2026-09-26 01:04:38 +08:00
kun 9d7de90373 Merge remote-tracking branch 'origin/main' 2026-09-22 09:35:03 +08:00
kun 2f595a8226 update 26.9.22 2026-09-22 09:34:55 +08:00
kun 27b5f4771a 更新 480T/hindsight/.env 2026-09-05 06:50:06 +08:00
kun 5ca8c1d4da 更新 480T/hindsight/.env 2026-09-05 05:40:50 +08:00
kun ffd1b2fde9 更新 480T/hindsight/.env 2026-09-05 05:05:49 +08:00
kun a32a84f7d9 Merge remote-tracking branch 'origin/main' 2026-09-04 09:24:14 +08:00
kun 1034c807c0 update 26.9.4 2026-09-04 09:24:08 +08:00
kun 6767a482a1 更新 480T/hindsight/.env 2026-09-03 22:43:39 +08:00
kun d185ac536b Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.idea/workspace.xml
2026-09-02 15:26:26 +08:00
kun 9fd5aa0418 update 26.9.2 2026-09-02 15:26:17 +08:00
kun 039a5699a1 更新 480T/rc/.env 2026-09-02 09:08:48 +08:00
kun 78918eb938 更新 480T/rc/.env 2026-09-02 09:08:04 +08:00
kun 460c4318fb 更新 480T/hindsight/.env 2026-09-02 00:01:09 +08:00
kun 42d0ec220a 更新 480T/hindsight/docker-compose.yaml 2026-09-01 23:25:23 +08:00
kun 68b9934f08 update 26.9.1 2026-09-01 22:47:37 +08:00
kun 6e847d265b update 26.8.31 2026-08-31 16:00:34 +08:00
kun 875a96d97b Merge remote-tracking branch 'origin/main' 2026-08-31 14:11:53 +08:00
kun 85c8f4d766 update 26.8.31 2026-08-31 14:11:48 +08:00
19 changed files with 595 additions and 703 deletions
+9
View File
@@ -0,0 +1,9 @@
# macOS generated files
.DS_Store
# Python generated caches
__pycache__/
*.py[cod]
# PyCharm personal workspace state
.idea/workspace.xml
-4
View File
@@ -1,4 +0,0 @@
<changelist name="在进行更新之前于_2026_8_25_09_09_取消提交了更改_[更改]" date="1787620195855" recycled="true" deleted="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/在进行更新之前于_2026_8_25_09_09_取消提交了更改_[更改]/shelved.patch" />
<option name="DESCRIPTION" value="在进行更新之前于 2026/8/25 09:09 取消提交了更改 [更改]" />
</changelist>
-4
View File
@@ -1,4 +0,0 @@
<changelist name="在进行更新之前于_2026_8_31_10_29_取消提交了更改_[更改]" date="1788143371090" recycled="true" deleted="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/在进行更新之前于_2026_8_31_10_29_取消提交了更改_[更改]/shelved.patch" />
<option name="DESCRIPTION" value="在进行更新之前于 2026/8/31 10:29 取消提交了更改 [更改]" />
</changelist>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Generated
-1
View File
@@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/4600Pro/odysseus" vcs="Git" />
</component>
</project>
-500
View File
@@ -1,500 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="ALL" />
</component>
<component name="ChangeListManager">
<list default="true" id="ae3fb6a0-aca4-4c0a-858b-91952e6dcdd3" name="更改" comment="update 26.8.26">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitHubPullRequestSearchHistory">{
&quot;lastFilter&quot;: {
&quot;state&quot;: &quot;OPEN&quot;,
&quot;assignee&quot;: &quot;K7Unle&quot;
}
}</component>
<component name="GithubPullRequestsUISettings">{
&quot;selectedUrlAndAccountId&quot;: {
&quot;url&quot;: &quot;https://github.com/odysseus-dev/odysseus.git&quot;,
&quot;accountId&quot;: &quot;59f646c1-e8fd-42ab-afc6-29303ea39a06&quot;
}
}</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 2,
&quot;fromUser&quot;: false
}</component>
<component name="ProjectId" id="3H46bMJcHkyVuOl0gvBGV4kmqAO" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;codeWithMe.voiceChat.enabledByDefault&quot;: &quot;false&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;last_opened_file_path&quot;: &quot;/Users/kun/PycharmProjects/Docker_Compose/AI团队设计&quot;,
&quot;node.js.detected.package.jshint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.jshint&quot;: &quot;&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;configurable.group.project&quot;
}
}</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/AI团队设计" />
<recent name="$PROJECT_DIR$/4600Pro/so-novel" />
<recent name="$PROJECT_DIR$/4600Pro/So-Novel" />
<recent name="$PROJECT_DIR$/4600Pro/NocoDB" />
<recent name="$PROJECT_DIR$/480T/yuvomi" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/AI团队设计/EVA" />
<recent name="$PROJECT_DIR$/AI团队设计" />
<recent name="$PROJECT_DIR$/4600Pro" />
</key>
</component>
<component name="RunManager">
<configuration default="true" type="DjangoTestsConfigurationType">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<option name="TARGET" value="" />
<option name="SETTINGS_FILE" value="" />
<option name="CUSTOM_SETTINGS" value="false" />
<option name="USE_OPTIONS" value="false" />
<option name="OPTIONS" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Python.Celery" factoryName="Python.Celery.Task">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Python.Celery" factoryName="Python.Celery.App">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Python.FlaskServer">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<option name="launchJavascriptDebuger" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="docs" factoryName="Docutils task">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<option name="RUN_TOOL" value="" />
<option name="docutils_input_file" value="" />
<option name="docutils_output_file" value="" />
<option name="docutils_params" value="" />
<option name="docutils_task" value="" />
<option name="docutils_open_in_browser" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="docs" factoryName="Sphinx task">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<option name="RUN_TOOL" value="" />
<option name="docutils_input_file" value="" />
<option name="docutils_output_file" value="" />
<option name="docutils_params" value="" />
<option name="docutils_task" value="" />
<option name="docutils_open_in_browser" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="tests" factoryName="Doctests">
<module name="iStore_Docker_Compose" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="DEBUG_JUST_MY_CODE" value="false" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="RUN_TOOL" value="" />
<option name="SCRIPT_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="FOLDER_NAME" value="" />
<option name="TEST_TYPE" value="TEST_SCRIPT" />
<option name="PATTERN" value="" />
<option name="USE_PATTERN" value="false" />
<method v="2" />
</configuration>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-4abd2a77f808-JavaScript-PY-262.9437.214" />
<option value="bundled-python-sdk-821f704e66d9-5bd6d13a2a75-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-262.9437.214" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="ae3fb6a0-aca4-4c0a-858b-91952e6dcdd3" name="更改" comment="" />
<created>1785115064124</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1785115064124</updated>
<workItem from="1785115065245" duration="1091000" />
<workItem from="1785116797216" duration="42000" />
<workItem from="1785116865103" duration="229000" />
<workItem from="1785117096824" duration="55000" />
<workItem from="1785117158260" duration="1000" />
<workItem from="1785118558426" duration="729000" />
<workItem from="1785119377011" duration="1872000" />
<workItem from="1785220412801" duration="13000" />
<workItem from="1785223191705" duration="1000" />
<workItem from="1785223194581" duration="22000" />
<workItem from="1785392379765" duration="65000" />
<workItem from="1786005163392" duration="201000" />
<workItem from="1786005375680" duration="538000" />
<workItem from="1786065138152" duration="11000" />
<workItem from="1786082842659" duration="893000" />
<workItem from="1786323616451" duration="105000" />
<workItem from="1786409759648" duration="770000" />
<workItem from="1787022222565" duration="1218000" />
<workItem from="1787030835540" duration="2629000" />
<workItem from="1787281083838" duration="1163000" />
<workItem from="1787290752342" duration="56000" />
<workItem from="1787619581117" duration="1502000" />
<workItem from="1787635812810" duration="5000" />
<workItem from="1787635822806" duration="12539000" />
<workItem from="1787705701661" duration="856000" />
</task>
<task id="LOCAL-00001" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785117134273</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1785117134273</updated>
</task>
<task id="LOCAL-00002" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785119062713</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1785119062713</updated>
</task>
<task id="LOCAL-00003" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785119183055</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1785119183055</updated>
</task>
<task id="LOCAL-00004" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785119242447</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1785119242447</updated>
</task>
<task id="LOCAL-00005" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785119449261</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1785119449261</updated>
</task>
<task id="LOCAL-00006" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785119906941</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1785119906941</updated>
</task>
<task id="LOCAL-00007" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785120129210</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1785120129210</updated>
</task>
<task id="LOCAL-00008" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785120154958</created>
<option name="number" value="00008" />
<option name="presentableId" value="LOCAL-00008" />
<option name="project" value="LOCAL" />
<updated>1785120154958</updated>
</task>
<task id="LOCAL-00009" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785120590256</created>
<option name="number" value="00009" />
<option name="presentableId" value="LOCAL-00009" />
<option name="project" value="LOCAL" />
<updated>1785120590256</updated>
</task>
<task id="LOCAL-00010" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785120682944</created>
<option name="number" value="00010" />
<option name="presentableId" value="LOCAL-00010" />
<option name="project" value="LOCAL" />
<updated>1785120682944</updated>
</task>
<task id="LOCAL-00011" summary="update 26.7.30">
<option name="closed" value="true" />
<created>1785392423458</created>
<option name="number" value="00011" />
<option name="presentableId" value="LOCAL-00011" />
<option name="project" value="LOCAL" />
<updated>1785392423458</updated>
</task>
<task id="LOCAL-00012" summary="update 26.8.6">
<option name="closed" value="true" />
<created>1786005435040</created>
<option name="number" value="00012" />
<option name="presentableId" value="LOCAL-00012" />
<option name="project" value="LOCAL" />
<updated>1786005435040</updated>
</task>
<task id="LOCAL-00013" summary="update 26.8.7">
<option name="closed" value="true" />
<created>1786083110752</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1786083110752</updated>
</task>
<task id="LOCAL-00014" summary="update 26.8.10">
<option name="closed" value="true" />
<created>1786323673444</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1786323673444</updated>
</task>
<task id="LOCAL-00015" summary="update 26.8.10">
<option name="closed" value="true" />
<created>1786410272062</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1786410272062</updated>
</task>
<task id="LOCAL-00016" summary="update 26.8.11">
<option name="closed" value="true" />
<created>1786410474675</created>
<option name="number" value="00016" />
<option name="presentableId" value="LOCAL-00016" />
<option name="project" value="LOCAL" />
<updated>1786410474675</updated>
</task>
<task id="LOCAL-00017" summary="update 26.8.11">
<option name="closed" value="true" />
<created>1787022400600</created>
<option name="number" value="00017" />
<option name="presentableId" value="LOCAL-00017" />
<option name="project" value="LOCAL" />
<updated>1787022400600</updated>
</task>
<task id="LOCAL-00018" summary="update 26.8.11">
<option name="closed" value="true" />
<created>1787030905479</created>
<option name="number" value="00018" />
<option name="presentableId" value="LOCAL-00018" />
<option name="project" value="LOCAL" />
<updated>1787030905479</updated>
</task>
<task id="LOCAL-00019" summary="update 26.8.11">
<option name="closed" value="true" />
<created>1787031207232</created>
<option name="number" value="00019" />
<option name="presentableId" value="LOCAL-00019" />
<option name="project" value="LOCAL" />
<updated>1787031207232</updated>
</task>
<task id="LOCAL-00020" summary="update 26.8.11">
<option name="closed" value="true" />
<created>1787033233020</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1787033233020</updated>
</task>
<task id="LOCAL-00021" summary="update 26.8.21">
<option name="closed" value="true" />
<created>1787281188731</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1787281188731</updated>
</task>
<task id="LOCAL-00022" summary="update 26.8.25">
<option name="closed" value="true" />
<created>1787620183521</created>
<option name="number" value="00022" />
<option name="presentableId" value="LOCAL-00022" />
<option name="project" value="LOCAL" />
<updated>1787620183521</updated>
</task>
<task id="LOCAL-00023" summary="update 26.8.25">
<option name="closed" value="true" />
<created>1787620202451</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1787620202451</updated>
</task>
<task id="LOCAL-00024" summary="update 26.8.25">
<option name="closed" value="true" />
<created>1787620261315</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1787620261315</updated>
</task>
<task id="LOCAL-00025" summary="update 26.8.25">
<option name="closed" value="true" />
<created>1787648681948</created>
<option name="number" value="00025" />
<option name="presentableId" value="LOCAL-00025" />
<option name="project" value="LOCAL" />
<updated>1787648681948</updated>
</task>
<option name="localTasksCounter" value="26" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="update 26.7.27" />
<MESSAGE value="update 26.7.30" />
<MESSAGE value="update 26.8.6" />
<MESSAGE value="update 26.8.7" />
<MESSAGE value="update 26.8.10" />
<MESSAGE value="update 26.8.11" />
<MESSAGE value="update 26.8.21" />
<MESSAGE value="update 26.8.25" />
<option name="LAST_COMMIT_MESSAGE" value="update 26.8.25" />
</component>
</project>
+107
View File
@@ -0,0 +1,107 @@
# Docker image to run. Pin a sha-* tag or @sha256 digest for stricter deploys.
APP_IMAGE=ghcr.io/bookorbit/bookorbit:latest
# App publish port on host
# For access only from this host (such as a host reverse proxy), use 127.0.0.1:3000.
APP_PORT=2600
# Optional listen address inside the container (IPv4 or IPv6, without brackets).
# Keep the default for bridge networking; use APP_PORT above to restrict host exposure.
# HOST=0.0.0.0
# Host folder that appears as /books in the container.
# Point this at your library root; use an absolute path on NAS/Portainer installs.
BOOKS_HOST_PATH=/volume2/docker/docker_projects/bookorbit/books
APP_DATA_HOST_PATH=/volume2/docker/docker_projects/bookorbit/data/app
POSTGRES_DATA_HOST_PATH=/volume2/docker/docker_projects/bookorbit/data/postgres
# Container runtime UID/GID for files written to app-managed data folders.
# Most users can leave these defaults.
PUID=1000
PGID=1000
# Database credentials
POSTGRES_USER=bookorbit
POSTGRES_PASSWORD=nxY7HUoJYjUgn
POSTGRES_DB=bookorbit
# App secrets
JWT_SECRET=5c1c59712f970672a6cb09fd6e8823f44e024cd8633e11bdae5e616c743d3371
# Fresh installs should generate an independent key with: openssl rand -hex 32
# Existing installs upgrading from an older release must initially copy their current JWT_SECRET here so existing podcast URLs remain readable.
PODCAST_ENCRYPTION_KEY=5c1c59712f970672a6cb09fd6e8823f44e024cd8633e11bdae5e616c743d3371
# Required for the initial /auth/setup endpoint (x-setup-token header)
SETUP_BOOTSTRAP_TOKEN=5c1c59712f970672a6cb09fd6e8823f44e024cd8633e11bdae5e616c743d3371
# Sensitive values can instead be read from mounted files by appending _FILE.
# Leave the direct value blank, then set its _FILE variable to the container path.
# Keep the blank assignment: docker-compose.yml requires these keys to be present.
# A non-empty direct value and its _FILE variable are mutually exclusive.
# The file must be mounted into every service that uses it, and must not be empty.
# POSTGRES_PASSWORD_FILE=/run/secrets/bookorbit_postgres_password
# JWT_SECRET_FILE=/run/secrets/bookorbit_jwt_secret
# PODCAST_ENCRYPTION_KEY_FILE=/run/secrets/bookorbit_podcast_encryption_key
# SETUP_BOOTSTRAP_TOKEN_FILE=/run/secrets/bookorbit_setup_bootstrap_token
# External/public URL used by emails and Kobo endpoints
APP_URL=https://bookorbit.example.com
# Node.js JavaScript heap limit in MB. Raise this for very large libraries, 250K+ books.
NODE_MAX_OLD_SPACE_SIZE=2048
# --- Optional overrides (uncomment to set) ---
# If you already run your own PostgreSQL, set DATABASE_URL and remove the
# postgres service from docker-compose.yml. Your instance must have the
# uuid-ossp, pg_trgm, and vector (pgvector) extensions available.
# DATABASE_URL=postgres://user:password@yourhost:5432/bookorbit
# DATABASE_URL_FILE=/run/secrets/bookorbit_database_url
# Or set individual parts (POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB)
# CORS origin for the frontend when served from a different domain than APP_URL
# CLIENT_URL=https://app.example.com
# Container folder used as the top of the library creation folder picker.
# Defaults to / when unset. Set to /books to hide other container root folders.
# LIBRARY_BROWSE_ROOT=/books
# Set to false only if your platform manages bind mount ownership externally.
# BOOKORBIT_FIX_PERMISSIONS=true
# Recommended if you store SMTP provider credentials (generate: openssl rand -hex 32)
# EMAIL_ENCRYPTION_KEY=
# EMAIL_ENCRYPTION_KEY_FILE=/run/secrets/bookorbit_email_encryption_key
# Recommended if you store migration source credentials (generate: openssl rand -hex 32)
# MIGRATION_ENCRYPTION_KEY=
# MIGRATION_ENCRYPTION_KEY_FILE=/run/secrets/bookorbit_migration_encryption_key
# Required before download-client or indexer credentials can be saved.
# BOOK_REQUEST_ENCRYPTION_KEY=
# BOOK_REQUEST_ENCRYPTION_KEY_FILE=/run/secrets/bookorbit_book_request_encryption_key
# Optional GitHub token used to read release notes, raising the anonymous API rate limit.
# GITHUB_RELEASES_TOKEN=
# GITHUB_RELEASES_TOKEN_FILE=/run/secrets/bookorbit_github_releases_token
# Absolute container path that authorizes local migration backup files.
# Mount a dedicated host directory at this path as read-only before enabling backup mode.
# MIGRATION_IMPORT_ROOT=/imports
# Log level (default: info). Set to debug for verbose output.
# LOG_LEVEL=info
# Allow OIDC issuer/discovery URLs that resolve to private/local addresses.
# Default false. Enable only in trusted self-hosted networks.
# OIDC_ALLOW_LOCAL_ISSUERS=false
# Trust additional PEM-encoded certificate authorities for outbound TLS, including OIDC.
# Mount the CA bundle read-only, set its in-container path here, and restart BookOrbit.
# NODE_EXTRA_CA_CERTS=/path/to/private-ca-bundle.pem
# Disable username/password sign-in after at least one active administrator has linked an enabled
# OIDC provider. Set false and restart to recover access if the identity provider is unavailable.
# DISABLE_LOCAL_AUTH=false
# Optional: allow Cloudflare Web Analytics beacon when using automatic setup.
# Keep unset/false to preserve strict CSP (`script-src 'self'`).
# CSP_ALLOW_CLOUDFLARE_INSIGHTS=false
+96
View File
@@ -0,0 +1,96 @@
name: bookorbit
services:
app:
container_name: bookorbit-app
image: ${APP_IMAGE?required}
restart: unless-stopped
init: true
env_file:
- .env
ports:
- "${APP_PORT:-3000}:${PORT:-3000}"
environment:
NODE_ENV: production
PORT: ${PORT:-3000}
DATABASE_URL: ${DATABASE_URL:-}
POSTGRES_HOST: ${POSTGRES_HOST:-postgres}
POSTGRES_PORT: ${POSTGRES_PORT:-5432}
POSTGRES_USER: ${POSTGRES_USER?required}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD?required}
POSTGRES_DB: ${POSTGRES_DB?required}
JWT_SECRET: ${JWT_SECRET?required}
PODCAST_ENCRYPTION_KEY: ${PODCAST_ENCRYPTION_KEY:-}
SETUP_BOOTSTRAP_TOKEN: ${SETUP_BOOTSTRAP_TOKEN?required}
APP_URL: ${APP_URL?required}
CLIENT_URL: ${CLIENT_URL:-${APP_URL?required}}
TZ: ${TZ:-UTC}
PUID: ${PUID:-1000}
PGID: ${PGID:-1000}
NODE_MAX_OLD_SPACE_SIZE: ${NODE_MAX_OLD_SPACE_SIZE:-auto}
BOOK_DOCK_PATH: ${BOOK_DOCK_PATH:-}
LIBRARY_BROWSE_ROOT: ${LIBRARY_BROWSE_ROOT:-}
DISABLE_LOCAL_AUTH: ${DISABLE_LOCAL_AUTH:-false}
depends_on:
postgres:
condition: service_healthy
volumes:
- ${BOOKS_HOST_PATH:-./books}:/books
- ${APP_DATA_HOST_PATH:-./data/app}:/data
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETGID
- SETUID
security_opt:
- no-new-privileges:true
stop_grace_period: 30s
# Opt-in: add `--profile tts` to your compose commands. BookOrbit reaches it inside the compose
# network at http://kokoro:8880/v1, so no port is published to the host.
kokoro:
container_name: bookorbit-kokoro
image: ${KOKORO_IMAGE:-ghcr.io/remsky/kokoro-fastapi-cpu:v0.8.0}
profiles: ["tts"]
restart: unless-stopped
init: true
expose:
- "8880"
security_opt:
- no-new-privileges:true
stop_grace_period: 30s
healthcheck:
test:
[
"CMD-SHELL",
'python -c "import urllib.request;urllib.request.urlopen(''http://127.0.0.1:8880/v1/audio/voices'')"',
]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
postgres:
container_name: bookorbit-db
image: pgvector/pgvector:pg18
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER?required}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD?required}
POSTGRES_DB: ${POSTGRES_DB?required}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- ${POSTGRES_DATA_HOST_PATH:-./data/postgres}:/var/lib/postgresql/data
healthcheck:
test:
["CMD-SHELL", 'pg_isready -U "$${POSTGRES_USER}" -d "$${POSTGRES_DB}"']
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
-13
View File
@@ -1,13 +0,0 @@
services:
komga:
image: gotson/komga
container_name: komga
volumes:
# 本地卷宗挂载
- /volume2/docker/docker_projects/komga:/config
- /volume1/4600Pro/PornClub/Anime:/data
ports:
- "2600:25600"
environment:
- TZ=Asia/Shanghai
restart: unless-stopped
+38
View File
@@ -0,0 +1,38 @@
{
title:"逛逛GitHub",
id:"3516884134",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3516884134.xml",
htmlUrl:"http://192.168.0.111:300/feed/3516884134.xml"
},
title:"GitHub每日推文",
id:"3513986032",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3513986032.xml",
htmlUrl:"http://192.168.0.111:300/feed/3513986032.xml"
},
title:"HelloGitHub",
id:"3093627441",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3093627441.xml",
htmlUrl:"http://192.168.0.111:300/feed/3093627441.xml"
},
title:"GitHub精选",
id:"3003197367",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3003197367.xml",
htmlUrl:"http://192.168.0.111:300/feed/3003197367.xml"
},
title:"开源星探",
id:"3902447249",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3902447249.xml",
htmlUrl:"http://192.168.0.111:300/feed/3902447249.xml"
},
title:"数说123之上海",
id:"3918696924",
data_url:{
xmlUrl:"http://192.168.0.111:3000/feed/3918696924.xml",
htmlUrl:"http://192.168.0.111:300/feed/3918696924.xml"
}
}
+71
View File
@@ -0,0 +1,71 @@
services:
app:
image: mauriceboe/trek:latest
container_name: trek
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
tmpfs:
- /tmp:noexec,nosuid,size=128m
ports:
- "3600:3000"
environment:
- NODE_ENV=production
- PORT=3000
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-} # Recommended. Generate with: openssl rand -hex 32. If unset, falls back to data/.jwt_secret (existing installs) or auto-generates a key (fresh installs).
- TZ=${TZ:-UTC} # Timezone for logs, reminders and scheduled tasks (e.g. Europe/Berlin)
- LOG_LEVEL=${LOG_LEVEL:-info} # info = concise user actions; debug = verbose admin-level details
# - TREK_WIKI_DIR=/app/wiki # Where the in-app Help pages (/help) read their content from. Leave unset: the image ships the wiki at /app/wiki and finds it automatically. Only set this to serve your own docs, mounted into the container. If the path does not exist, Help falls back to fetching the public GitHub wiki (needs outbound network, and tracks the latest release rather than your version).
# - DEFAULT_LANGUAGE=en # Default language on the login page for users with no saved preference. Browser/OS language is auto-detected first; this is the fallback. Supported: de, en, es, fr, hu, nl, br, cs, pl, ru, zh, zh-TW, it, ar
# - SESSION_DURATION=30d # How long users stay logged in (trek_session JWT + cookie maxAge). Accepts: 1h | 12h | 7d | 30d | 90d. Default: 24h
# - SESSION_DURATION_REMEMBER=30d # Session length when "Remember me" is ticked at login: longer-lived JWT + persistent cookie that survives browser restarts. Same format as SESSION_DURATION. Default: 30d
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-} # Comma-separated origins for CORS and email notification links
# - FORCE_HTTPS=true # Optional. Enables HTTPS redirect, HSTS, CSP upgrade-insecure-requests, and secure cookies behind a TLS proxy
# - HSTS_INCLUDE_SUBDOMAINS=false # When true: adds includeSubDomains to the HSTS header. Only effective when HSTS is active. Leave false if sibling subdomains still run over plain HTTP.
# - COOKIE_SECURE=false # Escape hatch: force session cookies over plain HTTP even in production. Not recommended.
# - TRUST_PROXY=1 # Trusted proxy count for X-Forwarded-For / X-Forwarded-Proto. Required for FORCE_HTTPS to work.
# - ALLOW_INTERNAL_NETWORK=false # Set to true if Immich or other services are hosted on your local network (RFC-1918 IPs). Loopback and link-local addresses remain blocked regardless.
# - ALLOW_LINK_LOCAL_IPS= # Single link-local addresses TREK may reach after all, e.g. 169.254.1.2 for the host gateway of a rootless Podman container. Cloud metadata addresses cannot be listed.
# - HTTP_PROXY=${HTTP_PROXY:-} # Optional. Proxy URL for outbound HTTP requests (e.g. http://192.168.1.10:7890)
# - HTTPS_PROXY=${HTTPS_PROXY:-} # Optional. Proxy URL for outbound HTTPS requests
# - NO_PROXY=${NO_PROXY:-localhost,127.0.0.1} # Optional. Comma-separated hosts and domains that bypass the outbound proxy
# - APP_URL=https://trek.example.com # Public base URL — required when OIDC is enabled (must match the redirect URI registered with your IdP); also used as base URL for links in email notifications
# - OIDC_ISSUER=https://auth.example.com # OpenID Connect provider URL
# - OIDC_CLIENT_ID=trek # OpenID Connect client ID
# - OIDC_CLIENT_SECRET=supersecret # OpenID Connect client secret
# - OIDC_DISPLAY_NAME=SSO # Label shown on the SSO login button
# - OIDC_ONLY=false # Set true to force SSO-only mode: disables password login and registration, overrides Admin > Settings toggles, cannot be changed at runtime
# - OIDC_ADMIN_CLAIM=groups # OIDC claim used to identify admin users
# - OIDC_ADMIN_VALUE=app-trek-admins # Value of the OIDC claim that grants admin role
# - OIDC_SCOPE=openid email profile # Fully overrides the default. Add extra scopes as needed (e.g. add groups if using OIDC_ADMIN_CLAIM)
# - OIDC_DISCOVERY_URL= # Override the OIDC discovery endpoint for providers with non-standard paths (e.g. Authentik)
# - ADMIN_EMAIL=admin@trek.local # Initial admin e-mail — only used on first boot when no users exist
# - ADMIN_PASSWORD=changeme # Initial admin password — only used on first boot when no users exist
# - MCP_RATE_LIMIT=300 # Max MCP API requests per user per minute (default: 300)
# - MCP_MAX_SESSION_PER_USER=20 # Max concurrent MCP sessions per user (default: 20)
# - KITINERARY_EXTRACTOR_PATH= # Optional. Full path to kitinerary-extractor binary. Auto-detected from PATH and /usr/lib/*/libexec/kf6/ when unset.
# - LLM_TIMEOUT_MS=900000 # Optional. Ceiling (ms) for one AI-parsing call before it is abandoned, applied to every provider and to the HTTP client underneath. Generous by default so heavier documents fit; lower it on a cloud provider to fail fast. Must be a whole number of milliseconds between 1 and 2147483647 — anything else stops the server at startup with the reason. (default: 900000)
# - TREK_PLUGINS_IGNORE_TREK_RANGE=true # Optional. Lets plugins whose declared TREK version range predates this build, and plugins that declare none, be installed and activated anyway. Every gate warns instead of refusing; the plugin-API version gate and the Discover compatibility verdict stay hard. Off unless set. (default: off)
# - UNSPLASH_ACCESS_KEY= # Optional. Unsplash Access Key for trip-cover / place-image search. Without one, TREK uses Unsplash's unauthenticated endpoint, which some datacenter/VPS IPs are blocked from (#1449). Free key at unsplash.com/developers. Can also be set per-admin in Admin > Settings; the env var overrides that.
# - TREK_PLACES_ENABLED=false # Optional. Place search (suggestions, full search, category buttons, Road trip search, import geocoding, offline downloads) asks the TREK Places API at https://places.liketrek.com by default, so the server makes outbound requests to that host. Set false to search the way it did before 4.3.0 (OpenStreetMap, or your Google/Amap key) and send nothing there. No switch in the admin panel on purpose: whether searches leave the instance is decided here. (default: true)
# - TREK_PLACES_URL=https://places.liketrek.com # Optional. Base URL of a copy of the Places API you run yourself; it has to answer the same /v1 API. Read from configuration rather than typed by a user, so an address on your LAN or Docker network works without ALLOW_INTERNAL_NETWORK. (default: https://places.liketrek.com)
# - AMAP_API_KEY= # Optional. Amap (高德地图) Web 服务 key for place search and geocoding inside mainland China. Overrides the key set in Admin > Settings > API Keys. A Web 端 (JS API) key is a different credential and is rejected with INVALID_USER_KEY.
# - AMAP_API_SECRET= # Optional. The private secret (数字签名) of that key. Required exactly when the key was created with signing enabled, because such a key rejects every unsigned request. Leave unset otherwise.
# - AMAP_API_BASE=https://restapi.amap.com # Optional. Send the Amap calls through an egress proxy, a cache or a gateway that speaks the same API instead of restapi.amap.com directly. (default: https://restapi.amap.com)
volumes:
- /volume1/docker/docker_projects/trek/data:/app/data
- /volume1/docker/docker_projects/trek/uploads:/app/uploads
# - ./storage-config.json:/app/data/storage-config.json:ro # optional seed-once storage provisioning (wiki: Admin-Storage)
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
+119
View File
@@ -0,0 +1,119 @@
# 复制本文件为 .env 即可覆盖默认配置。全部可选——不建 .env 也能直接 `docker compose up -d`。
# 面板首个管理员账号 / 密码(仅首次启动、无账号文件时写入)。强烈建议改掉默认密码!
WOC_USER=yakun
WOC_PASSWORD=nxY7HUoJYjUgn
# 镜像版本:默认 latest;上线后建议钉到具体版本(如 1.0.0,注意不带 v)以便可控升级。
# 同时作用于面板镜像和新建微信实例所用镜像。
WOC_VERSION=latest
# 镜像源前缀(registry + 命名空间)。本项目镜像同步发布到 Docker Hub 和 GHCR。
#
# 默认走 Docker Hub:国内/国际通用、无需登录即可拉公开镜像,飞牛 OS(fnOS) 等 NAS 还内置拉取加速。
# 拉不动时按需切到备用源:
# WOC_IMAGE_PREFIX=ghcr.io/gloridust # GitHub Container Registry(备用)
# WOC_IMAGE_PREFIX=ghcr.nju.edu.cn/gloridust # 南京大学镜像站反代 ghcr.io(国内较稳)
# WOC_IMAGE_PREFIX=registry.cn-hangzhou.aliyuncs.com/你的命名空间 # 自己的阿里云 ACR / 腾讯 TCR / 华为 SWR
#
# 反代会把 docker.io/gloridust/xxx(或 ghcr.io/gloridust/xxx)映射为 <反代>/gloridust/xxx。
WOC_IMAGE_PREFIX=docker.io/gloridust
# 宿主用户 uid/gid(飞牛上用 `id` 命令查看;单用户 NAS 一般是 1000)。
# 透传给每个微信实例容器,决定面板数据与微信数据卷的属主。
WOC_PUID=1000
WOC_PGID=1000
# 时区
WOC_TZ=Asia/Shanghai
# 面板对外端口(宿主侧,默认用冷门端口避免冲突;容器内固定 8080)。
# 面板是唯一对外入口;微信实例不直接对宿主暴露,由面板反向代理。
WOC_HTTP_PORT=4500
# 面板允许的 Host 头白名单。用于阻止 DNS rebinding:攻击者控制的域名解析到面板
# LAN/loopback 地址后,浏览器视其为同源、自动带上面板 cookie,能从受害者浏览器内
# 发起任何已鉴权 API 调用(含挂载 docker.sock 的管理端点);sameSite=lax 不挡此攻击。
#
# 默认始终放行:localhost / 127.0.0.1 / ::1 + RFC1918 私网(10/8、172.16-31/12、
# 192.168/16、169.254/16)—— 覆盖直连 NAS / 局域网访问场景,**不需要改任何东西**。
#
# 套 HTTPS 反代部署(Caddy / nginx / 飞牛 内置反代 / Cloudflare Tunnel 等)时,把对外
# 域名加进来。**支持多个域名,用英文逗号分隔**;填免端口主机名,大小写不敏感:
#
# 单域名: PANEL_ALLOWED_HOSTS=woc.example.com
# 多域名: PANEL_ALLOWED_HOSTS=woc.example.com,woc.lan,wechat.mynas.cn
# 通配子域: PANEL_ALLOWED_HOSTS=*.example.com (匹配 a.example.com,不含裸 example.com)
# 含 IPv6 字面量:PANEL_ALLOWED_HOSTS=[2001:db8::1]
#
# 改完务必用 **docker compose up -d** 让容器带新环境重建;只 `docker restart` **不会**加载新值!
#
# 排错:若反代/Cloudflare 部署后仍看到 400 "Host header not allowed",错误响应里会回显面板实际
# 收到的 host / forwardedHost —— 把那个值(或其通配)加进本白名单即可。面板也会自动接受
# X-Forwarded-Host(可信反代设置),故多数反代无需额外配置。
PANEL_ALLOWED_HOSTS=
# ── 音频 / 麦克风 / 摄像头 ───────────────────────────────────
# 音频(听):**自动开启**,进入桌面、点一下画面(浏览器自动播放策略要求一次手势)即可出声,
# 无需手动找工具条。仅当前聚焦的实例出声,切走/切到别的实例会自动断开,避免多端串音。
# 麦克风(说) / 摄像头(视频):浏览器要求"安全上下文",即必须通过 HTTPS 访问面板
# (或 localhost)。生产环境务必给面板套 HTTPS(反代/证书),否则浏览器会禁用麦克风与摄像头。
#
# 摄像头还需要宿主提供一个虚拟视频设备(v4l2loopback):
# 1) 宿主安装并加载内核模块:
# Ubuntu/Debian: sudo apt install v4l2loopback-dkms && sudo modprobe v4l2loopback
# (飞牛/其它发行版若自带 v4l2loopback 同理 modprobe;没有则摄像头不可用,其余功能正常)
# 2) 确认出现了 /dev/videoN 设备。
# 3) 二选一让实例容器拿到该设备:
# a) 自动:保留 compose 里的 `/dev:/host-dev:ro` 挂载,面板会自动探测并映射;
# b) 显式:在下面列出设备(逗号分隔),并可删掉那条 /host-dev 挂载。
# 留空 = 不映射摄像头(音频/麦克风不受影响)。
WOC_VIDEO_DEVICES=
# ── 实例资源 / 稳定性 ───────────────────────────────────────
# GPU 硬件编码:baseimage 检测到 /dev/dri/renderD* 时会给 Xvnc 加 -hw3d(GPU 加速编码)。
# 在 WSL2 / 虚拟 GPU(如 Docker Desktop on Windows)下,该路径会导致 Xvnc 内存持续膨胀
# (实测 21 小时涨到 ~9GB)。本项目已强制软件渲染(LIBGL_ALWAYS_SOFTWARE=1),hw3d 对微信
# 这类静态界面收益甚微,故默认关闭。仅在你有真实可用的 GPU 且确认无内存问题时再设为 1 启用。
WOC_ENABLE_GPU=
# 每个微信实例容器的内存上限(GiB)。默认空 = 不限制(与旧版一致)。
# 作为兜底:万一某进程异常增长,命中上限时容器内 OOM 杀进程、由 s6 自动重启 VNC,
# 避免拖垮整台宿主。常规使用单实例约需 1~1.5GiB,设 3~4 较稳妥。
WOC_INSTANCE_MEM_GB=
# ── 设备伪装(降低被微信判"非真实设备"风控的概率) ───────────
# 每个实例默认已自动做:唯一且持久的 machine-id(避免全网共用同一个,触发"设备农场"风控)、
# 像个人电脑的 hostname(不再是 woc-wx-<hex>)、移除 /.dockerenv 容器标记。这些恒定开启。
#
# WOC_SPOOF_OS 是否把 /etc/os-release 伪装成 deepin(微信官方支持的发行版,且 Deepin 基于
# Debian、与本镜像用户态一致)。默认 1(开);设 0 恢复显示真实 Debian。
# 说明:设备伪装是「尽力而为」,非保证不被封;详见 doc/设备伪装.md。
WOC_SPOOF_OS=1
# 实例桌面深色:无需在此配置。面板顶栏右上角的主题开关(管理员)控制,设置持久化在面板数据。
# 仅对**浏览器(Chromium)实例**生效(--force-dark-mode,重启实例后生效);微信不吃命令行参数、也不跟随
# 极简容器的桌面信号,微信深色请在微信「设置→通用→深色模式」里手动选(随数据卷持久化)。
# ── 自愈 watchdog(应对 KasmVNC/Xvnc 长跑内存泄漏) ───────────
# 实测 Xvnc 长跑 24h 可膨胀到 ~9GiB,原因在 KasmVNC/Xvnc 自身的 framebuffer / 软渲染 cache
# 累积,不归本项目控制。面板内置一个 watchdog:周期性检查每个 running 实例的 working set
# 内存(= docker stats 显示值),按两档阈值(这里设全局默认;每个实例可在「管理 → 实例卡片
# → 安全」按钮里单独覆盖)触发主动 stop + run(聊天数据在卷里、登录态本来也会定期失效,
# 可控时机自愈优于撑到 OOM):
#
# soft 超过且【当前没人在远程会话】才重启 → 柔和自愈,不打扰使用者
# hard 超过即重启(无视会话),防止 OOM 拖垮宿主
#
# WOC_INSTANCE_MEM_SOFT_MB soft 阈值(MiB),默认 1500
# WOC_INSTANCE_MEM_HARD_MB hard 阈值(MiB),默认 2500(兼容旧名 WOC_INSTANCE_MEM_LIMIT_MB)
# WOC_WATCHDOG_INTERVAL_SEC 巡检间隔秒,默认 300(5 分钟);最小 60;0 = 关闭整个 watchdog
# WOC_WATCHDOG_HEALTH_FAILS VNC 响应性探测:连续无响应几次才重启实例;默认 0 = 关闭该探测(仅保留内存自愈)。
# 健康实例探测约 1ms,但宿主级 CPU/IO 偶发争用会让探测超时被误判为卡死而重启正常实例,故默认关闭;
# 想要"卡在正在连接桌面"时自动兜底,可设为正整数(如 3 = 连续 3 次≈15 分钟无响应才重启)。
#
# 调参建议:日常活跃单实例约 1500 MiB;soft 应略高于此(如 2000);hard 远低于宿主可用内存。
WOC_INSTANCE_MEM_SOFT_MB=1500
WOC_INSTANCE_MEM_HARD_MB=2500
WOC_WATCHDOG_INTERVAL_SEC=300
# WOC_WATCHDOG_HEALTH_FAILS=0
+67
View File
@@ -0,0 +1,67 @@
# WechatOnCloud —— 面板为唯一服务;微信实例由面板按需动态创建(docker run)。
# 面板挂载 docker.sock 来创建/启动/删除微信实例容器,并反向代理到它们的 KasmVNC。
# 镜像默认从 Docker Hub 拉取(GHCR 备用),无需本地构建。要改配置:复制 .env.example 为 .env 后修改。
services:
panel:
# 镜像源前缀默认 Docker Hub(飞牛等 NAS 有加速);拉不动时改 .env 的 WOC_IMAGE_PREFIX 切到 GHCR/国内反代(见 .env.example)。
image: ${WOC_IMAGE_PREFIX:-docker.io/gloridust}/woc-panel:${WOC_VERSION:-latest}
container_name: woc-panel
# pull_policy 用默认(missing):本地已有同名镜像就直接用,没有才去镜像源拉。
# 这样「发布前本地自构建」与「线上拉取」都能用同一份 compose。
# 想强制更新到最新版:docker compose pull && docker compose up -d
environment:
- PORT=8080
# 新建微信实例时使用的镜像(多架构,amd64/arm64 自动匹配);前缀同样跟随 WOC_IMAGE_PREFIX。
- WOC_WECHAT_IMAGE=${WOC_IMAGE_PREFIX:-docker.io/gloridust}/wechat-on-cloud:${WOC_VERSION:-latest}
# 透传给每个微信实例容器(KasmVNC 基础镜像用它们降权运行)
- PUID=${WOC_PUID:-1000}
- PGID=${WOC_PGID:-1000}
- TZ=${WOC_TZ:-Asia/Shanghai}
# 摄像头直通:逗号分隔的宿主视频设备(如 /dev/video0)。留空则自动探测(见下方 /host-dev 挂载)或禁用摄像头。
# 启用前需在宿主加载 v4l2loopback 内核模块。详见 .env.example。
- WOC_VIDEO_DEVICES=${WOC_VIDEO_DEVICES:-}
# 实例资源相关(见 .env.example):GPU 硬件编码默认关闭(避免 WSL2/虚拟 GPU 下 Xvnc 内存暴涨);
# 可选给每个实例设内存上限(GiB),0=不限制;watchdog 双阈值(soft 柔和自愈 / hard 强制重启)+ 巡检间隔。
- WOC_ENABLE_GPU=${WOC_ENABLE_GPU:-}
- WOC_INSTANCE_MEM_GB=${WOC_INSTANCE_MEM_GB:-}
- WOC_INSTANCE_MEM_SOFT_MB=${WOC_INSTANCE_MEM_SOFT_MB:-1500}
- WOC_INSTANCE_MEM_HARD_MB=${WOC_INSTANCE_MEM_HARD_MB:-2500}
- WOC_WATCHDOG_INTERVAL_SEC=${WOC_WATCHDOG_INTERVAL_SEC:-300}
# 设备伪装:os-release 伪装成 deepin(默认开,=0 关恢复 Debian)。详见 .env.example / doc/设备伪装.md。
- WOC_SPOOF_OS=${WOC_SPOOF_OS:-1}
# 登录会话时长(天,默认 30)。会话已落盘持久化:面板重启/自更新不再踢人。调小更安全、调大更省事。
- WOC_SESSION_DAYS=${WOC_SESSION_DAYS:-30}
# 拉取实例镜像的"无进度"超时(分钟,默认 5)。NAS 直连 docker.io 卡死时据此快速失败而非无限转圈。
- WOC_PULL_STALL_MIN=${WOC_PULL_STALL_MIN:-5}
# 实例桌面深色:由面板顶栏的主题开关统一控制(管理员),持久化在 accounts.json,无需在此配 env。
# 面板首个管理员账号(仅首次启动、无账号文件时写入;务必改掉默认密码)
- PANEL_ADMIN_USER=${WOC_USER:-admin}
- PANEL_ADMIN_PASSWORD=${WOC_PASSWORD:-wechat}
- PANEL_DATA=/data/accounts.json
# DNS-rebinding 防护:套 HTTPS 反代部署时把对外域名加进 .env(详见 .env.example)。
# 默认仅放行 loopback + RFC1918 私网,直连 NAS / 局域网无需改动。
- PANEL_ALLOWED_HOSTS=${PANEL_ALLOWED_HOSTS:-}
volumes:
# 面板账号数据(用户、实例元信息、密码哈希)
- /volume1/docker/docker_projects/wechat/data-panel:/data
# 面板经 docker 引擎创建/启动/删除微信实例容器、exec 触发下载、读取进度。
# 注意:docker.sock 等同宿主 root 权限,故实例增删仅限管理员,docker API 绝不暴露给前端。
- /var/run/docker.sock:/var/run/docker.sock
# 摄像头自动探测(可选):把宿主 /dev 只读挂进来,面板据此发现 /dev/videoN 并映射给实例。
# 不想自动探测就删掉此行,改用上面的 WOC_VIDEO_DEVICES 显式指定。
- /dev:/host-dev:ro
ports:
- "${WOC_HTTP_PORT:-36080}:8080" # 面板 = 唯一对外入口
# 日志硬上限:docker 默认 json-file 不限大小,长期运行/异常刷错会无限吃磁盘。
# (实例容器的同类上限由面板创建时注入,无需在此配置。)
logging:
driver: json-file
options:
max-size: "20m"
max-file: "2"
restart: unless-stopped
+18
View File
@@ -0,0 +1,18 @@
# ================================
# Hindsight
# ================================
HINDSIGHT_VERSION=latest
# ================================
# LLM
# ================================
# 第一阶段建议直接用 OpenAI
HINDSIGHT_API_LLM_PROVIDER=deepseek
# 替换为你的 API Key
HINDSIGHT_API_LLM_API_KEY=sk-2550c20fe4f943cf8bf94aca723dd5cf
# 模型
HINDSIGHT_API_LLM_MODEL=deepseek-v4-pro
+32
View File
@@ -0,0 +1,32 @@
version: "3.8"
services:
hindsight:
image: ghcr.io/vectorize-io/hindsight:${HINDSIGHT_VERSION:-latest}
container_name: hindsight
restart: always
ports:
# Hindsight API
- "8888:8888"
# Hindsight Control Plane / Web UI
- "4400:9999"
environment:
# 时区
- TZ=Asia/Shanghai
# LLM Provider
- HINDSIGHT_API_LLM_PROVIDER=${HINDSIGHT_API_LLM_PROVIDER:-openai}
# API Key
- HINDSIGHT_API_LLM_API_KEY=${HINDSIGHT_API_LLM_API_KEY}
# LLM Model
- HINDSIGHT_API_LLM_MODEL=${HINDSIGHT_API_LLM_MODEL:-gpt-4.1-mini}
volumes:
# Hindsight 内嵌 PostgreSQL 数据
- hindsight-data:/home/hindsight/.pg0
volumes:
hindsight-data:
+2
View File
@@ -0,0 +1,2 @@
MINIO_ROOT_USER=kun
MINIO_ROOT_PASSWORD=nxY7HUoJYjUgn
+1 -1
View File
@@ -3,7 +3,7 @@
REG_TOKEN=
DOMAIN=localhost
ROOT_URL=http://localhost:3000
RELEASE=8.7.1
RELEASE=8.8.0
# Change to true after you set your domain and valid lets encrypt email
LETSENCRYPT_ENABLED=false
LETSENCRYPT_EMAIL=demo@email.com
+34 -1
View File
@@ -28,6 +28,22 @@ UgreenNas(芯片:N6005,运行内存:32G,储存:1TB固态+35TB机械
9. yuvomi:`http://192.168.0.111:2700` 【家庭管理平台】
10. searxng:`http://192.168.0.111:2800` 【智能体搜素引擎MCP服务】
11: db-mcp-server:`http://192.168.0.111:2900` 【智能体数据库MCP服务】
12: wechat2rss:`http://192.168.0.111:2900` 【微信公众号Rss服务】
### 4600Pro主机
UgreenNas(芯片:N6005,运行内存:32G,储存:1TB固态+35TB机械硬盘【1TB SSD硬盘缓存】)
1. 节点小宝 【内网穿透】
2. socket-proxy:`http://192.168.0.111:1011` 【监管节点】
3. MoviePilot:`http://192.168.0.111:2100` 【影视平台】
4. mdcX:`http://192.168.0.111:2200` 【影视刮削器】
5. qBittorrent:`http://192.168.0.111:2300` 【下载器】
6. TG_Downloader:`http://192.168.0.111:2400` 【下载器】
7. qinglongPanel:`http://192.168.0.111:2500` 【python代码托管】
8. komga:`http://192.168.0.111:2600` 【漫画阅读器】
9. yuvomi:`http://192.168.0.111:2700` 【家庭管理平台】
10. searxng:`http://192.168.0.111:2800` 【智能体搜素引擎MCP服务】
11. db-mcp-server:`http://192.168.0.111:2900` 【智能体数据库MCP服务】
12. wechat2rss:`http://192.168.0.111:3000` 【微信公众号Rss服务】
### Ultra 7 255H 六盘位 NAS
------ 媒体及下载中心 ------
@@ -41,10 +57,26 @@ UgreenNas(芯片:Ultra 7 255H,运行内存:64G,储存:1TB固态+35TB
5. qBittorrent:`http://192.168.0.111:2400` 【下载器】
6. TG_Downloader:`http://192.168.0.111:2500` 【下载器】
7. qinglongPanel:`http://192.168.0.111:2600` 【python代码托管】【Frp:ql.kunle777.top】
8. komga:`http://192.168.0.111:2700` 【漫画阅读器】【Frp:komga.kunle777.top】
9. yuvomi:`http://192.168.0.111:2800` 【家庭管理平台】
10. SearXNG:`http://192.168.0.111:2900` 【智能体搜素引擎MCP服务】
### 480t主机
UgreenNas(芯片:1235U,运行内存:64GB,储存:4TB固态)
1. 节点小宝 【内网穿透】
2. cpolar 【监管节点】
3. socket-proxy:`http://192.168.0.112:1011` 【监管节点】
4. emby-serves1:`http://192.168.0.112:3100` 【影视平台1】
5. emby-serves2:`http://192.168.0.112:3200` 【影视平台2】
6. n8n_service:`http://192.168.0.112:3300` 【自动化平台】
7. dify:`http://192.168.0.112:3400` 【智能体平台】
8. minio:http://192.168.0.112:3500 【智能体数据库MCP服务】
x. TREK:http://192.168.0.112:3600 【智能体数据库MCP服务】
9. mysql数据库:`tcp://192.168.0.112:4100`
10. postgres数据库:`tcp://192.168.0.112:4200`
11. redis数据库:`tcp://192.168.0.112:4300`
12. hindsight:`tcp://192.168.0.112:4400`【hermesAgent记忆库】
### 480t主机
------ AI及数据中心 ------
UgreenNas(芯片:1235U,运行内存:64GB,储存:4TB固态)
@@ -55,3 +87,4 @@ UgreenNas(芯片:1235U,运行内存:64GB,储存:4TB固态)
5. minio:`http://192.168.0.112:4100` 【对象存储】
6. postgres数据库:`tcp://192.168.0.112:4200`
7. redis数据库:`tcp://192.168.0.112:4300`
9. hindsight:`tcp://192.168.0.112:4400`