mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 19:02:31 +00:00
fix: OCI image data paths, LAN endpoints for OpenAI-compatible AI and lab-validated apps
This commit is contained in:
@@ -397,6 +397,10 @@ const SELFHST_THEME_LOGOS: Record<string, { lightTheme: string; darkTheme: strin
|
|||||||
lightTheme: `${SELFHST_WEBP_BASE}/frigate-dark.webp`,
|
lightTheme: `${SELFHST_WEBP_BASE}/frigate-dark.webp`,
|
||||||
darkTheme: `${SELFHST_WEBP_BASE}/frigate-light.webp`,
|
darkTheme: `${SELFHST_WEBP_BASE}/frigate-light.webp`,
|
||||||
},
|
},
|
||||||
|
"llama-cpp": {
|
||||||
|
lightTheme: `${SELFHST_WEBP_BASE}/llama-cpp.webp`,
|
||||||
|
darkTheme: `${SELFHST_WEBP_BASE}/llama-cpp-light.webp`,
|
||||||
|
},
|
||||||
portainer: {
|
portainer: {
|
||||||
lightTheme: `${SELFHST_WEBP_BASE}/portainer-dark.webp`,
|
lightTheme: `${SELFHST_WEBP_BASE}/portainer-dark.webp`,
|
||||||
darkTheme: `${SELFHST_WEBP_BASE}/portainer-light.webp`,
|
darkTheme: `${SELFHST_WEBP_BASE}/portainer-light.webp`,
|
||||||
@@ -409,7 +413,7 @@ const SELFHST_THEME_LOGOS: Record<string, { lightTheme: string; darkTheme: strin
|
|||||||
|
|
||||||
function selfhstThemeLogos(src: string) {
|
function selfhstThemeLogos(src: string) {
|
||||||
if (!src.toLowerCase().includes("cdn.jsdelivr.net/gh/selfhst/icons")) return null
|
if (!src.toLowerCase().includes("cdn.jsdelivr.net/gh/selfhst/icons")) return null
|
||||||
const match = src.toLowerCase().match(/\/(frigate|portainer|vaultwarden)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/)
|
const match = src.toLowerCase().match(/\/(frigate|llama-cpp|portainer|vaultwarden)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/)
|
||||||
return match ? SELFHST_THEME_LOGOS[match[1]] : null
|
return match ? SELFHST_THEME_LOGOS[match[1]] : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3163,7 +3163,10 @@ class NotificationManager:
|
|||||||
if not ok:
|
if not ok:
|
||||||
raise ValueError(f"Invalid ai_ollama_url: {err}")
|
raise ValueError(f"Invalid ai_ollama_url: {err}")
|
||||||
if short_key == 'ai_openai_base_url' and str(value):
|
if short_key == 'ai_openai_base_url' and str(value):
|
||||||
ok, err = validate_external_url(str(value), allow_loopback=False)
|
# Custom OpenAI-compatible servers can run on the LAN or
|
||||||
|
# localhost, just like Ollama. Match test-ai/provider-models;
|
||||||
|
# unsafe schemes, metadata hosts and link-local stay blocked.
|
||||||
|
ok, err = validate_external_url(str(value), allow_loopback=True)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise ValueError(f"Invalid ai_openai_base_url: {err}")
|
raise ValueError(f"Invalid ai_openai_base_url: {err}")
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,41 @@ class OpenAICompatibleModelTests(unittest.TestCase):
|
|||||||
self.addCleanup(patcher.stop)
|
self.addCleanup(patcher.stop)
|
||||||
return db_path
|
return db_path
|
||||||
|
|
||||||
|
def test_local_compatible_endpoint_can_be_saved_and_reloaded(self):
|
||||||
|
db_path = self._temp_db_patch()
|
||||||
|
# Synthetic addresses cover each RFC1918 range; no network is used.
|
||||||
|
for url in ('http://10.0.0.10:8080/v1', 'http://172.16.0.10:8080/v1',
|
||||||
|
'http://192.168.1.10:8080/v1', 'http://localhost:8080/v1',
|
||||||
|
'http://127.0.0.1:8080/v1'):
|
||||||
|
with self.subTest(url=url):
|
||||||
|
manager = self._manager({})
|
||||||
|
result = manager.save_settings({'ai_openai_base_url': url})
|
||||||
|
self.assertTrue(result['success'], result)
|
||||||
|
with sqlite3.connect(db_path) as conn:
|
||||||
|
saved = conn.execute(
|
||||||
|
'SELECT setting_value FROM user_settings WHERE setting_key=?',
|
||||||
|
('notification.ai_openai_base_url',),
|
||||||
|
).fetchone()
|
||||||
|
self.assertEqual(saved, (url,))
|
||||||
|
reloaded = self._manager({})
|
||||||
|
reloaded._load_config()
|
||||||
|
self.assertEqual(reloaded._config['ai_openai_base_url'], url)
|
||||||
|
|
||||||
|
def test_local_compatible_endpoint_keeps_unsafe_urls_blocked(self):
|
||||||
|
db_path = self._temp_db_patch()
|
||||||
|
for url in ('file:///etc/shadow', 'http://169.254.169.254/latest/meta-data/',
|
||||||
|
'http://metadata.google.internal/', 'http://[fe80::1]/',
|
||||||
|
'http://0.0.0.0:8080/v1', 'http://224.0.0.1/v1'):
|
||||||
|
with self.subTest(url=url):
|
||||||
|
result = self._manager({}).save_settings({'ai_openai_base_url': url})
|
||||||
|
self.assertFalse(result['success'], result)
|
||||||
|
with sqlite3.connect(db_path) as conn:
|
||||||
|
saved = conn.execute(
|
||||||
|
'SELECT setting_value FROM user_settings WHERE setting_key=?',
|
||||||
|
('notification.ai_openai_base_url',),
|
||||||
|
).fetchone()
|
||||||
|
self.assertIsNone(saved)
|
||||||
|
|
||||||
def test_custom_openai_endpoint_omits_temperature_for_opaque_alias(self):
|
def test_custom_openai_endpoint_omits_temperature_for_opaque_alias(self):
|
||||||
provider = CapturingOpenAIProvider(
|
provider = CapturingOpenAIProvider(
|
||||||
api_key="token",
|
api_key="token",
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ A special thank you goes to [@Vaso73](https://github.com/Vaso73), [@f3rs3n](http
|
|||||||
- **The Ollama entry describes what the image provides** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), contributed by [@jcastro](https://github.com/jcastro)): its HTTP API on port 11434, with its link and startup check on `/api/version`.
|
- **The Ollama entry describes what the image provides** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), contributed by [@jcastro](https://github.com/jcastro)): its HTTP API on port 11434, with its link and startup check on `/api/version`.
|
||||||
- **An update clears the snapshot an interrupted backup leaves** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reported by [@kiosvantra](https://github.com/kiosvantra)). A snapshot made by the user stops the update, because a rebuilt container cannot keep it.
|
- **An update clears the snapshot an interrupted backup leaves** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reported by [@kiosvantra](https://github.com/kiosvantra)). A snapshot made by the user stops the update, because a rebuilt container cannot keep it.
|
||||||
- **A container that ignores the shutdown signal is stopped after 60 seconds**, as `docker stop` does, during an update and when an interrupted operation is recovered.
|
- **A container that ignores the shutdown signal is stopped after 60 seconds**, as `docker stop` does, during an update and when an interrupted operation is recovered.
|
||||||
- **SearXNG keeps its configuration in its own volume**, `/etc/searxng`, so Modify and updates accept it.
|
- **Modify and updates accept every application whose image declares a data path**: SearXNG, Tor, Whoogle and BIND9 keep it in a volume of its own, Kanboard keeps its certificates, and Chrony, Jaeger, PlantUML, UrBackup, GoToSocial, AceStream HTTP Proxy and RomM mark the paths that hold no data. When an installation still keeps such a path in the container, the message names it.
|
||||||
|
|
||||||
## 🖥️ Monitor — Proxmox updates and pending reboots
|
## 🖥️ Monitor — Proxmox updates and pending reboots
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
|
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
|
||||||
|
|
||||||
44 of 532 applications in the OCI catalog have been tested for real: 41 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
52 of 532 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
||||||
|
|
||||||
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
|
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com
|
|||||||
| Alby Hub ✨ | Finance & Budgeting |
|
| Alby Hub ✨ | Finance & Budgeting |
|
||||||
| Alist | Files & Sharing |
|
| Alist | Files & Sharing |
|
||||||
| aMule | Files & Downloads |
|
| aMule | Files & Downloads |
|
||||||
|
| Authentik | Authentication & Security |
|
||||||
| Chromium | Browsers & Web Desktops |
|
| Chromium | Browsers & Web Desktops |
|
||||||
| CodeProject.AI Server | AI |
|
| CodeProject.AI Server | AI |
|
||||||
| CopyParty | Files & Sharing |
|
| CopyParty | Files & Sharing |
|
||||||
@@ -50,26 +51,33 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com
|
|||||||
| Flexget | *Arr Suite |
|
| Flexget | *Arr Suite |
|
||||||
| Frigate | NVR & Cameras |
|
| Frigate | NVR & Cameras |
|
||||||
| Grafana | Monitoring & Analytics |
|
| Grafana | Monitoring & Analytics |
|
||||||
|
| HAOS One | IoT & Smart Home |
|
||||||
| Immich | Media |
|
| Immich | Media |
|
||||||
| JDownloader | Files & Downloads |
|
| JDownloader | Files & Downloads |
|
||||||
| Jenkins CI/CD | AI / Coding & Dev-Tools |
|
| Jenkins CI/CD | AI / Coding & Dev-Tools |
|
||||||
| Linkwarden | Documents & Notes |
|
| Linkwarden | Documents & Notes |
|
||||||
|
| Mariadb | Databases |
|
||||||
| Memos | Documents & Notes |
|
| Memos | Documents & Notes |
|
||||||
| MineOS | Gaming & Leisure |
|
| MineOS | Gaming & Leisure |
|
||||||
| Motioneye | NVR & Cameras |
|
| Motioneye | NVR & Cameras |
|
||||||
|
| Navidrome | Media & Streaming |
|
||||||
| Nextcloud | Productivity & Workflows |
|
| Nextcloud | Productivity & Workflows |
|
||||||
| Nextcloud Stack | Productivity & Workflows |
|
| Nextcloud Stack | Productivity & Workflows |
|
||||||
| OpenList | Files & Sharing |
|
| OpenList | Files & Sharing |
|
||||||
| Openssh Server | Remote Access & VPN |
|
| Openssh Server | Remote Access & VPN |
|
||||||
| Paperless-ngx | Productivity & Workflows |
|
| Paperless-ngx | Productivity & Workflows |
|
||||||
| Phpmyadmin | Databases |
|
| Phpmyadmin | Databases |
|
||||||
|
| Prowlarr | *Arr Suite |
|
||||||
| Qbittorrent | Files & Downloads |
|
| Qbittorrent | Files & Downloads |
|
||||||
| Rclone WebUI | Backup & Recovery |
|
| Rclone WebUI | Backup & Recovery |
|
||||||
| Real-Debrid Torrent Client | Files & Downloads |
|
| Real-Debrid Torrent Client | Files & Downloads |
|
||||||
|
| Scanopy | Network & Firewall |
|
||||||
| ShareCoveX | Files & Sharing |
|
| ShareCoveX | Files & Sharing |
|
||||||
| SnapOtter | Media & Streaming |
|
| SnapOtter | Media & Streaming |
|
||||||
|
| Sonarr | *Arr Suite |
|
||||||
| Tandoor Recipes | Productivity & Workflows |
|
| Tandoor Recipes | Productivity & Workflows |
|
||||||
| Thelounge | Communication & Community |
|
| Thelounge | Communication & Community |
|
||||||
| Trilium | Documents & Notes |
|
| Trilium | Documents & Notes |
|
||||||
|
| Vaultwarden | Authentication & Security |
|
||||||
| Wireguard | Remote Access & VPN |
|
| Wireguard | Remote Access & VPN |
|
||||||
| WireGuard Easy | Remote Access & VPN |
|
| WireGuard Easy | Remote Access & VPN |
|
||||||
|
|||||||
@@ -323,6 +323,9 @@
|
|||||||
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
|
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
|
||||||
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
|
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
|
||||||
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
|
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
|
||||||
|
],
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/home/appuser/.ACEStream"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,38 @@
|
|||||||
"backup": true,
|
"backup": true,
|
||||||
"default_size_gb": 2
|
"default_size_gb": 2
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-1",
|
||||||
|
"container_path": "/etc/bind",
|
||||||
|
"compose_source_example": "./config",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-2",
|
||||||
|
"container_path": "/var/lib/bind",
|
||||||
|
"compose_source_example": "./lib",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
@@ -123,7 +155,9 @@
|
|||||||
"53:53/tcp"
|
"53:53/tcp"
|
||||||
],
|
],
|
||||||
"volumes": [
|
"volumes": [
|
||||||
"./bind:/var/cache/bind"
|
"./bind:/var/cache/bind",
|
||||||
|
"./config:/etc/bind",
|
||||||
|
"./lib:/var/lib/bind"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,6 +185,28 @@
|
|||||||
"shared_with_other_lxc": false,
|
"shared_with_other_lxc": false,
|
||||||
"source_path": null,
|
"source_path": null,
|
||||||
"source_path_prompt": null
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bind9-volume-1",
|
||||||
|
"service": "bind9",
|
||||||
|
"container_path": "/etc/bind",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": true,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bind9-volume-2",
|
||||||
|
"service": "bind9",
|
||||||
|
"container_path": "/var/lib/bind",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": true,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
@@ -349,7 +405,11 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {},
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/var/log"
|
||||||
|
]
|
||||||
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
"replaces_discovered_ids": []
|
"replaces_discovered_ids": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,13 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {}
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/etc/chrony",
|
||||||
|
"/run/chrony",
|
||||||
|
"/var/lib/chrony"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"automatic_install_candidate": true,
|
"automatic_install_candidate": true,
|
||||||
|
|||||||
@@ -409,7 +409,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/gotosocial/.cache"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -345,7 +345,11 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {},
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/tmp"
|
||||||
|
]
|
||||||
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
"replaces_discovered_ids": []
|
"replaces_discovered_ids": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,22 @@
|
|||||||
"backup": true,
|
"backup": true,
|
||||||
"default_size_gb": 8
|
"default_size_gb": 8
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-2",
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"compose_source_example": "./ssl",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
@@ -134,7 +150,8 @@
|
|||||||
],
|
],
|
||||||
"volumes": [
|
"volumes": [
|
||||||
"./data:/var/www/app/data",
|
"./data:/var/www/app/data",
|
||||||
"./plugins:/var/www/app/plugins"
|
"./plugins:/var/www/app/plugins",
|
||||||
|
"./ssl:/etc/nginx/ssl"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,6 +188,17 @@
|
|||||||
"shared_with_other_lxc": false,
|
"shared_with_other_lxc": false,
|
||||||
"source_path": null,
|
"source_path": null,
|
||||||
"source_path_prompt": null
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "kanboard-volume-2",
|
||||||
|
"service": "kanboard",
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
@@ -391,6 +419,12 @@
|
|||||||
"remove_lost_found": true,
|
"remove_lost_found": true,
|
||||||
"owner_strategy": "mapped-application-user",
|
"owner_strategy": "mapped-application-user",
|
||||||
"only_when_mount_type": "managed-volume"
|
"only_when_mount_type": "managed-volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-root",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"startup_healthcheck": {
|
"startup_healthcheck": {
|
||||||
|
|||||||
@@ -329,7 +329,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/tmp/jetty"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -788,6 +788,9 @@
|
|||||||
"owner_strategy": "mapped-root",
|
"owner_strategy": "mapped-root",
|
||||||
"only_when_mount_type": "managed-volume"
|
"only_when_mount_type": "managed-volume"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/romm"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,7 +60,24 @@
|
|||||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||||
},
|
},
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"volumes": [],
|
"volumes": [
|
||||||
|
{
|
||||||
|
"id": "volume-0",
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"compose_source_example": "./tor-data",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
{
|
{
|
||||||
"container_port": 9050,
|
"container_port": 9050,
|
||||||
@@ -103,6 +120,9 @@
|
|||||||
"ports": [
|
"ports": [
|
||||||
"9050:9050",
|
"9050:9050",
|
||||||
"8118:8118"
|
"8118:8118"
|
||||||
|
],
|
||||||
|
"volumes": [
|
||||||
|
"./tor-data:/var/lib/tor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +139,19 @@
|
|||||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||||
"prompt_user_for_private_network": false
|
"prompt_user_for_private_network": false
|
||||||
},
|
},
|
||||||
"storage": [],
|
"storage": [
|
||||||
|
{
|
||||||
|
"id": "tor-volume-0",
|
||||||
|
"service": "tor",
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
"reserve_vmids_atomically": 1,
|
"reserve_vmids_atomically": 1,
|
||||||
"start_order": [
|
"start_order": [
|
||||||
@@ -323,7 +355,19 @@
|
|||||||
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
|
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
|
||||||
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
|
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
|
||||||
"Only applications configured to use this proxy send their traffic through Tor."
|
"Only applications configured to use this proxy send their traffic through Tor."
|
||||||
]
|
],
|
||||||
|
"volume_preparations": [
|
||||||
|
{
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-application-user",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"volume_owner": {
|
||||||
|
"uid": 101,
|
||||||
|
"gid": 102
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -323,7 +323,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/var/log"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"adaptations": [
|
"adaptations": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,7 +77,24 @@
|
|||||||
"source": "upstream-documentation"
|
"source": "upstream-documentation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"volumes": [],
|
"volumes": [
|
||||||
|
{
|
||||||
|
"id": "volume-0",
|
||||||
|
"container_path": "/config",
|
||||||
|
"compose_source_example": "./config",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
{
|
{
|
||||||
"container_port": 5000,
|
"container_port": 5000,
|
||||||
@@ -117,7 +134,10 @@
|
|||||||
"environment": {
|
"environment": {
|
||||||
"WHOOGLE_USER": "admin",
|
"WHOOGLE_USER": "admin",
|
||||||
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
|
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
|
||||||
}
|
},
|
||||||
|
"volumes": [
|
||||||
|
"./config:/config"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -133,7 +153,19 @@
|
|||||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||||
"prompt_user_for_private_network": false
|
"prompt_user_for_private_network": false
|
||||||
},
|
},
|
||||||
"storage": [],
|
"storage": [
|
||||||
|
{
|
||||||
|
"id": "whoogle-volume-0",
|
||||||
|
"service": "whoogle",
|
||||||
|
"container_path": "/config",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
"reserve_vmids_atomically": 1,
|
"reserve_vmids_atomically": 1,
|
||||||
"start_order": [
|
"start_order": [
|
||||||
@@ -378,6 +410,18 @@
|
|||||||
"bytes": 24,
|
"bytes": 24,
|
||||||
"prompt": false
|
"prompt": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"volume_preparations": [
|
||||||
|
{
|
||||||
|
"container_path": "/config",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-application-user",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"volume_owner": {
|
||||||
|
"uid": 927,
|
||||||
|
"gid": 927
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
|
|||||||
@@ -323,6 +323,9 @@
|
|||||||
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
|
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
|
||||||
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
|
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
|
||||||
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
|
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
|
||||||
|
],
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/home/appuser/.ACEStream"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,38 @@
|
|||||||
"backup": true,
|
"backup": true,
|
||||||
"default_size_gb": 2
|
"default_size_gb": 2
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-1",
|
||||||
|
"container_path": "/etc/bind",
|
||||||
|
"compose_source_example": "./config",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-2",
|
||||||
|
"container_path": "/var/lib/bind",
|
||||||
|
"compose_source_example": "./lib",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
@@ -123,7 +155,9 @@
|
|||||||
"53:53/tcp"
|
"53:53/tcp"
|
||||||
],
|
],
|
||||||
"volumes": [
|
"volumes": [
|
||||||
"./bind:/var/cache/bind"
|
"./bind:/var/cache/bind",
|
||||||
|
"./config:/etc/bind",
|
||||||
|
"./lib:/var/lib/bind"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,6 +185,28 @@
|
|||||||
"shared_with_other_lxc": false,
|
"shared_with_other_lxc": false,
|
||||||
"source_path": null,
|
"source_path": null,
|
||||||
"source_path_prompt": null
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bind9-volume-1",
|
||||||
|
"service": "bind9",
|
||||||
|
"container_path": "/etc/bind",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": true,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bind9-volume-2",
|
||||||
|
"service": "bind9",
|
||||||
|
"container_path": "/var/lib/bind",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": true,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
@@ -349,7 +405,11 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {},
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/var/log"
|
||||||
|
]
|
||||||
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
"replaces_discovered_ids": []
|
"replaces_discovered_ids": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,13 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {}
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/etc/chrony",
|
||||||
|
"/run/chrony",
|
||||||
|
"/var/lib/chrony"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"automatic_install_candidate": true,
|
"automatic_install_candidate": true,
|
||||||
|
|||||||
@@ -409,7 +409,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/gotosocial/.cache"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -345,7 +345,11 @@
|
|||||||
"validation": "not-requested-by-compose"
|
"validation": "not-requested-by-compose"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"installer_profile": {},
|
"installer_profile": {
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/tmp"
|
||||||
|
]
|
||||||
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
"replaces_discovered_ids": []
|
"replaces_discovered_ids": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,22 @@
|
|||||||
"backup": true,
|
"backup": true,
|
||||||
"default_size_gb": 8
|
"default_size_gb": 8
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume-2",
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"compose_source_example": "./ssl",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
@@ -134,7 +150,8 @@
|
|||||||
],
|
],
|
||||||
"volumes": [
|
"volumes": [
|
||||||
"./data:/var/www/app/data",
|
"./data:/var/www/app/data",
|
||||||
"./plugins:/var/www/app/plugins"
|
"./plugins:/var/www/app/plugins",
|
||||||
|
"./ssl:/etc/nginx/ssl"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,6 +188,17 @@
|
|||||||
"shared_with_other_lxc": false,
|
"shared_with_other_lxc": false,
|
||||||
"source_path": null,
|
"source_path": null,
|
||||||
"source_path_prompt": null
|
"source_path_prompt": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "kanboard-volume-2",
|
||||||
|
"service": "kanboard",
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
@@ -391,6 +419,12 @@
|
|||||||
"remove_lost_found": true,
|
"remove_lost_found": true,
|
||||||
"owner_strategy": "mapped-application-user",
|
"owner_strategy": "mapped-application-user",
|
||||||
"only_when_mount_type": "managed-volume"
|
"only_when_mount_type": "managed-volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"container_path": "/etc/nginx/ssl",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-root",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"startup_healthcheck": {
|
"startup_healthcheck": {
|
||||||
|
|||||||
@@ -329,7 +329,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/tmp/jetty"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -60,7 +60,24 @@
|
|||||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||||
},
|
},
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"volumes": [],
|
"volumes": [
|
||||||
|
{
|
||||||
|
"id": "volume-0",
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"compose_source_example": "./tor-data",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
{
|
{
|
||||||
"container_port": 9050,
|
"container_port": 9050,
|
||||||
@@ -103,6 +120,9 @@
|
|||||||
"ports": [
|
"ports": [
|
||||||
"9050:9050",
|
"9050:9050",
|
||||||
"8118:8118"
|
"8118:8118"
|
||||||
|
],
|
||||||
|
"volumes": [
|
||||||
|
"./tor-data:/var/lib/tor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +139,19 @@
|
|||||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||||
"prompt_user_for_private_network": false
|
"prompt_user_for_private_network": false
|
||||||
},
|
},
|
||||||
"storage": [],
|
"storage": [
|
||||||
|
{
|
||||||
|
"id": "tor-volume-0",
|
||||||
|
"service": "tor",
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
"reserve_vmids_atomically": 1,
|
"reserve_vmids_atomically": 1,
|
||||||
"start_order": [
|
"start_order": [
|
||||||
@@ -323,7 +355,19 @@
|
|||||||
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
|
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
|
||||||
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
|
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
|
||||||
"Only applications configured to use this proxy send their traffic through Tor."
|
"Only applications configured to use this proxy send their traffic through Tor."
|
||||||
]
|
],
|
||||||
|
"volume_preparations": [
|
||||||
|
{
|
||||||
|
"container_path": "/var/lib/tor",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-application-user",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"volume_owner": {
|
||||||
|
"uid": 101,
|
||||||
|
"gid": 102
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
|
|||||||
@@ -323,7 +323,10 @@
|
|||||||
"request_timeout_seconds": 10,
|
"request_timeout_seconds": 10,
|
||||||
"stability_seconds": 4,
|
"stability_seconds": 4,
|
||||||
"verify_tls": true
|
"verify_tls": true
|
||||||
}
|
},
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/var/log"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"adaptations": [
|
"adaptations": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,7 +77,24 @@
|
|||||||
"source": "upstream-documentation"
|
"source": "upstream-documentation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"volumes": [],
|
"volumes": [
|
||||||
|
{
|
||||||
|
"id": "volume-0",
|
||||||
|
"container_path": "/config",
|
||||||
|
"compose_source_example": "./config",
|
||||||
|
"read_only": false,
|
||||||
|
"required": true,
|
||||||
|
"installation_choice": [
|
||||||
|
"managed-volume",
|
||||||
|
"host-bind"
|
||||||
|
],
|
||||||
|
"default": "managed-volume",
|
||||||
|
"managed_volume": {
|
||||||
|
"backup": true,
|
||||||
|
"default_size_gb": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
{
|
{
|
||||||
"container_port": 5000,
|
"container_port": 5000,
|
||||||
@@ -117,7 +134,10 @@
|
|||||||
"environment": {
|
"environment": {
|
||||||
"WHOOGLE_USER": "admin",
|
"WHOOGLE_USER": "admin",
|
||||||
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
|
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
|
||||||
}
|
},
|
||||||
|
"volumes": [
|
||||||
|
"./config:/config"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -133,7 +153,19 @@
|
|||||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||||
"prompt_user_for_private_network": false
|
"prompt_user_for_private_network": false
|
||||||
},
|
},
|
||||||
"storage": [],
|
"storage": [
|
||||||
|
{
|
||||||
|
"id": "whoogle-volume-0",
|
||||||
|
"service": "whoogle",
|
||||||
|
"container_path": "/config",
|
||||||
|
"mode": "managed-volume",
|
||||||
|
"user_selectable": false,
|
||||||
|
"backup": true,
|
||||||
|
"shared_with_other_lxc": false,
|
||||||
|
"source_path": null,
|
||||||
|
"source_path_prompt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"orchestration": {
|
"orchestration": {
|
||||||
"reserve_vmids_atomically": 1,
|
"reserve_vmids_atomically": 1,
|
||||||
"start_order": [
|
"start_order": [
|
||||||
@@ -378,6 +410,18 @@
|
|||||||
"bytes": 24,
|
"bytes": 24,
|
||||||
"prompt": false
|
"prompt": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"volume_preparations": [
|
||||||
|
{
|
||||||
|
"container_path": "/config",
|
||||||
|
"remove_lost_found": true,
|
||||||
|
"owner_strategy": "mapped-application-user",
|
||||||
|
"only_when_mount_type": "managed-volume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"volume_owner": {
|
||||||
|
"uid": 927,
|
||||||
|
"gid": 927
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"catalog": {
|
"catalog": {
|
||||||
|
|||||||
@@ -99,6 +99,9 @@
|
|||||||
"owner_strategy": "mapped-root",
|
"owner_strategy": "mapped-root",
|
||||||
"only_when_mount_type": "managed-volume"
|
"only_when_mount_type": "managed-volume"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"non_persistent_image_volumes": [
|
||||||
|
"/romm"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
"amule": {
|
"amule": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"authentik": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"chromium": {
|
"chromium": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -62,6 +65,9 @@
|
|||||||
"grafana": {
|
"grafana": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"haos-one": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"immich": {
|
"immich": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -74,6 +80,9 @@
|
|||||||
"linkwarden": {
|
"linkwarden": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"mariadb": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"memos": {
|
"memos": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -83,6 +92,9 @@
|
|||||||
"motioneye": {
|
"motioneye": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"navidrome": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"nextcloud": {
|
"nextcloud": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -108,6 +120,9 @@
|
|||||||
"report": "https://github.com/MacRimi/ProxMenux/discussions/392#discussioncomment-18623868"
|
"report": "https://github.com/MacRimi/ProxMenux/discussions/392#discussioncomment-18623868"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prowlarr": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"qbittorrent": {
|
"qbittorrent": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -117,12 +132,18 @@
|
|||||||
"rdtclient": {
|
"rdtclient": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"scanopy": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"sharecovex": {
|
"sharecovex": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
"snapotter": {
|
"snapotter": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"sonarr": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"tandoor": {
|
"tandoor": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
@@ -140,6 +161,9 @@
|
|||||||
"trilium": {
|
"trilium": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
"vaultwarden": {
|
||||||
|
"status": "laboratory-validated"
|
||||||
|
},
|
||||||
"wg-easy": {
|
"wg-easy": {
|
||||||
"status": "laboratory-validated"
|
"status": "laboratory-validated"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -728,8 +728,9 @@ def preflight(record, candidate, config, coordinated=None, in_place=False, basel
|
|||||||
raise ValueError(translate('Required persistent paths cannot be removed'))
|
raise ValueError(translate('Required persistent paths cannot be removed'))
|
||||||
image_paths = set(record['observed']['image']['defaults'].get('Volumes') or {})
|
image_paths = set(record['observed']['image']['defaults'].get('Volumes') or {})
|
||||||
image_paths -= non_persistent_image_volumes(record['template'])
|
image_paths -= non_persistent_image_volumes(record['template'])
|
||||||
if any(not any(p == target or p.startswith(target.rstrip('/') + '/') for target in old) for p in image_paths):
|
in_rootfs = sorted(p for p in image_paths if not any(p == target or p.startswith(target.rstrip('/') + '/') for target in old))
|
||||||
raise ValueError(translate('The image declares data paths that are still stored in the rootfs'))
|
if in_rootfs:
|
||||||
|
raise ValueError(f"{translate('The image declares data paths that are still stored in the rootfs')}: {', '.join(in_rootfs)}")
|
||||||
check = effective_healthcheck(candidate['template'])
|
check = effective_healthcheck(candidate['template'])
|
||||||
if not check and not coordinated:
|
if not check and not coordinated:
|
||||||
raise ValueError(translate('Updates are not available yet for this application in this beta'))
|
raise ValueError(translate('Updates are not available yet for this application in this beta'))
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ def service_template(parent, service, main=False):
|
|||||||
own_preparations.append(entry)
|
own_preparations.append(entry)
|
||||||
if own_preparations:
|
if own_preparations:
|
||||||
single['proxmox'].setdefault('installer_profile', {})['volume_preparations'] = own_preparations
|
single['proxmox'].setdefault('installer_profile', {})['volume_preparations'] = own_preparations
|
||||||
|
# Image paths the oci-compose states hold no data; an image that does not
|
||||||
|
# declare one of them is not affected by it.
|
||||||
|
transient = parent.get('proxmox', {}).get('installer_profile', {}).get('non_persistent_image_volumes')
|
||||||
|
if transient:
|
||||||
|
single['proxmox'].setdefault('installer_profile', {})['non_persistent_image_volumes'] = list(transient)
|
||||||
return single
|
return single
|
||||||
|
|
||||||
|
|
||||||
@@ -784,10 +789,11 @@ def apply_stack_support(template):
|
|||||||
template['status'] = 'generated-review-required'
|
template['status'] = 'generated-review-required'
|
||||||
return
|
return
|
||||||
template['proxmox'].pop('generic_stack_review',None)
|
template['proxmox'].pop('generic_stack_review',None)
|
||||||
preserved_preparations = template['proxmox'].get('installer_profile',{}).get('volume_preparations')
|
profile = template['proxmox'].get('installer_profile',{})
|
||||||
template['proxmox']['installer_profile'] = {'stack_driver':'generic-multi-lxc-stack'}
|
template['proxmox']['installer_profile'] = {'stack_driver':'generic-multi-lxc-stack'}
|
||||||
if preserved_preparations:
|
for key in ('volume_preparations', 'non_persistent_image_volumes'):
|
||||||
template['proxmox']['installer_profile']['volume_preparations'] = preserved_preparations
|
if profile.get(key):
|
||||||
|
template['proxmox']['installer_profile'][key] = profile[key]
|
||||||
template['compatibility']['untranslated_blockers'] = []
|
template['compatibility']['untranslated_blockers'] = []
|
||||||
template['compatibility']['automatic_install_candidate'] = True
|
template['compatibility']['automatic_install_candidate'] = True
|
||||||
template['status'] = 'generated-unvalidated'
|
template['status'] = 'generated-unvalidated'
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
"""Image paths a stack's oci-compose states hold no data reach the template
|
||||||
|
of every container of the stack, where updates and Modify read them."""
|
||||||
|
import copy
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.path.insert(0, str(ROOT / "src"))
|
||||||
|
|
||||||
|
from proxmenux_oci.catalog import Catalog
|
||||||
|
from proxmenux_oci.stack import apply_stack_support, build_stack, DefaultsUI
|
||||||
|
|
||||||
|
|
||||||
|
class StackTransientImageVolumesTests(unittest.TestCase):
|
||||||
|
def test_each_container_of_romm_receives_the_transient_paths(self):
|
||||||
|
result = build_stack(Catalog(ROOT).compose("romm"), DefaultsUI(), mode="simple")
|
||||||
|
for service in result["services"]:
|
||||||
|
profile = service["template"]["proxmox"]["installer_profile"]
|
||||||
|
self.assertEqual(profile.get("non_persistent_image_volumes"), ["/romm"], service["name"])
|
||||||
|
|
||||||
|
def test_the_stack_profile_keeps_them_when_it_is_rewritten(self):
|
||||||
|
template = copy.deepcopy(Catalog(ROOT).compose("romm"))
|
||||||
|
template["proxmox"]["installer_profile"]["stack_driver"] = "generic-multi-lxc-stack"
|
||||||
|
apply_stack_support(template)
|
||||||
|
self.assertEqual(template["proxmox"]["installer_profile"].get("non_persistent_image_volumes"), ["/romm"])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -164,7 +164,9 @@ class UpdateCheckTests(unittest.TestCase):
|
|||||||
check.check(self.root, self.configs, path=path, progress=lambda *event: events.append(event))
|
check.check(self.root, self.configs, path=path, progress=lambda *event: events.append(event))
|
||||||
native.assert_called_once(); notify.assert_not_called(); external.assert_not_called()
|
native.assert_called_once(); notify.assert_not_called(); external.assert_not_called()
|
||||||
self.assertEqual(events[0], (0, 1)); self.assertEqual(events[-1], (1, 1))
|
self.assertEqual(events[0], (0, 1)); self.assertEqual(events[-1], (1, 1))
|
||||||
self.assertEqual([r['vmid'] for r in self.status()['available']], [110])
|
# The bridge stamps its result with the real clock, so read it at the real time too.
|
||||||
|
available = check.cached(self.root, self.configs, apps=self.apps)['available']
|
||||||
|
self.assertEqual([r['vmid'] for r in available], [110])
|
||||||
self.assertFalse((self.root / '.update-check.json').exists())
|
self.assertFalse((self.root / '.update-check.json').exists())
|
||||||
|
|
||||||
def test_missing_monitor_never_falls_back_to_registry_commands(self):
|
def test_missing_monitor_never_falls_back_to_registry_commands(self):
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Un agradecimiento especial a [@Vaso73](https://github.com/Vaso73), [@f3rs3n](htt
|
|||||||
- **La entrada de Ollama describe lo que ofrece la imagen** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), aportado por [@jcastro](https://github.com/jcastro)): su API HTTP en el puerto 11434, con el enlace y la comprobación de arranque en `/api/version`.
|
- **La entrada de Ollama describe lo que ofrece la imagen** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), aportado por [@jcastro](https://github.com/jcastro)): su API HTTP en el puerto 11434, con el enlace y la comprobación de arranque en `/api/version`.
|
||||||
- **Una actualización elimina el snapshot que deja un backup interrumpido** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reportado por [@kiosvantra](https://github.com/kiosvantra)). Un snapshot hecho por el usuario detiene la actualización, porque un contenedor reconstruido no puede conservarlo.
|
- **Una actualización elimina el snapshot que deja un backup interrumpido** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reportado por [@kiosvantra](https://github.com/kiosvantra)). Un snapshot hecho por el usuario detiene la actualización, porque un contenedor reconstruido no puede conservarlo.
|
||||||
- **Un contenedor que ignora la señal de apagado se detiene a los 60 segundos**, como hace `docker stop`, durante una actualización y al recuperar una operación interrumpida.
|
- **Un contenedor que ignora la señal de apagado se detiene a los 60 segundos**, como hace `docker stop`, durante una actualización y al recuperar una operación interrumpida.
|
||||||
- **SearXNG guarda su configuración en su propio volumen**, `/etc/searxng`, de modo que Modificar y las actualizaciones lo aceptan.
|
- **Modificar y las actualizaciones aceptan toda aplicación cuya imagen declara una ruta de datos**: SearXNG, Tor, Whoogle y BIND9 la guardan en un volumen propio, Kanboard conserva sus certificados, y Chrony, Jaeger, PlantUML, UrBackup, GoToSocial, AceStream HTTP Proxy y RomM marcan las rutas que no guardan datos. Cuando una instalación aún tiene una de esas rutas dentro del contenedor, el mensaje la nombra.
|
||||||
|
|
||||||
## 🖥️ Monitor — actualizaciones de Proxmox y reinicios pendientes
|
## 🖥️ Monitor — actualizaciones de Proxmox y reinicios pendientes
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user