Compare commits

..
Author SHA1 Message Date
github-actions[bot] 1a951c49c7 Screenshot: ct/marimo.sh (pve)-after-update for #18672 at 0a5d0d2 2026-11-13 13:30:35 +00:00
github-actions[bot] 19dc117137 Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 13:30:34 +00:00
github-actions[bot] bf280d38a0 Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:30:10 +00:00
github-actions[bot] 061f94dee0 Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:24:25 +00:00
github-actions[bot] 977e82f9e7 Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:18:53 +00:00
github-actions[bot] 7a8f833f5b Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:13:26 +00:00
github-actions[bot] 13ce043254 Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:06:36 +00:00
github-actions[bot] e3d8c3d14c Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 12:00:55 +00:00
github-actions[bot] 694d8897ed Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 11:54:43 +00:00
github-actions[bot] 1a08ed2101 Screenshot: ct/marimo.sh (arm64) for #18672 at 0a5d0d2 2026-11-13 11:47:19 +00:00
github-actions[bot] 7f73610052 Screenshot: ct/marimo.sh (incus) for #18672 at 0a5d0d2 2026-11-13 11:47:17 +00:00
github-actions[bot] fdd1438cea Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 11:47:16 +00:00
github-actions[bot] bfe85fc6bd Screenshot: ct/libredbstudio.sh (arm64)-after-update for #18699 at 93dbd8b 2026-11-13 11:41:27 +00:00
github-actions[bot] 167fe3dad2 Screenshot: ct/libredbstudio.sh (arm64) for #18699 at 93dbd8b 2026-11-13 11:41:25 +00:00
github-actions[bot] f404992a3c Screenshot: ct/libredbstudio.sh (incus)-after-update for #18699 at 93dbd8b 2026-11-13 11:41:23 +00:00
github-actions[bot] e5935edd98 Screenshot: ct/libredbstudio.sh (incus) for #18699 at 93dbd8b 2026-11-13 11:41:21 +00:00
github-actions[bot] a9f87e5008 Screenshot: ct/libredbstudio.sh (pve)-after-update for #18699 at 93dbd8b 2026-11-13 11:41:19 +00:00
github-actions[bot] e5419f76ed Screenshot: ct/libredbstudio.sh (pve) for #18699 at 93dbd8b 2026-11-13 11:41:17 +00:00
github-actions[bot] 5986051a83 Screenshot: ct/unsloth.sh (incus)-after-update for #18697 at de28b30 2026-11-13 11:39:32 +00:00
github-actions[bot] 5e02aa14f4 Screenshot: ct/unsloth.sh (incus) for #18697 at de28b30 2026-11-13 11:39:31 +00:00
github-actions[bot] cb09350e80 Screenshot: ct/unsloth.sh (pve)-after-update for #18697 at de28b30 2026-11-13 11:39:29 +00:00
github-actions[bot] 9defd43eee Screenshot: ct/unsloth.sh (pve) for #18697 at de28b30 2026-11-13 11:39:28 +00:00
github-actions[bot] 870822db0c Screenshot: ct/colanode.sh (arm64)-after-update for #18685 at 1632b00 2026-11-13 10:38:33 +00:00
github-actions[bot] c5d4248f97 Screenshot: ct/colanode.sh (arm64) for #18685 at 1632b00 2026-11-13 10:38:31 +00:00
github-actions[bot] 4e90c21097 Screenshot: ct/colanode.sh (incus)-after-update for #18685 at 1632b00 2026-11-13 10:38:30 +00:00
github-actions[bot] de008c64bb Screenshot: ct/colanode.sh (incus) for #18685 at 1632b00 2026-11-13 10:38:29 +00:00
github-actions[bot] c9d88a58f9 Screenshot: ct/colanode.sh (pve)-after-update for #18685 at 1632b00 2026-11-13 10:38:27 +00:00
github-actions[bot] 9116192266 Screenshot: ct/colanode.sh (pve) for #18685 at 1632b00 2026-11-13 10:38:26 +00:00
github-actions[bot] 4c9563a4de Screenshot: ct/simplelogin.sh (arm64)-after-update for #18680 at 2a28bf3 2026-11-13 10:19:49 +00:00
github-actions[bot] 2b39094aec Screenshot: ct/simplelogin.sh (arm64) for #18680 at 2a28bf3 2026-11-13 10:19:47 +00:00
github-actions[bot] 8aa4c0bf57 Screenshot: ct/simplelogin.sh (incus)-after-update for #18680 at 2a28bf3 2026-11-13 10:19:46 +00:00
github-actions[bot] 2ecefab480 Screenshot: ct/simplelogin.sh (incus) for #18680 at 2a28bf3 2026-11-13 10:19:44 +00:00
github-actions[bot] d21d45a5ac Screenshot: ct/simplelogin.sh (pve)-after-update for #18680 at 2a28bf3 2026-11-13 10:19:43 +00:00
github-actions[bot] df074ab2cd Screenshot: ct/simplelogin.sh (pve) for #18680 at 2a28bf3 2026-11-13 10:19:41 +00:00
github-actions[bot] 10f1f6beea Screenshot: ct/nightingale.sh (arm64)-after-update for #18674 at 76c4eb0 2026-11-13 10:10:39 +00:00
github-actions[bot] 22ae92c384 Screenshot: ct/nightingale.sh (arm64) for #18674 at 76c4eb0 2026-11-13 10:10:37 +00:00
github-actions[bot] fe947bf24a Screenshot: ct/aiostreams.sh (arm64)-after-update for #18673 at 95634fb 2026-11-13 10:02:02 +00:00
github-actions[bot] 0a56631631 Screenshot: ct/aiostreams.sh (arm64) for #18673 at 95634fb 2026-11-13 10:02:00 +00:00
github-actions[bot] 9f559b3e64 Screenshot: ct/temporal.sh (incus)-after-update for #18670 at bfe4e82 2026-11-13 09:53:43 +00:00
github-actions[bot] 5194e737de Screenshot: ct/temporal.sh (incus) for #18670 at bfe4e82 2026-11-13 09:53:42 +00:00
github-actions[bot] 5238f97162 Screenshot: ct/temporal.sh (pve)-after-update for #18670 at bfe4e82 2026-11-13 09:53:40 +00:00
github-actions[bot] ea8784b273 Screenshot: ct/temporal.sh (pve) for #18670 at bfe4e82 2026-11-13 09:53:39 +00:00
github-actions[bot] 6480e62e70 Screenshot: ct/marimo.sh (arm64) for #18672 at 0a5d0d2 2026-11-13 09:48:58 +00:00
github-actions[bot] 649c6b42c7 Screenshot: ct/marimo.sh (incus) for #18672 at 0a5d0d2 2026-11-13 09:48:57 +00:00
github-actions[bot] fddb4e4eff Screenshot: ct/marimo.sh (pve) for #18672 at 0a5d0d2 2026-11-13 09:48:55 +00:00
github-actions[bot] cce84491fa Screenshot: ct/trailbase.sh (arm64)-after-update for #18669 at a96a736 2026-11-13 09:46:14 +00:00
github-actions[bot] 27e2109a23 Screenshot: ct/trailbase.sh (arm64) for #18669 at a96a736 2026-11-13 09:46:12 +00:00
github-actions[bot] c8971784ad Screenshot: ct/trailbase.sh (incus)-after-update for #18669 at a96a736 2026-11-13 09:46:10 +00:00
github-actions[bot] 3b57c60e3a Screenshot: ct/trailbase.sh (incus) for #18669 at a96a736 2026-11-13 09:46:09 +00:00
github-actions[bot] 7b235ec1f4 Screenshot: ct/trailbase.sh (pve)-after-update for #18669 at a96a736 2026-11-13 09:46:07 +00:00
github-actions[bot] 8b4927e050 Screenshot: ct/trailbase.sh (pve) for #18669 at a96a736 2026-11-13 09:46:06 +00:00
github-actions[bot] b9c74271fd Screenshot: ct/weaviate.sh (arm64)-after-update for #18671 at b64d9a7 2026-11-13 09:42:07 +00:00
github-actions[bot] 29d3a59c44 Screenshot: ct/weaviate.sh (arm64) for #18671 at b64d9a7 2026-11-13 09:42:05 +00:00
github-actions[bot] ae4db6d06e Screenshot: ct/weaviate.sh (incus)-after-update for #18671 at b64d9a7 2026-11-13 09:42:04 +00:00
github-actions[bot] a7fa6a10b8 Screenshot: ct/weaviate.sh (incus) for #18671 at b64d9a7 2026-11-13 09:42:02 +00:00
github-actions[bot] ccf3026279 Screenshot: ct/weaviate.sh (pve)-after-update for #18671 at b64d9a7 2026-11-13 09:42:01 +00:00
github-actions[bot] 0211299bc9 Screenshot: ct/weaviate.sh (pve) for #18671 at b64d9a7 2026-11-13 09:41:59 +00:00
github-actions[bot] 976177ef02 Screenshot: ct/spacebot.sh (arm64)-after-update for #18668 at 6ab5b67 2026-11-13 09:37:42 +00:00
github-actions[bot] aa00e97302 Screenshot: ct/spacebot.sh (arm64) for #18668 at 6ab5b67 2026-11-13 09:37:40 +00:00
github-actions[bot] 3bf8fd8be5 Screenshot: ct/new-api.sh (arm64)-after-update for #18667 at fcf67de 2026-11-13 09:26:54 +00:00
github-actions[bot] 61514d0e92 Screenshot: ct/new-api.sh (arm64) for #18667 at fcf67de 2026-11-13 09:26:52 +00:00
github-actions[bot] 3af359f44d Screenshot: ct/new-api.sh (incus)-after-update for #18667 at fcf67de 2026-11-13 09:26:50 +00:00
github-actions[bot] a7cc2746ff Screenshot: ct/new-api.sh (incus) for #18667 at fcf67de 2026-11-13 09:26:48 +00:00
github-actions[bot] a4185178f9 Screenshot: ct/new-api.sh (pve)-after-update for #18667 at fcf67de 2026-11-13 09:26:47 +00:00
github-actions[bot] 4d0e096b1e Screenshot: ct/new-api.sh (pve) for #18667 at fcf67de 2026-11-13 09:26:45 +00:00
github-actions[bot] e415cfb261 Screenshot: ct/martin.sh (arm64)-after-update for #18666 at 996a4a0 2026-11-13 09:22:04 +00:00
github-actions[bot] f1b83df279 Screenshot: ct/martin.sh (arm64) for #18666 at 996a4a0 2026-11-13 09:22:03 +00:00
github-actions[bot] 2a11ceceff Screenshot: ct/martin.sh (incus)-after-update for #18666 at 996a4a0 2026-11-13 09:22:01 +00:00
github-actions[bot] 7eccee8d4f Screenshot: ct/martin.sh (incus) for #18666 at 996a4a0 2026-11-13 09:22:00 +00:00
github-actions[bot] 18c1d60b24 Screenshot: ct/martin.sh (pve)-after-update for #18666 at 996a4a0 2026-11-13 09:21:58 +00:00
github-actions[bot] af1f9b3064 Screenshot: ct/martin.sh (pve) for #18666 at 996a4a0 2026-11-13 09:21:56 +00:00
github-actions[bot] 28ec9ae77a Screenshot: ct/langflow.sh (arm64)-after-update for #18665 at 5205f53 2026-11-13 09:18:03 +00:00
github-actions[bot] e9faddb733 Screenshot: ct/langflow.sh (arm64) for #18665 at 5205f53 2026-11-13 09:18:01 +00:00
github-actions[bot] 693c4ef6e2 Screenshot: ct/langflow.sh (incus)-after-update for #18665 at 5205f53 2026-11-13 09:18:00 +00:00
github-actions[bot] 6b9389d16c Screenshot: ct/langflow.sh (incus) for #18665 at 5205f53 2026-11-13 09:17:58 +00:00
github-actions[bot] 94c8a7ecd7 Screenshot: ct/langflow.sh (pve)-after-update for #18665 at 5205f53 2026-11-13 09:17:57 +00:00
github-actions[bot] 389839d646 Screenshot: ct/langflow.sh (pve) for #18665 at 5205f53 2026-11-13 09:17:55 +00:00
github-actions[bot] bb057148a1 Screenshot: ct/inngest.sh (arm64)-after-update for #18664 at 2ed9368 2026-11-13 09:08:14 +00:00
github-actions[bot] cdcfde0661 Screenshot: ct/inngest.sh (arm64) for #18664 at 2ed9368 2026-11-13 09:08:12 +00:00
github-actions[bot] b4a4f0e886 Screenshot: ct/inngest.sh (incus)-after-update for #18664 at 2ed9368 2026-11-13 09:08:11 +00:00
github-actions[bot] 0ffff4559a Screenshot: ct/inngest.sh (incus) for #18664 at 2ed9368 2026-11-13 09:08:09 +00:00
github-actions[bot] ed5259e10e Screenshot: ct/inngest.sh (pve)-after-update for #18664 at 2ed9368 2026-11-13 09:08:07 +00:00
github-actions[bot] cf69cb4555 Screenshot: ct/inngest.sh (pve) for #18664 at 2ed9368 2026-11-13 09:08:04 +00:00
github-actions[bot] 358617f0e5 Screenshot: ct/hatchet.sh (arm64)-after-update for #18663 at df9a740 2026-11-13 09:03:06 +00:00
github-actions[bot] 8407dab667 Screenshot: ct/hatchet.sh (arm64) for #18663 at df9a740 2026-11-13 09:03:05 +00:00
github-actions[bot] d3e2fd3488 Screenshot: ct/hatchet.sh (incus)-after-update for #18663 at df9a740 2026-11-13 09:03:03 +00:00
github-actions[bot] 66a806f451 Screenshot: ct/hatchet.sh (incus) for #18663 at df9a740 2026-11-13 09:03:02 +00:00
github-actions[bot] ad04f427b3 Screenshot: ct/hatchet.sh (pve)-after-update for #18663 at df9a740 2026-11-13 09:03:00 +00:00
github-actions[bot] 1fb06dfe28 Screenshot: ct/hatchet.sh (pve) for #18663 at df9a740 2026-11-13 09:02:59 +00:00
github-actions[bot] ceb58eb458 Screenshot: ct/engram.sh (arm64)-after-update for #18661 at dbb1dc6 2026-11-13 08:41:08 +00:00
github-actions[bot] 2c97e0128d Screenshot: ct/engram.sh (arm64) for #18661 at dbb1dc6 2026-11-13 08:41:07 +00:00
github-actions[bot] 694bdf3756 Screenshot: ct/engram.sh (incus)-after-update for #18661 at dbb1dc6 2026-11-13 08:41:05 +00:00
github-actions[bot] 7055d46ec9 Screenshot: ct/engram.sh (incus) for #18661 at dbb1dc6 2026-11-13 08:41:04 +00:00
github-actions[bot] 7695f4100e Screenshot: ct/engram.sh (pve)-after-update for #18661 at dbb1dc6 2026-11-13 08:41:02 +00:00
github-actions[bot] 5a2ed3501d Screenshot: ct/engram.sh (pve) for #18661 at dbb1dc6 2026-11-13 08:41:00 +00:00
github-actions[bot] eee4480b79 Screenshot: ct/goatcounter.sh (arm64)-after-update for #18662 at bf9d32e 2026-11-13 08:35:29 +00:00
github-actions[bot] 6ea9017ad6 Screenshot: ct/goatcounter.sh (arm64) for #18662 at bf9d32e 2026-11-13 08:35:27 +00:00
github-actions[bot] 9e4e4ace2f Screenshot: ct/goatcounter.sh (incus)-after-update for #18662 at bf9d32e 2026-11-13 08:35:26 +00:00
github-actions[bot] 9fc31d47df Screenshot: ct/goatcounter.sh (incus) for #18662 at bf9d32e 2026-11-13 08:35:25 +00:00
github-actions[bot] f532a6090b Screenshot: ct/goatcounter.sh (pve)-after-update for #18662 at bf9d32e 2026-11-13 08:35:23 +00:00
github-actions[bot] 343d843767 Screenshot: ct/goatcounter.sh (pve) for #18662 at bf9d32e 2026-11-13 08:35:21 +00:00
github-actions[bot] 92560a6d3f Screenshot: ct/euro-office.sh (arm64)-after-update for #18660 at 47e8554 2026-11-13 08:30:26 +00:00
github-actions[bot] 3a5b8c410b Screenshot: ct/euro-office.sh (arm64) for #18660 at 47e8554 2026-11-13 08:30:24 +00:00
github-actions[bot] 282b0e1d9d Screenshot: ct/euro-office.sh (incus)-after-update for #18660 at 47e8554 2026-11-13 08:30:23 +00:00
github-actions[bot] 40153430d1 Screenshot: ct/euro-office.sh (incus) for #18660 at 47e8554 2026-11-13 08:30:22 +00:00
github-actions[bot] a6721df39a Screenshot: ct/euro-office.sh (pve)-after-update for #18660 at 47e8554 2026-11-13 08:30:20 +00:00
github-actions[bot] ad09567a22 Screenshot: ct/euro-office.sh (pve) for #18660 at 47e8554 2026-11-13 08:30:19 +00:00
github-actions[bot] cc1ec33170 Screenshot: ct/cypht.sh (arm64)-after-update for #18659 at 8f3e000 2026-11-13 08:20:37 +00:00
github-actions[bot] 1d66e965fa Screenshot: ct/cypht.sh (arm64) for #18659 at 8f3e000 2026-11-13 08:20:36 +00:00
github-actions[bot] c5b6b67c91 Screenshot: ct/cypht.sh (incus)-after-update for #18659 at 8f3e000 2026-11-13 08:20:34 +00:00
github-actions[bot] 0997e45e36 Screenshot: ct/cypht.sh (incus) for #18659 at 8f3e000 2026-11-13 08:20:33 +00:00
github-actions[bot] fb843f72db Screenshot: ct/cypht.sh (pve)-after-update for #18659 at 8f3e000 2026-11-13 08:20:31 +00:00
github-actions[bot] 8767fd589e Screenshot: ct/cypht.sh (pve) for #18659 at 8f3e000 2026-11-13 08:20:30 +00:00
github-actions[bot] eb25fed5fa Screenshot: ct/bulwark.sh (arm64)-after-update for #18656 at 4290d7a 2026-11-13 08:14:31 +00:00
github-actions[bot] e1b4b04c41 Screenshot: ct/bulwark.sh (arm64) for #18656 at 4290d7a 2026-11-13 08:14:30 +00:00
github-actions[bot] 61e0cc247a Screenshot: ct/bulwark.sh (incus)-after-update for #18656 at 4290d7a 2026-11-13 08:14:28 +00:00
github-actions[bot] 0a5e8e8f8f Screenshot: ct/bulwark.sh (incus) for #18656 at 4290d7a 2026-11-13 08:14:27 +00:00
github-actions[bot] 3a76caf9e3 Screenshot: ct/bulwark.sh (pve)-after-update for #18656 at 4290d7a 2026-11-13 08:14:25 +00:00
github-actions[bot] e593d1a94c Screenshot: ct/bulwark.sh (pve) for #18656 at 4290d7a 2026-11-13 08:14:24 +00:00
github-actions[bot] 35ccf8967c Screenshot: ct/convex.sh (arm64)-after-update for #18658 at 0c43b23 2026-11-13 08:08:11 +00:00
github-actions[bot] 3dc06c4074 Screenshot: ct/convex.sh (arm64) for #18658 at 0c43b23 2026-11-13 08:08:09 +00:00
github-actions[bot] f60a504448 Screenshot: ct/convex.sh (incus)-after-update for #18658 at 0c43b23 2026-11-13 08:08:08 +00:00
github-actions[bot] 8cb4317324 Screenshot: ct/convex.sh (incus) for #18658 at 0c43b23 2026-11-13 08:08:07 +00:00
github-actions[bot] c84dbb18a1 Screenshot: ct/convex.sh (pve)-after-update for #18658 at 0c43b23 2026-11-13 08:08:06 +00:00
github-actions[bot] 3852a09f81 Screenshot: ct/convex.sh (pve) for #18658 at 0c43b23 2026-11-13 08:08:04 +00:00
github-actions[bot] ad90eb0881 Screenshot: ct/chroma.sh (arm64)-after-update for #18657 at 8a7e004 2026-11-13 08:02:36 +00:00
github-actions[bot] 0ba1b7aed5 Screenshot: ct/chroma.sh (arm64) for #18657 at 8a7e004 2026-11-13 08:02:34 +00:00
github-actions[bot] eb5dd3e7e1 Screenshot: ct/chroma.sh (incus)-after-update for #18657 at 8a7e004 2026-11-13 08:02:33 +00:00
github-actions[bot] 26745d6e4f Screenshot: ct/chroma.sh (incus) for #18657 at 8a7e004 2026-11-13 08:02:31 +00:00
github-actions[bot] 4260567936 Screenshot: ct/chroma.sh (pve)-after-update for #18657 at 8a7e004 2026-11-13 08:02:30 +00:00
github-actions[bot] b02079943d Screenshot: ct/chroma.sh (pve) for #18657 at 8a7e004 2026-11-13 08:02:28 +00:00
github-actions[bot] 40c5adaabf Screenshot: ct/bugsink.sh (arm64)-after-update for #18655 at 70099c2 2026-11-13 07:56:51 +00:00
github-actions[bot] 33dcf66590 Screenshot: ct/bugsink.sh (arm64) for #18655 at 70099c2 2026-11-13 07:56:50 +00:00
github-actions[bot] 2fb6e7a273 Screenshot: ct/bugsink.sh (incus)-after-update for #18655 at 70099c2 2026-11-13 07:56:48 +00:00
github-actions[bot] 2f184db6bc Screenshot: ct/bugsink.sh (incus) for #18655 at 70099c2 2026-11-13 07:56:47 +00:00
github-actions[bot] 372d7375e1 Screenshot: ct/bugsink.sh (pve)-after-update for #18655 at 70099c2 2026-11-13 07:56:46 +00:00
github-actions[bot] 4a8398df9f Screenshot: ct/bugsink.sh (pve) for #18655 at 70099c2 2026-11-13 07:56:44 +00:00
github-actions[bot] c69ea31526 Screenshot: ct/9router.sh (arm64)-after-update for #18654 at f0d339e 2026-11-13 07:51:26 +00:00
github-actions[bot] d3c053c7dd Screenshot: ct/9router.sh (arm64) for #18654 at f0d339e 2026-11-13 07:51:24 +00:00
github-actions[bot] abf5004262 Screenshot: ct/9router.sh (incus)-after-update for #18654 at f0d339e 2026-11-13 07:51:23 +00:00
github-actions[bot] a3aec2a591 Screenshot: ct/9router.sh (incus) for #18654 at f0d339e 2026-11-13 07:51:21 +00:00
github-actions[bot] 67a07fa0b4 Screenshot: ct/9router.sh (pve)-after-update for #18654 at f0d339e 2026-11-13 07:51:20 +00:00
github-actions[bot] 1e73cea41d Screenshot: ct/9router.sh (pve) for #18654 at f0d339e 2026-11-13 07:51:18 +00:00
github-actions[bot] 426d72d92e Screenshot: ct/immich.sh (pve · upgrade)-after-update for #18605 at afef3ff 2026-11-12 16:48:47 +00:00
github-actions[bot] 9c0038177e Screenshot: ct/immich.sh (pve · upgrade) for #18605 at afef3ff 2026-11-12 16:48:46 +00:00
github-actions[bot] 44efba76fc Screenshot: ct/immich.sh (arm64)-after-update for #18605 at afef3ff 2026-11-12 16:48:44 +00:00
github-actions[bot] 9cfb9b3fb1 Screenshot: ct/immich.sh (arm64) for #18605 at afef3ff 2026-11-12 16:48:43 +00:00
github-actions[bot] 83cbde12e9 Screenshot: ct/immich.sh (incus)-after-update for #18605 at afef3ff 2026-11-12 16:48:41 +00:00
github-actions[bot] 348b4c4814 Screenshot: ct/immich.sh (incus) for #18605 at afef3ff 2026-11-12 16:48:40 +00:00
github-actions[bot] 2c941edbbf Screenshot: ct/immich.sh (pve)-after-update for #18605 at afef3ff 2026-11-12 16:48:38 +00:00
github-actions[bot] 8b6f353bfc Screenshot: ct/immich.sh (pve) for #18605 at afef3ff 2026-11-12 16:48:36 +00:00
github-actions[bot] 0ec6c1f2d4 Screenshot: ct/changedetection.sh (pve · upgrade)-after-update for #18613 at 5775dba 2026-11-12 16:07:04 +00:00
github-actions[bot] 47bd4b12aa Screenshot: ct/changedetection.sh (pve · upgrade) for #18613 at 5775dba 2026-11-12 16:07:01 +00:00
github-actions[bot] 50598ed1d1 Screenshot: ct/changedetection.sh (arm64)-after-update for #18613 at 5775dba 2026-11-12 16:06:59 +00:00
github-actions[bot] 13d4551d9b Screenshot: ct/changedetection.sh (arm64) for #18613 at 5775dba 2026-11-12 16:06:57 +00:00
github-actions[bot] 9309634f25 Screenshot: ct/changedetection.sh (incus)-after-update for #18613 at 5775dba 2026-11-12 16:06:56 +00:00
github-actions[bot] 6e619925c8 Screenshot: ct/changedetection.sh (incus) for #18613 at 5775dba 2026-11-12 16:06:53 +00:00
github-actions[bot] c7cecb8b32 Screenshot: ct/changedetection.sh (pve)-after-update for #18613 at 5775dba 2026-11-12 16:06:51 +00:00
github-actions[bot] 4b3ac31dbb Screenshot: ct/changedetection.sh (pve) for #18613 at 5775dba 2026-11-12 16:06:49 +00:00
github-actions[bot] be16da7a7f Screenshot: ct/onlyoffice.sh (arm64)-after-update for #18642 at d388830 2026-11-12 15:53:05 +00:00
github-actions[bot] f9603b9b0f Screenshot: ct/onlyoffice.sh (arm64) for #18642 at d388830 2026-11-12 15:53:03 +00:00
github-actions[bot] 0b053e237e Screenshot: ct/onlyoffice.sh (incus)-after-update for #18642 at d388830 2026-11-12 15:53:02 +00:00
github-actions[bot] 4f8acf4097 Screenshot: ct/onlyoffice.sh (incus) for #18642 at d388830 2026-11-12 15:53:00 +00:00
github-actions[bot] 0bf8da5c28 Screenshot: ct/onlyoffice.sh (pve)-after-update for #18642 at d388830 2026-11-12 15:52:59 +00:00
github-actions[bot] d554be4c7b Screenshot: ct/onlyoffice.sh (pve) for #18642 at d388830 2026-11-12 15:52:57 +00:00
github-actions[bot] 98daed03e4 Screenshot: ct/immich.sh (pve · upgrade)-after-update for #18605 at afef3ff 2026-11-12 15:44:43 +00:00
github-actions[bot] c46134c5be Screenshot: ct/immich.sh (arm64)-after-update for #18605 at afef3ff 2026-11-12 15:44:42 +00:00
github-actions[bot] 2915bb45a7 Screenshot: ct/immich.sh (arm64) for #18605 at afef3ff 2026-11-12 15:44:40 +00:00
github-actions[bot] 5497d56599 Screenshot: ct/immich.sh (incus)-after-update for #18605 at afef3ff 2026-11-12 15:44:38 +00:00
github-actions[bot] aed10ba902 Screenshot: ct/immich.sh (incus) for #18605 at afef3ff 2026-11-12 15:44:36 +00:00
github-actions[bot] b4530e21e8 Screenshot: ct/immich.sh (pve)-after-update for #18605 at afef3ff 2026-11-12 15:44:34 +00:00
github-actions[bot] f10f19329c Screenshot: ct/immich.sh (pve) for #18605 at afef3ff 2026-11-12 15:44:32 +00:00
github-actions[bot] 4d987d29c6 Screenshot: ct/onlyoffice.sh (arm64)-after-update for #18640 at 0d095e0 2026-11-12 15:39:13 +00:00
github-actions[bot] df8c71b0fa Screenshot: ct/onlyoffice.sh (arm64) for #18640 at 0d095e0 2026-11-12 15:39:11 +00:00
github-actions[bot] 4718d5382a Screenshot: ct/onlyoffice.sh (incus) for #18640 at 0d095e0 2026-11-12 15:39:10 +00:00
github-actions[bot] 429b31faf6 Screenshot: ct/onlyoffice.sh (pve)-after-update for #18640 at 0d095e0 2026-11-12 15:39:08 +00:00
github-actions[bot] b83fd4c84b Screenshot: ct/onlyoffice.sh (pve) for #18640 at 0d095e0 2026-11-12 15:39:06 +00:00
github-actions[bot] 782e2cac5e Screenshot: ct/immich.sh (pve · upgrade)-after-update for #18605 at 46f0678 2026-11-12 11:30:21 +00:00
github-actions[bot] 38c1b19349 Screenshot: ct/immich.sh (pve · upgrade) for #18605 at 46f0678 2026-11-12 11:30:19 +00:00
github-actions[bot] 6352efdb76 Screenshot: ct/immich.sh (arm64)-after-update for #18605 at 46f0678 2026-11-12 11:30:17 +00:00
github-actions[bot] ed7ae1f725 Screenshot: ct/immich.sh (arm64) for #18605 at 46f0678 2026-11-12 11:30:16 +00:00
github-actions[bot] a0511fe6ae Screenshot: ct/immich.sh (incus)-after-update for #18605 at 46f0678 2026-11-12 11:30:14 +00:00
github-actions[bot] 65cd1cf5e7 Screenshot: ct/immich.sh (incus) for #18605 at 46f0678 2026-11-12 11:30:13 +00:00
github-actions[bot] 88cbe39194 Screenshot: ct/immich.sh (pve)-after-update for #18605 at 46f0678 2026-11-12 11:30:12 +00:00
github-actions[bot] a62bba8d6b Screenshot: ct/immich.sh (pve) for #18605 at 46f0678 2026-11-12 11:30:10 +00:00
github-actions[bot] 960db7485a Screenshot: ct/changedetection.sh (arm64)-after-update for #18613 at 429194e 2026-11-12 10:23:21 +00:00
github-actions[bot] 8867442b99 Screenshot: ct/changedetection.sh (arm64) for #18613 at 429194e 2026-11-12 10:23:20 +00:00
github-actions[bot] 294d8fe08f Screenshot: ct/changedetection.sh (incus)-after-update for #18613 at 429194e 2026-11-12 10:23:18 +00:00
github-actions[bot] 0ef79b6060 Screenshot: ct/changedetection.sh (incus) for #18613 at 429194e 2026-11-12 10:23:16 +00:00
github-actions[bot] c43b84bb2d Screenshot: ct/changedetection.sh (pve)-after-update for #18613 at 429194e 2026-11-12 10:23:15 +00:00
github-actions[bot] 76ae39e535 Screenshot: ct/changedetection.sh (pve) for #18613 at 429194e 2026-11-12 10:23:13 +00:00
github-actions[bot] 096f9a0d0a Screenshot: ct/changedetection.sh (arm64)-after-update for #18613 at 429194e 2026-11-12 10:01:46 +00:00
github-actions[bot] 93ef75322b Screenshot: ct/changedetection.sh (arm64) for #18613 at 429194e 2026-11-12 10:01:44 +00:00
github-actions[bot] 3539ee9ea9 Screenshot: ct/changedetection.sh (incus)-after-update for #18613 at 429194e 2026-11-12 10:01:42 +00:00
github-actions[bot] 8522a01aaa Screenshot: ct/changedetection.sh (incus) for #18613 at 429194e 2026-11-12 10:01:40 +00:00
github-actions[bot] f4bb56b78f Screenshot: ct/whisparr-eros.sh (arm64)-after-update for #18617 at a05406e 2026-11-11 22:44:04 +00:00
github-actions[bot] 124f8dfa84 Screenshot: ct/whisparr-eros.sh (arm64) for #18617 at a05406e 2026-11-11 22:44:02 +00:00
github-actions[bot] 69a734f860 Screenshot: ct/whisparr-eros.sh (incus)-after-update for #18617 at a05406e 2026-11-11 22:44:00 +00:00
github-actions[bot] 07028ff084 Screenshot: ct/whisparr-eros.sh (incus) for #18617 at a05406e 2026-11-11 22:43:59 +00:00
github-actions[bot] 020bfebbf9 Screenshot: ct/whisparr-eros.sh (pve)-after-update for #18617 at a05406e 2026-11-11 22:43:57 +00:00
github-actions[bot] ddd35172b6 Screenshot: ct/whisparr-eros.sh (pve) for #18617 at a05406e 2026-11-11 22:43:55 +00:00
github-actions[bot] 03457df16f Screenshot: ct/pixelfed.sh (arm64)-after-update for #18523 at a022bd4 2026-11-11 22:27:36 +00:00
github-actions[bot] d50ca5fcae Screenshot: ct/pixelfed.sh (arm64) for #18523 at a022bd4 2026-11-11 22:27:35 +00:00
github-actions[bot] 0eba2f26bd Screenshot: ct/pixelfed.sh (incus)-after-update for #18523 at a022bd4 2026-11-11 22:27:33 +00:00
github-actions[bot] e60903bf60 Screenshot: ct/pixelfed.sh (incus) for #18523 at a022bd4 2026-11-11 22:27:32 +00:00
github-actions[bot] 433f0c069b Screenshot: ct/pixelfed.sh (pve)-after-update for #18523 at a022bd4 2026-11-11 22:27:30 +00:00
github-actions[bot] 01478959b1 Screenshot: ct/pixelfed.sh (pve) for #18523 at a022bd4 2026-11-11 22:27:28 +00:00
github-actions[bot] 80bfaf6662 Screenshot: ct/paperless-ai.sh (arm64)-after-update for #18620 at 5b1a07b 2026-11-11 22:20:16 +00:00
github-actions[bot] 9e347f202e Screenshot: ct/paperless-ai.sh (arm64) for #18620 at 5b1a07b 2026-11-11 22:20:14 +00:00
github-actions[bot] 7eb4b0f5ea Screenshot: ct/paperless-ai.sh (incus)-after-update for #18620 at 5b1a07b 2026-11-11 22:20:13 +00:00
github-actions[bot] 24fa4fc23c Screenshot: ct/paperless-ai.sh (incus) for #18620 at 5b1a07b 2026-11-11 22:20:10 +00:00
github-actions[bot] 84ce12efbf Screenshot: ct/paperless-ai.sh (pve)-after-update for #18620 at 5b1a07b 2026-11-11 22:20:08 +00:00
github-actions[bot] 42cd90761c Screenshot: ct/paperless-ai.sh (pve) for #18620 at 5b1a07b 2026-11-11 22:20:06 +00:00
github-actions[bot] 7c6c4f4598 Screenshot: ct/pixelfed.sh (arm64)-after-update for #18523 at a022bd4 2026-11-11 22:07:25 +00:00
github-actions[bot] 4da79e314d Screenshot: ct/pixelfed.sh (arm64) for #18523 at a022bd4 2026-11-11 22:07:23 +00:00
github-actions[bot] e4b1fdfb49 Screenshot: ct/pixelfed.sh (incus)-after-update for #18523 at a022bd4 2026-11-11 22:07:21 +00:00
github-actions[bot] 35f4023d6d Screenshot: ct/pixelfed.sh (incus) for #18523 at a022bd4 2026-11-11 22:07:20 +00:00
github-actions[bot] c12582e2b6 Screenshot: ct/pixelfed.sh (pve)-after-update for #18523 at a022bd4 2026-11-11 22:07:17 +00:00
github-actions[bot] 5f757cdcf3 Screenshot: ct/pixelfed.sh (pve) for #18523 at a022bd4 2026-11-11 22:07:15 +00:00
github-actions[bot] ba0644cdbb Screenshot: ct/changedetection.sh (incus)-after-update for #18613 at ddcb523 2026-11-11 15:11:05 +00:00
github-actions[bot] 092de60619 Screenshot: ct/changedetection.sh (incus) for #18613 at ddcb523 2026-11-11 15:11:02 +00:00
github-actions[bot] 7dc14c183d Screenshot: ct/changedetection.sh (pve)-after-update for #18613 at ddcb523 2026-11-11 15:11:00 +00:00
github-actions[bot] 395caa24be Screenshot: ct/changedetection.sh (pve) for #18613 at ddcb523 2026-11-11 15:10:58 +00:00
github-actions[bot] 67dedeefd1 Screenshot: ct/immich.sh (incus)-after-update for #18605 at 519e279 2026-11-11 15:05:32 +00:00
github-actions[bot] 33be56554e Screenshot: ct/immich.sh (incus) for #18605 at 519e279 2026-11-11 15:05:31 +00:00
github-actions[bot] a64c3ae787 Screenshot: ct/immich.sh (pve)-after-update for #18605 at 519e279 2026-11-11 15:05:29 +00:00
github-actions[bot] 1f10de36bc Screenshot: ct/immich.sh (pve) for #18605 at 519e279 2026-11-11 15:05:27 +00:00
github-actions[bot] 6978bf29fb Screenshot: ct/immich.sh (incus) for #18605 at 519e279 2026-11-11 12:25:29 +00:00
github-actions[bot] 8270c69c1c Screenshot: ct/immich.sh (pve) for #18605 at 519e279 2026-11-11 12:25:27 +00:00
github-actions[bot] 596a9626c1 Screenshot: ct/pocketbase.sh (incus)-after-update for #18609 at 6ba8cb6 2026-11-11 12:07:54 +00:00
github-actions[bot] bc053c5137 Screenshot: ct/pocketbase.sh (incus) for #18609 at 6ba8cb6 2026-11-11 12:07:52 +00:00
github-actions[bot] a872f8323f Screenshot: ct/pocketbase.sh (pve)-after-update for #18609 at 6ba8cb6 2026-11-11 12:07:51 +00:00
github-actions[bot] 44ce90bd39 Screenshot: ct/pocketbase.sh (pve) for #18609 at 6ba8cb6 2026-11-11 12:07:50 +00:00
github-actions[bot] 03c81a157c Screenshot: ct/immich.sh (incus) for #18605 at 609bfd0 2026-11-11 11:15:01 +00:00
github-actions[bot] 13063f879c Screenshot: ct/immich.sh (pve) for #18605 at 609bfd0 2026-11-11 11:14:59 +00:00
github-actions[bot] 4f3446d529 Screenshot: vm/truenas-vm.sh (VM) for #18578 at e258159 2026-11-11 11:11:48 +00:00
github-actions[bot] 030f643b24 Screenshot: ct/gotenberg.sh (default)-after-update for #18598 at f63d1bd 2026-11-11 10:00:34 +00:00
github-actions[bot] aeabe6d069 Screenshot: ct/gotenberg.sh (default) for #18598 at f63d1bd 2026-11-11 10:00:33 +00:00
github-actions[bot] 3ed19741ac Screenshot: ct/immich.sh (default) for #18600 at 8685d17 2026-11-11 09:55:19 +00:00
github-actions[bot] 5f93d6b1ee Screenshot: ct/gotenberg.sh (default) for #18602 at d0e1b8b 2026-11-11 09:23:12 +00:00
github-actions[bot] 342d5ab8da Screenshot: ct/pixelfed.sh (default) for #18523 at 422fec4 2026-11-10 15:33:33 +00:00
github-actions[bot] 40657fff33 Start ci-screenshots 2026-11-10 15:33:31 +00:00
2033 changed files with 1 additions and 124612 deletions

No files matched your search

-16
View File
@@ -1,16 +0,0 @@
; editorconfig.org
root = true
[*]
charset = utf-8
continuation_indent_size = 2
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 120
tab_width = 2
; trim_trailing_whitespace = true ; disabled until files are cleaned up
[*.md]
trim_trailing_whitespace = false
-38
View File
@@ -1,38 +0,0 @@
# ---------------------------------------
# Treat Shell files as first-class code
# ---------------------------------------
*.sh linguist-detectable=true
*.bash linguist-language=Shell
*.func linguist-language=Shell
*.install linguist-language=Shell
# ---------------------------------------
# Treat Golang files as Go (for /api/)
api/**/*.go linguist-language=Go
# ---------------------------------------
# Treat frontend as JavaScript/TypeScript (optional)
frontend/**/*.ts linguist-language=TypeScript
frontend/**/*.js linguist-language=JavaScript
# ---------------------------------------
# Exclude documentation from stats
*.md linguist-documentation
docs/** linguist-documentation
README.md linguist-documentation
CONTRIBUTING.md linguist-documentation
SECURITY.md linguist-documentation
# ---------------------------------------
# Exclude generated/config files
*.json linguist-generated
frontend/public/json/*.json linguist-generated=false
*.lock linguist-generated
*.yml linguist-generated
*.yaml linguist-generated
.github/** linguist-generated
.vscode/** linguist-generated
# ---------------------------------------
# Standard text handling
* text=auto eol=lf
-17
View File
@@ -1,17 +0,0 @@
#
# CODEOWNERS for ProxmoxVE
#
# Order is important; the last matching pattern takes the most
# precedence.
# Codeowners for specific folders and files
# Remember ending folders with /
# Set default reviewers
* @community-scripts/Contributor
# All changes in frontend
/frontend/ @community-scripts/Frontend-Dev
-132
View File
@@ -1,132 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
@@ -1,14 +0,0 @@
<div align="center">
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
</div>
<h2><div align="center">Exploring the Scripts and Steps Involved in an Application LXC Installation</div></h2>
1) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.)
2) [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func): Adds user settings and integrates collected information.
3) [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh): Constructs the LXC container.
4) [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), and installs the application.
5) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh) (again): To display the completion message.
The installation process uses reusable scripts: [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func), [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh), and [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), which are not specific to any particular application.
To gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container.
@@ -1,129 +0,0 @@
# Community Scripts Contribution Guide
## **Welcome to the communty-scripts Repository!**
📜 These documents outline the essential coding standards for all our scripts and JSON files. Adhering to these standards ensures that our codebase remains consistent, readable, and maintainable. By following these guidelines, we can improve collaboration, reduce errors, and enhance the overall quality of our project.
### Why Coding Standards Matter
Coding standards are crucial for several reasons:
1. **Consistency**: Consistent code is easier to read, understand, and maintain. It helps new team members quickly get up to speed and reduces the learning curve.
2. **Readability**: Clear and well-structured code is easier to debug and extend. It allows developers to quickly identify and fix issues.
3. **Maintainability**: Code that follows a standard structure is easier to refactor and update. It ensures that changes can be made with minimal risk of introducing new bugs.
4. **Collaboration**: When everyone follows the same standards, it becomes easier to collaborate on code. It reduces friction and misunderstandings during code reviews and merges.
### Scope of These Documents
These documents cover the coding standards for the following types of files in our project:
- **`install/$AppName-install.sh` Scripts**: These scripts are responsible for the installation of applications.
- **`ct/$AppName.sh` Scripts**: These scripts handle the creation and updating of containers.
- **`frontend/public/json/$AppName.json`**: These files store structured data and are used for the website.
Each section provides detailed guidelines on various aspects of coding, including shebang usage, comments, variable naming, function naming, indentation, error handling, command substitution, quoting, script structure, and logging. Additionally, examples are provided to illustrate the application of these standards.
By following the coding standards outlined in this document, we ensure that our scripts and JSON files are of high quality, making our project more robust and easier to manage. Please refer to this guide whenever you create or update scripts and JSON files to maintain a high standard of code quality across the project. 📚🔍
Let's work together to keep our codebase clean, efficient, and maintainable! 💪🚀
## Getting Started
Before contributing, please ensure that you have the following setup:
1. **Visual Studio Code** (recommended for script development)
2. **Recommended VS Code Extensions:**
- [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax)
- [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)
- [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format)
### Important Notes
- Use [AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh) and [AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh) as templates when creating new scripts. Final version of the script (the one you will push for review), must have all comments removed, except the ones in the file header.
---
# 🚀 The Application Script (ct/AppName.sh)
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md).
- These scripts are responsible for container creation, setting the necessary variables and handling the update of the application once installed.
---
# 🛠 The Installation Script (install/AppName-install.sh)
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.md).
- These scripts are responsible for the installation of the application.
---
## 🚀 Building Your Own Scripts
Start with the [template script](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh)
---
## 🤝 Contribution Process
All PR's related to new scripts should be made against our Dev repository first, where we can test the scripts before they are pushed and merged in the official repository.
**Our Dev repo is `http://www.github.com/community-scripts/ProxmoxVED`**
You will need to adjust paths mentioned further down this document to match the repo you're pushing the scripts to.
### 1. Fork the repository
Fork to your GitHub account
### 2. Clone your fork on your local environment
```bash
git clone https://github.com/yourUserName/ForkName
```
### 3. Create a new branch
```bash
git switch -c your-feature-branch
```
### 4. Change paths in build.func install.func and AppName.sh
To be able to develop from your own branch you need to change:\
`https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main`\
to\
`https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/heads/[BRANCH]`\
in following files:
`misc/build.func`\
`misc/install.func`\
`ct/AppName.sh`
Example: `https://raw.githubusercontent.com/tremor021/PromoxVE/refs/heads/testbranch`
Also you need to change:\
`https://raw.githubusercontent.com/community-scripts/ProxmoxVE/raw/main`\
to\
`https://raw.githubusercontent.com/[USER]/[REPOSITORY]/raw/[BRANCH]`\
in `misc/install.func` in order for `update` shell command to work.\
These changes are only while writing and testing your scripts. Before opening a Pull Request, you should change all above mentioned paths in `misc/build.func`, `misc/install.func` and `ct/AppName.sh` to point to the original paths.
### 4. Commit changes (without build.func and install.func!)
```bash
git commit -m "Your commit message"
```
### 5. Push to your fork
```bash
git push origin your-feature-branch
```
### 6. Create a Pull Request
Open a Pull Request from your feature branch to the main branch on the Dev repository. You must only include your **$AppName.sh**, **$AppName-install.sh** and **$AppName.json** files in the pull request.
---
## 📚 Pages
- [CT Template: AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh)
- [Install Template: AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh)
- [JSON Template: AppName.json](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/json/AppName.json)
@@ -1,44 +0,0 @@
<div align="center">
<a href="#">
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
</a>
</div>
<h2 align="center">User Submitted Guides </h2>
<sub> In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. </sub>
[Proxmox Automation with Proxmox Helper Scripts!](https://www.youtube.com/watch?v=kcpu4z5eSEU)
[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835)
[How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/)
[How To Install Home Assistant On Proxmox: The Easy Way](https://smarthomescene.com/guides/how-to-install-home-assistant-on-proxmox-the-easy-way/)
[Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html)
[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html)
[Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html)
[Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html)
[How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/)
[Running Frigate on Proxmox](https://www.homeautomationguy.io/blog/running-frigate-on-proxmox)
[Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html)
[Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/)
[How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html)
[iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs)
[Proxmox + NetData](<https://dbt3ch.com/books/proxmox-netdata-for-better-insights-and-notifications/page/proxmox-netdata-for-better-insights-and-notifications>)
[Proxmox Homelab Series](<https://blog.kye.dev/proxmox-series>)
[The fastest installation of Docker and Portainer on Proxmox VE](https://lavr.site/en-fastest-install-docker-portainer-proxmox/)
[How To Setup Proxmox Backuper Server Using Helper Scripts](<https://youtu.be/6C2JOsrZZZw?si=kkrrcL_nLCDBJkOB>)
@@ -1,287 +0,0 @@
# **AppName<span></span>.sh Scripts**
`AppName.sh` scripts found in the `/ct` directory. These scripts are responsible for the installation of the desired application. For this guide we take `/ct/snipeit.sh` as example.
## Table of Contents
- [**AppName.sh Scripts**](#appnamesh-scripts)
- [Table of Contents](#table-of-contents)
- [1. **File Header**](#1-file-header)
- [1.1 **Shebang**](#11-shebang)
- [1.2 **Import Functions**](#12-import-functions)
- [1.3 **Metadata**](#13-metadata)
- [2 **Variables and function import**](#2-variables-and-function-import)
- [2.1 **Default Values**](#21-default-values)
- [2.2 **📋 App output \& base settings**](#22--app-output--base-settings)
- [2.3 **🛠 Core functions**](#23--core-functions)
- [3 **Update function**](#3-update-function)
- [3.1 **Function Header**](#31-function-header)
- [3.2 **Check APP**](#32-check-app)
- [3.3 **Check version**](#33-check-version)
- [3.4 **Verbosity**](#34-verbosity)
- [3.5 **Backups**](#35-backups)
- [3.6 **Cleanup**](#36-cleanup)
- [3.7 **No update function**](#37-no-update-function)
- [4 **End of the script**](#4-end-of-the-script)
- [5. **Contribution checklist**](#5-contribution-checklist)
## 1. **File Header**
### 1.1 **Shebang**
- Use `#!/usr/bin/env bash` as the shebang.
```bash
#!/usr/bin/env bash
```
### 1.2 **Import Functions**
- Import the build.func file.
- When developing your own script, change the URL to your own repository.
> [!IMPORTANT]
> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func`
Example for development:
```bash
source <(curl -s https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func)
```
Final script:
```bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
```
> [!CAUTION]
> Before opening a Pull Request, change the URLs to point to the community-scripts repo.
### 1.3 **Metadata**
- Add clear comments for script metadata, including author, copyright, and license information.
Example:
```bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL]
```
> [!NOTE]:
>
> - Add your username and source URL
> - For existing scripts, add "| Co-Author [YourUserName]" after the current author
> - Source is a URL of github repo containting source files of the application you're installing (not URL of your homepage or a blog)
---
## 2 **Variables and function import**
>
> [!NOTE]
> You need to have all this set in your script, otherwise it will not work!
### 2.1 **Default Values**
- This section sets the default values for the container.
- `APP` needs to be set to the application name and must be equal to the filenames of your scripts.
- `var_tags`: You can set Tags for the CT wich show up in the Proxmox UI. Don´t overdo it!
>[!NOTE]
>Description for all Default Values
>
>| Variable | Description | Notes |
>|----------|-------------|-------|
>| `APP` | Application name | Must match ct\AppName.sh |
>| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number to 2 |
>| `var_cpu` | CPU cores | Number of cores |
>| `var_ram` | RAM | In MB |
>| `var_disk` | Disk capacity | In GB |
>| `var_os` | Operating system | alpine, debian, ubuntu |
>| `var_version` | OS version | e.g., 3.20, 11, 12, 20.04 |
>| `var_unprivileged` | Container type | 1 = Unprivileged, 0 = Privileged |
Example:
```bash
APP="SnipeIT"
var_tags="${var_tags:-asset-management;foss}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
```
## 2.2 **📋 App output & base settings**
```bash
header_info "$APP"
```
- `header_info`: Generates ASCII header for APP
## 2.3 **🛠 Core functions**
```bash
variables
color
catch_errors
```
- `variables`: Processes input and prepares variables
- `color`: Sets icons, colors, and formatting
- `catch_errors`: Enables error handling
---
## 3 **Update function**
### 3.1 **Function Header**
- If applicable write a function that updates the application and the OS in the container.
- Each update function starts with the same code:
```bash
function update_script() {
header_info
check_container_storage
check_container_resources
```
### 3.2 **Check APP**
- Before doing anything update-wise, check if the app is installed in the container.
Example:
```bash
if [[ ! -d /opt/snipe-it ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
```
### 3.3 **Check version**
- Before updating, check if a new version exists.
- We use the `${APPLICATION}_version.txt` file created in `/opt` during the install to compare new versions against the currently installed version.
Example with a Github Release:
```bash
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
#DO UPDATE
else
msg_ok "No update required. ${APP} is already at v${RELEASE}."
fi
exit
}
```
### 3.4 **Verbosity**
- Use the appropriate flag (**-q** in the examples) for a command to suppress its output.
Example:
```bash
wget -q
unzip -q
```
- If a command does not come with this functionality use `$STD` to suppress it's output.
Example:
```bash
$STD php artisan migrate --force
$STD php artisan config:clear
```
### 3.5 **Backups**
- Backup user data if necessary.
- Move all user data back in the directory when the update is finished.
>[!NOTE]
>This is not meant to be a permanent backup
Example backup:
```bash
mv /opt/snipe-it /opt/snipe-it-backup
```
Example config restore:
```bash
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
```
### 3.6 **Cleanup**
- Do not forget to remove any temporary files/folders such as zip-files or temporary backups.
Example:
```bash
rm -rf /opt/v${RELEASE}.zip
rm -rf /opt/snipe-it-backup
```
### 3.7 **No update function**
- In case you can not provide an update function use the following code to provide user feedback.
```bash
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/snipeit ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
```
---
## 4 **End of the script**
- `start`: Launches Whiptail dialogue
- `build_container`: Collects and integrates user settings
- `description`: Sets LXC container description
- With `echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"` you can point the user to the IP:PORT/folder needed to access the app.
```bash
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
```
---
## 5. **Contribution checklist**
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
- [ ] Correct link to *build.func*
- [ ] Metadata (author, license) is included at the top.
- [ ] Variables follow naming conventions.
- [ ] Update function exists.
- [ ] Update functions checks if app is installed and for new version.
- [ ] Update function cleans up temporary files.
- [ ] Script ends with a helpful message for the user to reach the application.
@@ -1,86 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL]
# App Default Values
# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole"
APP="[APP_NAME]"
# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp)
var_tags="${var_tags:-[TAGS]}"
# Number of cores (1-X) (e.g. 4) - default are 2
var_cpu="${var_cpu:-[CPU]}"
# Amount of used RAM in MB (e.g. 2048 or 4096)
var_ram="${var_ram:-[RAM]}"
# Amount of used disk space in GB (e.g. 4 or 10)
var_disk="${var_disk:-[DISK]}"
# Default OS (e.g. debian, ubuntu, alpine)
var_os="${var_os:-[OS]}"
# Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine)
var_version="${var_version:-[VERSION]}"
# 1 = unprivileged container, 0 = privileged container
var_unprivileged="${var_unprivileged:-[UNPRIVILEGED]}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
# Check if installation is present | -f for file, -d for folder
if [[ ! -f [INSTALLATION_CHECK_PATH] ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
# Crawling the new version and checking whether an update is required
RELEASE=$(curl -fsSL [RELEASE_URL] | [PARSE_RELEASE_COMMAND])
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
# Stopping Services
msg_info "Stopping $APP"
systemctl stop [SERVICE_NAME]
msg_ok "Stopped $APP"
# Creating Backup
msg_info "Creating Backup"
tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" [IMPORTANT_PATHS]
msg_ok "Backup Created"
# Execute Update
msg_info "Updating $APP to v${RELEASE}"
[UPDATE_COMMANDS]
msg_ok "Updated $APP to v${RELEASE}"
# Starting Services
msg_info "Starting $APP"
systemctl start [SERVICE_NAME]
msg_ok "Started $APP"
# Cleaning up
msg_info "Cleaning Up"
rm -rf [TEMP_FILES]
msg_ok "Cleanup Completed"
# Last Action
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Update Successful"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:[PORT]${CL}"
@@ -1,354 +0,0 @@
# **AppName<span></span>-install.sh Scripts**
`AppName-install.sh` scripts found in the `/install` directory. These scripts are responsible for the installation of the application. For this guide we take `/install/snipeit-install.sh` as example.
## Table of Contents
- [**AppName-install.sh Scripts**](#appname-installsh-scripts)
- [Table of Contents](#table-of-contents)
- [1. **File header**](#1-file-header)
- [1.1 **Shebang**](#11-shebang)
- [1.2 **Comments**](#12-comments)
- [1.3 **Variables and function import**](#13-variables-and-function-import)
- [2. **Variable naming and management**](#2-variable-naming-and-management)
- [2.1 **Naming conventions**](#21-naming-conventions)
- [3. **Dependencies**](#3-dependencies)
- [3.1 **Install all at once**](#31-install-all-at-once)
- [3.2 **Collapse dependencies**](#32-collapse-dependencies)
- [4. **Paths to application files**](#4-paths-to-application-files)
- [5. **Version management**](#5-version-management)
- [5.1 **Install the latest release**](#51-install-the-latest-release)
- [5.2 **Save the version for update checks**](#52-save-the-version-for-update-checks)
- [6. **Input and output management**](#6-input-and-output-management)
- [6.1 **User feedback**](#61-user-feedback)
- [6.2 **Verbosity**](#62-verbosity)
- [7. **String/File Manipulation**](#7-stringfile-manipulation)
- [7.1 **File Manipulation**](#71-file-manipulation)
- [8. **Security practices**](#8-security-practices)
- [8.1 **Password generation**](#81-password-generation)
- [8.2 **File permissions**](#82-file-permissions)
- [9. **Service Configuration**](#9-service-configuration)
- [9.1 **Configuration files**](#91-configuration-files)
- [9.2 **Credential management**](#92-credential-management)
- [9.3 **Enviroment files**](#93-enviroment-files)
- [9.4 **Services**](#94-services)
- [10. **Cleanup**](#10-cleanup)
- [10.1 **Remove temporary files**](#101-remove-temporary-files)
- [10.2 **Autoremove and autoclean**](#102-autoremove-and-autoclean)
- [11. **Best Practices Checklist**](#11-best-practices-checklist)
- [Example: High-Level Script Flow](#example-high-level-script-flow)
## 1. **File header**
### 1.1 **Shebang**
- Use `#!/usr/bin/env bash` as the shebang.
```bash
#!/usr/bin/env bash
```
### 1.2 **Comments**
- Add clear comments for script metadata, including author, copyright, and license information.
- Use meaningful inline comments to explain complex commands or logic.
Example:
```bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL]
```
> [!NOTE]:
>
> - Add your username
> - When updating/reworking scripts, add "| Co-Author [YourUserName]"
> - Source is a URL of github repo containting source files of the application you're installing (not URL of your homepage or a blog)
### 1.3 **Variables and function import**
- This sections adds the support for all needed functions and variables.
```bash
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
```
---
## 2. **Variable naming and management**
### 2.1 **Naming conventions**
- Use uppercase names for constants and environment variables.
- Use lowercase names for local script variables.
Example:
```bash
DB_NAME=snipeit_db # Environment-like variable (constant)
db_user="snipeit" # Local variable
```
---
## 3. **Dependencies**
### 3.1 **Install all at once**
- Install all dependencies with a single command if possible
Example:
```bash
$STD apt-get install -y \
composer \
git \
nginx
```
### 3.2 **Collapse dependencies**
Collapse dependencies to keep the code readable.
Example:
Use
```bash
php8.2-{bcmath,common,ctype}
```
instead of
```bash
php8.2-bcmath php8.2-common php8.2-ctype
```
---
## 4. **Paths to application files**
If possible install the app and all necessary files in `/opt/`
---
## 5. **Version management**
### 5.1 **Install the latest release**
- Always try and install the latest release
- Do not hardcode any version if not absolutely necessary
Example for a git release:
```bash
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
curl -fsSL "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip" -o "v${RELEASE}.zip"
```
### 5.2 **Save the version for update checks**
- Write the installed version into a file.
- This is used for the update function in **AppName.sh** to check for if a Update is needed.
Example:
```bash
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
```
---
## 6. **Input and output management**
### 6.1 **User feedback**
- Use standard functions like `msg_info`, `msg_ok` or `msg_error` to print status messages.
- Each `msg_info` must be followed with a `msg_ok` before any other output is made.
- Display meaningful progress messages at key stages.
- Taking user input with `read -p` must be outside of `msg_info`...`msg_ok` code block
Example:
```bash
msg_info "Installing Dependencies"
$STD apt-get install -y ...
msg_ok "Installed Dependencies"
read -p "${TAB3}Do you wish to enable HTTPS mode? (y/N): " httpschoice
```
### 6.2 **Verbosity**
- Use the appropiate flag (**-q** in the examples) for a command to suppres its output
Example:
```bash
wget -q
unzip -q
```
- If a command dose not come with such a functionality use `$STD` (a custom standard redirection variable) for managing output verbosity.
Example:
```bash
$STD apt-get install -y nginx
```
---
## 7. **String/File Manipulation**
### 7.1 **File Manipulation**
- Use `sed` to replace placeholder values in configuration files.
Example:
```bash
sed -i -e "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" \
-e "s|^DB_USERNAME=.*|DB_USERNAME=$DB_USER|" \
-e "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" .env
```
---
## 8. **Security practices**
### 8.1 **Password generation**
- Use `openssl` to generate random passwords.
- Use only alphanumeric values to not introduce unknown behaviour.
Example:
```bash
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
```
### 8.2 **File permissions**
Explicitly set secure ownership and permissions for sensitive files.
Example:
```bash
chown -R www-data: /opt/snipe-it
chmod -R 755 /opt/snipe-it
```
---
## 9. **Service Configuration**
### 9.1 **Configuration files**
Use `cat <<EOF` to write configuration files in a clean and readable way.
Example:
```bash
cat <<EOF >/etc/nginx/conf.d/snipeit.conf
server {
listen 80;
root /opt/snipe-it/public;
index index.php;
}
EOF
```
### 9.2 **Credential management**
Store the generated credentials in a file.
Example:
```bash
USERNAME=username
PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
{
echo "Application-Credentials"
echo "Username: $USERNAME"
echo "Password: $PASSWORD"
} >> ~/application.creds
```
### 9.3 **Enviroment files**
Use `cat <<EOF` to write enviromental files in a clean and readable way.
Example:
```bash
cat <<EOF >/path/to/.env
VARIABLE="value"
PORT=3000
DB_NAME="${DB_NAME}"
EOF
```
### 9.4 **Services**
Enable affected services after configuration changes and start them right away.
Example:
```bash
systemctl enable -q --now nginx
```
---
## 10. **Cleanup**
### 10.1 **Remove temporary files**
Remove temporary files and downloads after use.
Example:
```bash
rm -rf /opt/v${RELEASE}.zip
```
### 10.2 **Autoremove and autoclean**
Remove unused dependencies to reduce disk space usage.
Example:
```bash
apt-get -y autoremove
apt-get -y autoclean
```
---
## 11. **Best Practices Checklist**
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
- [ ] Metadata (author, license) is included at the top.
- [ ] Variables follow naming conventions.
- [ ] Sensitive values are dynamically generated.
- [ ] Files and services have proper permissions.
- [ ] Script cleans up temporary files.
---
### Example: High-Level Script Flow
1. Dependencies installation
2. Database setup
3. Download and configure application
4. Service configuration
5. Final cleanup
@@ -1,78 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL]
# Import Functions und Setup
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
# Installing Dependencies
msg_info "Installing Dependencies"
$STD apt-get install -y \
[PACKAGE_1] \
[PACKAGE_2] \
[PACKAGE_3]
msg_ok "Installed Dependencies"
# Template: MySQL Database
msg_info "Setting up Database"
DB_NAME=[DB_NAME]
DB_USER=[DB_USER]
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "${APPLICATION} Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/"$APP_NAME".creds
msg_ok "Set up Database"
# Setup App
msg_info "Setup ${APPLICATION}"
RELEASE=$(curl -fsSL https://api.github.com/repos/[REPO]/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
curl -fsSL -o "${RELEASE}.zip" "https://github.com/[REPO]/archive/refs/tags/${RELEASE}.zip"
unzip -q "${RELEASE}.zip"
mv "${APPLICATION}-${RELEASE}/" "/opt/${APPLICATION}"
#
#
#
echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt
msg_ok "Setup ${APPLICATION}"
# Creating Service (if needed)
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/"${APPLICATION}".service
[Unit]
Description=${APPLICATION} Service
After=network.target
[Service]
ExecStart=[START_COMMAND]
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now "${APPLICATION}"
msg_ok "Created Service"
motd_ssh
customize
# Cleanup
msg_info "Cleaning up"
rm -f "${RELEASE}".zip
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
@@ -1,34 +0,0 @@
{
"name": "AppName",
"slug": "appname",
"categories": [
0
],
"date_created": "DATE CREATED",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": DEFAULT-PORT,
"documentation": null,
"website": "LINK TO WEBSITE",
"logo": "LINK TO LOGO",
"description": "Description of the app",
"install_methods": [
{
"type": "default",
"script": "ct/AppName.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}
@@ -1,13 +0,0 @@
# **AppName<span></span>.json Files**
`AppName.json` files found in the `/json` directory. These files are used to provide informations for the website. For this guide we take `/json/snipeit.json` as example.
## Table of Contents
- [**AppName.json Files**](#appnamejson-files)
- [Table of Contents](#table-of-contents)
- [1. JSON Generator](#1-json-generator)
## 1. JSON Generator
Use the [JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor) to create this file for your application.
@@ -1,35 +0,0 @@
title: "[Script request]: "
labels: ["enhancement"]
body:
- type: input
attributes:
label: Application Name
description: Enter the application name.
placeholder: "e.g., Home Assistant"
validations:
required: true
- type: input
attributes:
label: Website
description: Official website or github page.
placeholder: "e.g., https://www.home-assistant.io/"
validations:
required: true
- type: textarea
attributes:
label: Description
description: Explain what the application does and why it should be added to Proxmox VE Helper-Scripts.
placeholder: "e.g., Home Assistant is a popular open-source platform that brings all your smart home devices together in one place. Adding it to Proxmox VE Helper-Scripts would make setup and management on Proxmox easy, letting users quickly get a powerful, self-hosted smart home system up and running."
validations:
required: true
- type: checkboxes
attributes:
label: Due Diligence
options:
- label: "I have searched existing [scripts](https://community-scripts.github.io/Proxmox/scripts) and found no duplicates."
required: true
- label: "I have searched existing [discussions](https://github.com/community-scripts/ProxmoxVE/discussions?discussions_q=) and found no duplicate requests."
required: true
- type: markdown
attributes:
value: "Thanks for submitting your request! The team will review it and reach out if we need more information."
-2
View File
@@ -1,2 +0,0 @@
ko_fi: community_scripts
github: community_scripts
-107
View File
@@ -1,107 +0,0 @@
name: "🐞 Script Issue Report"
description: Report a specific issue with a script. For other inquiries, please use the Discussions section.
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
## ⚠️ **IMPORTANT - READ FIRST**
- 🔍 **Search first:** Before submitting, check if the issue has already been reported or resolved in [closed issues](https://github.com/community-scripts/ProxmoxVE/issues?q=is%3Aissue+is%3Aclosed). If found, comment on that issue instead of creating a new one.
Alternatively, check the **[Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)** under the *"Announcement"* or *"Guide"* categories for relevant information.
- 🔎 If you encounter `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, rerun the script with verbose mode before submitting the issue.
- 📜 **Read the script:** Familiarize yourself with the script's content and its purpose. This will help you understand the issue better and provide more relevant information
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
- type: input
id: guidelines
attributes:
label: ✅ Have you read and understood the above guidelines?
placeholder: "yes"
validations:
required: true
- type: input
id: script_name
attributes:
label: 📜 What is the name of the script you are using?
placeholder: "e.g., NextcloudPi, Zigbee2MQTT"
validations:
required: true
- type: input
id: script_command
attributes:
label: 📂 What was the exact command used to execute the script?
placeholder: "e.g., bash -c \"$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/zigbee2mqtt.sh)\" or \"update\""
validations:
required: true
- type: checkboxes
validations:
required: true
attributes:
label: ⚙️ What settings are you using?
options:
- label: Default Settings
- label: Advanced Settings
- type: markdown
attributes:
value: "💡 **Tip:** If you are using Advanced Settings, please test with Default Settings before submitting an issue."
- type: dropdown
id: linux_distribution
attributes:
label: 🖥️ Which Linux distribution are you using?
options:
-
- Alpine
- Debian 11
- Debian 12
- Debian 13
- Ubuntu 22.04
- Ubuntu 24.04
- Ubuntu 24.10
validations:
required: true
- type: input
id: pve_version
attributes:
label: 📈 Which Proxmox version are you on?
placeholder: "run pveversion in your PVE node console"
validations:
required: true
- type: textarea
id: issue_description
attributes:
label: 📝 Provide a clear and concise description of the issue.
validations:
required: true
- type: textarea
id: steps_to_reproduce
attributes:
label: 🔄 Steps to reproduce the issue.
placeholder: "e.g., Step 1: ..., Step 2: ..."
validations:
required: true
- type: textarea
id: error_output
attributes:
label: ❌ Paste the full error output (if available).
placeholder: "Include any relevant logs or error messages."
validations:
required: true
- type: textarea
id: additional_context
attributes:
label: 🖼️ Additional context (optional).
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
validations:
required: false
-11
View File
@@ -1,11 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 🌟 new Script request
url: https://github.com/community-scripts/ProxmoxVE/discussions/new?category=request-script
about: For feature/script requests, please use the Discussions section.
- name: 🤔 Questions and Help
url: https://github.com/community-scripts/ProxmoxVE/discussions
about: For suggestions or questions, please use the Discussions section.
- name: 💻 Discord
url: https://discord.gg/jsYVk5JBxq
about: Join our Discord server to chat with other users in the Proxmox Helper Scripts community.
@@ -1,33 +0,0 @@
name: "✨ Feature Request"
description: "Suggest a new feature or enhancement. (not for script requests)"
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
# ✨ **Feature Request**
Have an idea for a new feature? Share your thoughts below!
- type: input
id: feature_summary
attributes:
label: "🌟 Briefly describe the feature"
placeholder: "e.g., Add support for XYZ"
validations:
required: true
- type: textarea
id: feature_description
attributes:
label: "📝 Detailed description"
placeholder: "Explain the feature in detail"
validations:
required: true
- type: textarea
id: use_case
attributes:
label: "💡 Why is this useful?"
placeholder: "Describe the benefit of this feature"
validations:
required: true
@@ -1,75 +0,0 @@
name: "🌐 Website Issue Report"
description: Report an issue, an optimization request or an documentation issue specifically related to the website.
labels: "website"
body:
- type: markdown
attributes:
value: |
**IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure.
- Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one.
- If the problem is related to a bug in the website, kindly check for browser compatibility and ensure the issue occurs in multiple browsers before submitting.
- For suggestions, questions, or feature requests, please use the [Discussions section.](https://github.com/community-scripts/ProxmoxVE/discussions)
- type: input
id: guidelines
attributes:
label: Please verify that you have read and understood the guidelines.
placeholder: 'yes'
validations:
required: true
- type: dropdown
id: issue_type
validations:
required: true
attributes:
label: What type of issue is this?
options:
-
- Bug
- Optimization
- Documentation
- Other
- type: textarea
id: bug_description
attributes:
label: A clear and concise description of the issue.
validations:
required: true
- type: dropdown
id: browser
validations:
required: true
attributes:
label: Which browser are you using?
options:
-
- Chrome
- Firefox
- Safari
- Edge
- Other
- type: markdown
attributes:
value: |
**If the issue is browser-related**, please provide information on the version and platform (Windows, MacOS, Linux, etc.).
- type: textarea
id: screenshot
attributes:
label: If relevant, including screenshots or a code block can be helpful in clarifying the issue.
placeholder: "Code blocks begin and conclude by enclosing the code with three backticks (```) above and below it."
validations:
required: false
- type: textarea
id: reproduce
attributes:
label: Please provide detailed steps to reproduce the issue.
placeholder: "First do this, then this ..."
validations:
required: false
-25
View File
@@ -1,25 +0,0 @@
name: "🛠️ Task / General Request"
description: "Request a general task, improvement, or refactor."
labels: ["task"]
body:
- type: markdown
attributes:
value: |
# 🛠️ **Task / General Request**
Request a task that isn't a bug or feature request.
- type: input
id: task_summary
attributes:
label: "📌 Task summary"
placeholder: "e.g., Refactor XYZ"
validations:
required: true
- type: textarea
id: task_details
attributes:
label: "📋 Task details"
placeholder: "Explain what needs to be done"
validations:
required: true
-131
View File
@@ -1,131 +0,0 @@
{
"new script": [
{
"fileStatus": "added",
"includeGlobs": [
"ct/**",
"tools/**",
"install/**",
"misc/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"update script": [
{
"fileStatus": "modified",
"includeGlobs": [
"ct/**",
"tools/**",
"install/**",
"misc/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"delete script": [
{
"fileStatus": "removed",
"includeGlobs": [
"ct/**",
"tools/**",
"install/**",
"misc/**",
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
}
],
"maintenance": [
{
"fileStatus": null,
"includeGlobs": [
"*.md"
],
"excludeGlobs": []
}
],
"core": [
{
"fileStatus": null,
"includeGlobs": [
"misc/*.func",
"misc/create_lxc.sh"
],
"excludeGlobs": [
"misc/api.func"
]
}
],
"website": [
{
"fileStatus": null,
"includeGlobs": [
"frontend/**"
],
"excludeGlobs": [
"frontend/public/json/**"
]
}
],
"api": [
{
"fileStatus": null,
"includeGlobs": [
"api/**",
"misc/api.func"
],
"excludeGlobs": []
}
],
"github": [
{
"fileStatus": null,
"includeGlobs": [
".github/**"
],
"excludeGlobs": []
}
],
"json": [
{
"fileStatus": "modified",
"includeGlobs": [
"frontend/public/json/**"
],
"excludeGlobs": []
}
],
"addon": [
{
"fileStatus": null,
"includeGlobs": [
"tools/addon/**"
],
"excludeGlobs": []
}
],
"pve-tool": [
{
"fileStatus": null,
"includeGlobs": [
"tools/pve/**"
],
"excludeGlobs": []
}
],
"vm": [
{
"fileStatus": null,
"includeGlobs": [
"vm/**"
],
"excludeGlobs": []
}
]
}
-148
View File
@@ -1,148 +0,0 @@
[
{
"title": "🆕 New Scripts",
"labels": [
"new script"
]
},
{
"title": "🚀 Updated Scripts",
"labels": [
"update script"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "🧰 Maintenance",
"labels": [
"maintenance"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "📡 API",
"labels": [
"api"
],
"notes": []
},
{
"title": "💾 Core",
"labels": [
"core"
],
"notes": []
},
{
"title": "📂 Github",
"labels": [
"github"
],
"notes": []
},
{
"title": "📝 Documentation",
"labels": [
"maintenance"
],
"notes": []
},
{
"title": "🔧 Refactor",
"labels": [
"refactor"
],
"notes": []
}
]
},
{
"title": "🌐 Website",
"labels": [
"website"
],
"subCategories": [
{
"title": "🐞 Bug Fixes",
"labels": [
"bugfix"
],
"notes": []
},
{
"title": "✨ New Features",
"labels": [
"feature"
],
"notes": []
},
{
"title": "💥 Breaking Changes",
"labels": [
"breaking change"
],
"notes": []
},
{
"title": "📝 Script Information",
"labels": [
"json"
],
"notes": []
}
]
},
{
"title": "❔ Unlabelled",
"labels": []
}
]
-27
View File
@@ -1,27 +0,0 @@
<!--🛑 New scripts must be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) for testing.
PRs without prior testing will be closed. -->
## ✍️ Description
## 🔗 Related PR / Issue
Link: #
## ✅ Prerequisites (**X** in brackets)
- [ ] **Self-review completed** – Code follows project standards.
- [ ] **Tested thoroughly** – Changes work as expected.
- [ ] **No security risks** – No hardcoded secrets, unnecessary privilege escalations, or permission issues.
---
## 🛠️ Type of Change (**X** in brackets)
- [ ] 🐞 **Bug fix** – Resolves an issue without breaking functionality.
- [ ] ✨ **New feature** – Adds new, non-breaking functionality.
- [ ] 💥 **Breaking change** – Alters existing functionality in a way that may require updates.
- [ ] 🆕 **New script** – A fully functional and tested script or script set.
- [ ] 🌍 **Website update** – Changes to website-related JSON files or metadata.
- [ ] 🔧 **Refactoring / Code Cleanup** – Improves readability or maintainability without changing functionality.
- [ ] 📝 **Documentation update** – Changes to `README`, `AppName.md`, `CONTRIBUTING.md`, or other docs.
@@ -1,68 +0,0 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy as build
ARG TARGETOS
ARG TARGETARCH
ARG DOCKER_VERSION=27.5.1
ARG BUILDX_VERSION=0.20.1
ARG RUNNER_ARCH="x64"
RUN apt update -y && apt install sudo curl unzip -y
WORKDIR /actions-runner
RUN RUNNER_VERSION=$(curl -s https://api.github.com/repos/actions/runner/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
&& curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \
&& tar xzf ./runner.tar.gz \
&& rm runner.tar.gz
RUN RUNNER_CONTAINER_HOOKS_VERSION=$(curl -s https://api.github.com/repos/actions/runner-container-hooks/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
&& curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
&& unzip ./runner-container-hooks.zip -d ./k8s \
&& rm runner-container-hooks.zip
RUN export RUNNER_ARCH=${TARGETARCH} \
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
&& curl -fLo docker.tgz https://download.docker.com/${TARGETOS}/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
&& tar zxvf docker.tgz \
&& rm -rf docker.tgz \
&& mkdir -p /usr/local/lib/docker/cli-plugins \
&& curl -fLo /usr/local/lib/docker/cli-plugins/docker-buildx \
"https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-${TARGETARCH}" \
&& chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy
ENV DEBIAN_FRONTEND=noninteractive
ENV RUNNER_MANUALLY_TRAP_SIG=1
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
ENV ImageOS=ubuntu22
RUN apt update -y \
&& apt install -y --no-install-recommends sudo lsb-release gpg-agent software-properties-common curl jq unzip \
&& rm -rf /var/lib/apt/lists/*
RUN add-apt-repository ppa:git-core/ppa \
&& apt update -y \
&& apt install -y git \
&& rm -rf /var/lib/apt/lists/*
RUN adduser --disabled-password --gecos "" --uid 1001 runner \
&& groupadd docker --gid 123 \
&& usermod -aG sudo runner \
&& usermod -aG docker runner \
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \
&& echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers
# Install own dependencies in final image
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
&& apt-get install -y gh jq git
WORKDIR /home/runner
COPY --chown=runner:docker --from=build /actions-runner .
COPY --from=build /usr/local/lib/docker/cli-plugins/docker-buildx /usr/local/lib/docker/cli-plugins/docker-buildx
RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
USER runner
@@ -1,117 +0,0 @@
name: Auto Update .app-files
on:
push:
branches:
- main
paths:
- "ct/**.sh"
workflow_dispatch:
jobs:
update-app-files:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
# Step 1: Checkout repository
- name: Checkout repository
uses: actions/checkout@v2
# Step 2: Disable file mode changes detection
- name: Disable file mode changes
run: git config core.fileMode false
# Step 3: Set up Git user for committing changes
- name: Set up Git
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Step 4: Install figlet
- name: Install figlet
run: sudo apt-get install -y figlet
# Step 5: Run the updated generate-app-files.sh script
- name: Run generate-app-files.sh
run: |
chmod +x .github/workflows/scripts/generate-app-headers.sh
.github/workflows/scripts/generate-app-headers.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Step 6: Check if there are any changes
- name: Check if there are any changes
run: |
echo "Checking for changes..."
git add -A # Untracked Dateien aufnehmen
git status
if git diff --cached --quiet; then
echo "No changes detected."
echo "changed=false" >> "$GITHUB_ENV"
else
echo "Changes detected:"
git diff --stat --cached
echo "changed=true" >> "$GITHUB_ENV"
fi
# Step 7: Commit and create PR if changes exist
- name: Commit and create PR if changes exist
if: env.changed == 'true'
run: |
git commit -m "Update .app files"
git checkout -b pr-update-app-files
git push origin pr-update-app-files --force
gh pr create --title "[core] update .app files" \
--body "This PR is auto-generated by a GitHub Action to update the .app files." \
--head pr-update-app-files \
--base main \
--label "automated pr"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "pr-update-app-files" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
run: |
git config --global user.name "github-actions-automege[bot]"
git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
# Step 8: Output success message when no changes
- name: No changes detected
if: env.changed == 'false'
run: echo "No changes to commit. Workflow completed successfully."
-114
View File
@@ -1,114 +0,0 @@
name: Auto Label Pull Requests
on:
workflow_dispatch:
pull_request_target:
branches: ["main"]
types: [opened, synchronize, reopened, edited]
jobs:
autolabeler:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
permissions:
pull-requests: write
env:
CONFIG_PATH: .github/autolabeler-config.json
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: npm install minimatch
- name: Label PR based on file changes and PR template
uses: actions/github-script@v7
with:
script: |
const fs = require('fs').promises;
const path = require('path');
const { minimatch } = require('minimatch');
const configPath = path.resolve(process.env.CONFIG_PATH);
const fileContent = await fs.readFile(configPath, 'utf-8');
const autolabelerConfig = JSON.parse(fileContent);
const prNumber = context.payload.pull_request.number;
const prBody = context.payload.pull_request.body || "";
let labelsToAdd = new Set();
const prListFilesResponse = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
});
const prFiles = prListFilesResponse.data;
for (const [label, rules] of Object.entries(autolabelerConfig)) {
const shouldAddLabel = prFiles.some((prFile) => {
return rules.some((rule) => {
const isFileStatusMatch = rule.fileStatus ? rule.fileStatus === prFile.status : true;
const isIncludeGlobMatch = rule.includeGlobs.some((glob) => minimatch(prFile.filename, glob));
const isExcludeGlobMatch = rule.excludeGlobs.some((glob) => minimatch(prFile.filename, glob));
return isFileStatusMatch && isIncludeGlobMatch && !isExcludeGlobMatch;
});
});
if (shouldAddLabel) {
labelsToAdd.add(label);
if (label === "update script") {
for (const prFile of prFiles) {
const filename = prFile.filename;
if (filename.startsWith("vm/")) labelsToAdd.add("vm");
if (filename.startsWith("tools/addon/")) labelsToAdd.add("addon");
if (filename.startsWith("tools/pve/")) labelsToAdd.add("pve-tool");
}
}
}
}
if (labelsToAdd.size < 2) {
const templateLabelMappings = {
"🐞 **Bug fix**": "bugfix",
"✨ **New feature**": "feature",
"💥 **Breaking change**": "breaking change",
"🆕 **New script**": "new script",
"🌍 **Website update**": "website", // handled special
"🔧 **Refactoring / Code Cleanup**": "refactor",
"📝 **Documentation update**": "documentation" // mapped to maintenance
};
for (const [checkbox, label] of Object.entries(templateLabelMappings)) {
const escapedCheckbox = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
const regex = new RegExp(`- \\[(x|X)\\]\\s*${escapedCheckbox}`, "i");
if (regex.test(prBody)) {
if (label === "website") {
const hasJson = prFiles.some((f) => f.filename.startsWith("frontend/public/json/"));
const hasUpdateScript = labelsToAdd.has("update script");
const hasContentLabel = ["bugfix", "feature", "refactor"].some((l) => labelsToAdd.has(l));
if (!(hasUpdateScript && hasContentLabel)) {
labelsToAdd.add(hasJson ? "json" : "website");
}
} else if (label === "documentation") {
labelsToAdd.add("maintenance");
} else {
labelsToAdd.add(label);
}
}
}
}
if (labelsToAdd.size === 0) {
labelsToAdd.add("needs triage");
}
if (labelsToAdd.size > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: Array.from(labelsToAdd),
});
}
-285
View File
@@ -1,285 +0,0 @@
name: Create Changelog Pull Request
on:
push:
branches: ["main"]
workflow_dispatch:
jobs:
update-changelog-pull-request:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
env:
CONFIG_PATH: .github/changelog-pr-config.json
BRANCH_NAME: github-action-update-changelog
AUTOMATED_PR_LABEL: "automated pr"
permissions:
contents: write
pull-requests: write
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest dates in changelog
run: |
DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}')
LATEST_DATE=$(echo "$DATES" | sed -n '1p')
SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p')
TODAY=$(date -u +%Y-%m-%d)
echo "TODAY=$TODAY" >> $GITHUB_ENV
if [[ "$LATEST_DATE" == "$TODAY" ]]; then
echo "LATEST_DATE=$SECOND_LATEST_DATE" >> $GITHUB_ENV
else
echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV
fi
- name: Get categorized pull requests
id: get-categorized-prs
uses: actions/github-script@v7
with:
script: |
async function main() {
const fs = require('fs').promises;
const path = require('path');
const configPath = path.resolve(process.env.CONFIG_PATH);
const fileContent = await fs.readFile(configPath, 'utf-8');
const changelogConfig = JSON.parse(fileContent);
const categorizedPRs = changelogConfig.map(obj => ({
...obj,
notes: [],
subCategories: obj.subCategories ?? (
obj.labels.includes("update script") ? [
{ title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
{ title: "✨ New Features", labels: ["feature"], notes: [] },
{ title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
{ title: "🔧 Refactor", labels: ["refactor"], notes: [] },
] :
obj.labels.includes("maintenance") ? [
{ title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
{ title: "✨ New Features", labels: ["feature"], notes: [] },
{ title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
{ title: "📡 API", labels: ["api"], notes: [] },
{ title: "Github", labels: ["github"], notes: [] },
{ title: "📝 Documentation", labels: ["maintenance"], notes: [] },
{ title: "🔧 Refactor", labels: ["refactor"], notes: [] }
] :
obj.labels.includes("website") ? [
{ title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
{ title: "✨ New Features", labels: ["feature"], notes: [] },
{ title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
{ title: "Script Information", labels: ["json"], notes: [] }
] : []
)
}));
const latestDateInChangelog = new Date(process.env.LATEST_DATE);
latestDateInChangelog.setUTCHours(23, 59, 59, 999);
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: "ProxmoxVE",
base: "main",
state: "closed",
sort: "updated",
direction: "desc",
per_page: 100,
});
const filteredPRs = pulls.filter(pr =>
pr.merged_at &&
new Date(pr.merged_at) > latestDateInChangelog &&
!pr.labels.some(label =>
["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())
)
);
for (const pr of filteredPRs) {
const prLabels = pr.labels.map(label => label.name.toLowerCase());
if (pr.user.login.includes("push-app-to-main[bot]")) {
const scriptName = pr.title;
try {
const { data: relatedIssues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: "ProxmoxVED",
state: "all",
labels: ["Started Migration To ProxmoxVE"]
});
const matchingIssue = relatedIssues.find(issue =>
issue.title.toLowerCase().includes(scriptName.toLowerCase())
);
if (matchingIssue) {
const issueAuthor = matchingIssue.user.login;
const issueAuthorUrl = `https://github.com/${issueAuthor}`;
prNote = `- ${pr.title} [@${issueAuthor}](${issueAuthorUrl}) ([#${pr.number}](${pr.html_url}))`;
}
else {
prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`;
}
} catch (error) {
console.error(`Error fetching related issues: ${error}`);
prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`;
}
}else{
prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`;
}
if (prLabels.includes("new script")) {
const newScriptCategory = categorizedPRs.find(category =>
category.title === "New Scripts" || category.labels.includes("new script"));
if (newScriptCategory) {
newScriptCategory.notes.push(prNote);
}
} else {
let categorized = false;
const priorityCategories = categorizedPRs.slice();
for (const category of priorityCategories) {
if (categorized) break;
if (category.labels.some(label => prLabels.includes(label))) {
if (category.subCategories && category.subCategories.length > 0) {
const subCategory = category.subCategories.find(sub =>
sub.labels.some(label => prLabels.includes(label))
);
if (subCategory) {
subCategory.notes.push(prNote);
} else {
category.notes.push(prNote);
}
} else {
category.notes.push(prNote);
}
categorized = true;
}
}
}
}
return categorizedPRs;
}
return await main();
- name: Update CHANGELOG.md
uses: actions/github-script@v7
with:
script: |
const fs = require('fs').promises;
const path = require('path');
const today = process.env.TODAY;
const latestDateInChangelog = process.env.LATEST_DATE;
const changelogPath = path.resolve('CHANGELOG.md');
const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }};
console.log(JSON.stringify(categorizedPRs, null, 2));
let newReleaseNotes = `## ${today}\n\n`;
for (const { title, notes, subCategories } of categorizedPRs) {
const hasSubcategories = subCategories && subCategories.length > 0;
const hasMainNotes = notes.length > 0;
const hasSubNotes = hasSubcategories && subCategories.some(sub => sub.notes && sub.notes.length > 0);
if (hasMainNotes || hasSubNotes) {
newReleaseNotes += `### ${title}\n\n`;
}
if (hasMainNotes) {
newReleaseNotes += ` ${notes.join("\n")}\n\n`;
}
if (hasSubcategories) {
for (const { title: subTitle, notes: subNotes } of subCategories) {
if (subNotes && subNotes.length > 0) {
newReleaseNotes += ` - #### ${subTitle}\n\n`;
newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`;
}
}
}
}
const changelogContent = await fs.readFile(changelogPath, 'utf-8');
const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`);
const regex = changelogIncludesTodaysReleaseNotes
? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs")
: new RegExp(`(?=## ${latestDateInChangelog})`, "gs");
const newChangelogContent = changelogContent.replace(regex, newReleaseNotes);
await fs.writeFile(changelogPath, newChangelogContent);
- name: Check for changes
id: verify-diff
run: |
git diff --quiet . || echo "changed=true" >> $GITHUB_ENV
- name: Commit and push changes
if: env.changed == 'true'
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add CHANGELOG.md
git commit -m "Update CHANGELOG.md"
git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME
git push origin $BRANCH_NAME --force
- name: Create pull request if not exists
if: env.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -z "$PR_EXISTS" ]; then
gh pr create --title "[Github Action] Update CHANGELOG.md" \
--body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \
--head $BRANCH_NAME \
--base main \
--label "$AUTOMATED_PR_LABEL"
fi
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
run: |
git config --global user.name "github-actions-automege[bot]"
git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
-164
View File
@@ -1,164 +0,0 @@
name: Close Discussion on PR Merge
on:
push:
branches:
- main
permissions:
contents: read
discussions: write
jobs:
close-discussion:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set Up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Dependencies
run: npm install zx @octokit/graphql
- name: Close Discussion
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
npx zx << 'EOF'
import { graphql } from "@octokit/graphql";
(async function () {
try {
const token = process.env.GITHUB_TOKEN;
const commitSha = process.env.GITHUB_SHA;
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
if (!token || !commitSha || !owner || !repo) {
console.log("Missing required environment variables.");
process.exit(1);
}
const graphqlWithAuth = graphql.defaults({
headers: { authorization: `Bearer ${token}` },
});
// Find PR from commit SHA
const searchQuery = `
query($owner: String!, $repo: String!, $sha: GitObjectID!) {
repository(owner: $owner, name: $repo) {
object(oid: $sha) {
... on Commit {
associatedPullRequests(first: 1) {
nodes {
number
body
}
}
}
}
}
}
`;
const prResult = await graphqlWithAuth(searchQuery, {
owner,
repo,
sha: commitSha,
});
const pr = prResult.repository.object.associatedPullRequests.nodes[0];
if (!pr) {
console.log("No PR found for this commit.");
return;
}
const prNumber = pr.number;
const prBody = pr.body;
const match = prBody.match(/#(\d+)/);
if (!match) {
console.log("No discussion ID found in PR body.");
return;
}
const discussionNumber = match[1];
console.log(`Extracted Discussion Number: ${discussionNumber}`);
// Fetch GraphQL discussion ID
const discussionQuery = `
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
discussion(number: $number) {
id
}
}
}
`;
//
try {
const discussionResponse = await graphqlWithAuth(discussionQuery, {
owner,
repo,
number: parseInt(discussionNumber, 10),
});
const discussionQLId = discussionResponse.repository.discussion.id;
if (!discussionQLId) {
console.log("Failed to fetch discussion GraphQL ID.");
return;
}
} catch (error) {
console.error("Discussion not found or error occurred while fetching discussion:", error);
return;
}
// Post comment
const commentMutation = `
mutation($discussionId: ID!, $body: String!) {
addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
comment { id body }
}
}
`;
const commentResponse = await graphqlWithAuth(commentMutation, {
discussionId: discussionQLId,
body: `Merged with PR #${prNumber}`,
});
const commentId = commentResponse.addDiscussionComment.comment.id;
if (!commentId) {
console.log("Failed to post the comment.");
return;
}
console.log(`Comment Posted Successfully! Comment ID: ${commentId}`);
// Mark comment as answer
const markAnswerMutation = `
mutation($id: ID!) {
markDiscussionCommentAsAnswer(input: { id: $id }) {
discussion { id title }
}
}
`;
await graphqlWithAuth(markAnswerMutation, { id: commentId });
console.log("Comment marked as answer successfully!");
} catch (error) {
console.error("Error:", error);
process.exit(1);
}
})();
EOF
-52
View File
@@ -1,52 +0,0 @@
name: Auto-Close tteck Issues
on:
issues:
types: [opened]
jobs:
close_tteck_issues:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Auto-close if tteck script detected
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const content = `${issue.title}\n${issue.body}`;
const issueNumber = issue.number;
// Check for tteck script mention
if (content.includes("tteck") || content.includes("tteck/Proxmox")) {
const message = `Hello, it looks like you are referencing the **old tteck repo**.
This repository is no longer used for active scripts.
**Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com)
Also make sure your Bash command starts with:
\`\`\`bash
bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/...)
\`\`\`
This issue is being closed automatically.`;
await github.rest.issues.createComment({
...context.repo,
issue_number: issueNumber,
body: message
});
// Optionally apply a label like "not planned"
await github.rest.issues.addLabels({
...context.repo,
issue_number: issueNumber,
labels: ["not planned"]
});
// Close the issue
await github.rest.issues.update({
...context.repo,
issue_number: issueNumber,
state: "closed"
});
}
-65
View File
@@ -1,65 +0,0 @@
name: Close Matching Issue on PR Merge
on:
pull_request:
types:
- closed
jobs:
close_issue:
if: github.event.pull_request.merged == true && github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout target repo (main)
uses: actions/checkout@v4
with:
repository: community-scripts/ProxmoxVE
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract and Process PR Title
id: extract_title
run: |
title=$(echo "${{ github.event.pull_request.title }}" | sed 's/^New Script://g' | tr '[:upper:]' '[:lower:]' | sed 's/ //g' | sed 's/-//g')
echo "Processed Title: $title"
echo "title=$title" >> $GITHUB_ENV
- name: Search for Issues with Similar Titles
id: find_issue
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
issues=$(gh issue list --repo community-scripts/ProxmoxVED --json number,title --jq '.[] | {number, title}')
best_match_score=0
best_match_number=0
for issue in $(echo "$issues" | jq -r '. | @base64'); do
_jq() {
echo ${issue} | base64 --decode | jq -r ${1}
}
issue_title=$(_jq '.title' | tr '[:upper:]' '[:lower:]' | sed 's/ //g' | sed 's/-//g')
issue_number=$(_jq '.number')
match_score=$(echo "$title" | grep -o "$issue_title" | wc -l)
if [ "$match_score" -gt "$best_match_score" ]; then
best_match_score=$match_score
best_match_number=$issue_number
fi
done
if [ "$best_match_number" != "0" ]; then
echo "issue_number=$best_match_number" >> $GITHUB_ENV
else
echo "No matching issue found."
exit 0
fi
- name: Comment on the Best-Matching Issue and Close It
if: env.issue_number != ''
env:
GH_TOKEN: ${{ secrets.PAT_MICHEL }}
run: |
gh issue comment $issue_number --repo community-scripts/ProxmoxVED --body "Merged with #${{ github.event.pull_request.number }} in ProxmoxVE"
gh issue close $issue_number --repo community-scripts/ProxmoxVED
@@ -1,59 +0,0 @@
name: Auto-Close Wrong Template Issues
on:
issues:
types: [opened]
jobs:
close_tteck_issues:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Auto-close if wrong Template issue detected
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const content = `${issue.title}\n${issue.body}`;
const issueNumber = issue.number;
// Regex patterns (case-insensitive, flexible versioning)
const patterns = [
/Template\s+debian-13-standard_[\d.]+-[\d]+_amd64\.tar\.zst\s*\[(online|local)\]/i,
/Template\s+debian-13-standard_[\d.]+-[\d]+_amd64\.tar\.zst\s+is\s+missing\s+or\s+corrupted/i,
/Container\s+creation\s+failed\.?\s+Checking\s+if\s+template\s+is\s+corrupted\s+or\s+incomplete/i,
/Template\s+is\s+valid,\s+but\s+container\s+creation\s+still\s+failed/i,
/exit\s+code\s+0:\s+while\s+executing\s+command\s+bash\s+-c\s+"\$?\(curl\s+-fsSL\s+https:\/\/raw\.githubusercontent\.com\/[\w/-]+\/create_lxc\.sh\)"/i
];
const matched = patterns.some((regex) => regex.test(content));
if (matched) {
const message = `👋 Hello!
It looks like you are referencing a **container creation issue with a Debian 13 template** (e.g. \`debian-13-standard_13.x-x_amd64.tar.zst\`).
We receive many similar reports about this, and it’s not related to the scripts themselves but to **a Proxmox base template bug**.
Please refer to [discussion #8126](https://github.com/community-scripts/ProxmoxVE/discussions/8126) for details.
If your issue persists after following the guidance there, feel free to reopen this issue.
_This issue was automatically closed by a bot._`;
await github.rest.issues.createComment({
...context.repo,
issue_number: issueNumber,
body: message
});
await github.rest.issues.addLabels({
...context.repo,
issue_number: issueNumber,
labels: ["not planned"]
});
await github.rest.issues.update({
...context.repo,
issue_number: issueNumber,
state: "closed"
});
}
-126
View File
@@ -1,126 +0,0 @@
name: Crawl Versions from newreleases.io
on:
workflow_dispatch:
schedule:
# Runs at 12:00 AM and 12:00 PM UTC
- cron: "0 0,12 * * *"
permissions:
contents: write
pull-requests: write
jobs:
crawl-versions:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
repository: community-scripts/ProxmoxVE
ref: main
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Crawl from newreleases.io
env:
token: ${{ secrets.NEWRELEASES_TOKEN }}
run: |
page=1
projects_file="project_json"
output_file="frontend/public/json/versions.json"
echo "[]" > $output_file
while true; do
echo "Start loop on page: $page"
projects=$(curl -s -H "X-Key: $token" "https://api.newreleases.io/v1/projects?page=$page")
total_pages=$(echo "$projects" | jq -r '.total_pages')
if [ -z "$total_pages" ] || [ "$total_pages" -eq 0 ]; then
echo "No pages available. Exiting."
exit 1
fi
if [ $page == $total_pages ]; then
break
fi
if [ -z "$projects" ] || ! echo "$projects" | jq -e '.projects' > /dev/null; then
echo "No more projects or invalid response. Exiting."
break
fi
echo "$projects" > "$projects_file"
jq -r '.projects[] | "\(.id) \(.name)"' "$projects_file" | while read -r id name; do
version=$(curl -s -H "X-Key: $token" "https://api.newreleases.io/v1/projects/$id/latest-release")
version_data=$(echo "$version" | jq -r '.version // empty')
date=$(echo "$version" | jq -r '.date // empty')
if [ -n "$version_data" ]; then
jq --arg name "$name" --arg version "$version_data" --arg date "$date" \
'. += [{"name": $name, "version": $version, "date": $date}]' "$output_file" > "$output_file.tmp" && mv "$output_file.tmp" "$output_file"
fi
done
((page++))
done
- name: Commit JSON
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "GitHub Actions[bot]"
git checkout -b update_versions || git checkout update_versions
git add frontend/public/json/versions.json
if git diff --cached --quiet; then
echo "No changes detected."
echo "changed=false" >> "$GITHUB_ENV"
exit 0
else
echo "Changes detected:"
git diff --stat --cached
echo "changed=true" >> "$GITHUB_ENV"
fi
git commit -m "Update versions.json"
git push origin update_versions --force
gh pr create --title "[Github Action] Update versions.json" --body "Update versions.json, crawled from newreleases.io" --base main --head update_versions --label "automated pr"
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.PAT_AUTOMERGE }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
- name: Re-approve pull request after update
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
@@ -1,38 +0,0 @@
name: Build and Publish Docker Image
on:
push:
branches:
- main
paths:
- '.github/runner/docker/**'
schedule:
- cron: '0 0 * * *'
jobs:
build:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest #To ensure it always builds we use the github runner with all the right tooling
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Log in to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image
run: |
repo_name=${{ github.repository }} # Get repository name
repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
docker build -t ghcr.io/$repo_name_lower/gh-runner-self:latest -f .github/runner/docker/gh-runner-self.dockerfile .
- name: Push Docker image to GHCR
run: |
repo_name=${{ github.repository }} # Get repository name
repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
docker push ghcr.io/$repo_name_lower/gh-runner-self:latest
-29
View File
@@ -1,29 +0,0 @@
name: Delete JSON date PR Branch
on:
pull_request:
types: [closed]
branches:
- main
jobs:
delete_branch:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v3
- name: Delete PR Update Branch
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'pr-update-json-')
run: |
PR_BRANCH="${{ github.event.pull_request.head.ref }}"
echo "Deleting branch $PR_BRANCH..."
# Avoid deleting the default branch (e.g., main)
if [[ "$PR_BRANCH" != "main" ]]; then
git push origin --delete "$PR_BRANCH"
else
echo "Skipping deletion of the main branch"
fi
-147
View File
@@ -1,147 +0,0 @@
# Based on https://github.com/actions/starter-workflows/blob/main/pages/nextjs.yml
name: Frontend CI/CD
on:
push:
branches: ["main"]
paths:
- frontend/**
pull_request:
branches: ["main"]
types: [opened, synchronize, reopened, edited]
paths:
- frontend/**
workflow_dispatch:
permissions:
contents: read
concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: false
jobs:
test-json-files:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Test JSON files
run: |
python3 << 'EOF'
import json
import glob
import os
import sys
def test_json_files():
# Change to the correct directory
json_dir = "public/json"
if not os.path.exists(json_dir):
print(f"❌ Directory not found: {json_dir}")
return False
# Find all JSON files
pattern = os.path.join(json_dir, "*.json")
json_files = glob.glob(pattern)
if not json_files:
print(f"⚠️ No JSON files found in {json_dir}")
return True
print(f"Testing {len(json_files)} JSON files for valid syntax...")
invalid_files = []
for file_path in json_files:
try:
with open(file_path, 'r', encoding='utf-8') as f:
json.load(f)
print(f"✅ Valid JSON: {file_path}")
except json.JSONDecodeError as e:
print(f"❌ Invalid JSON syntax in: {file_path}")
print(f" Error: {e}")
invalid_files.append(file_path)
except Exception as e:
print(f"⚠️ Error reading: {file_path}")
print(f" Error: {e}")
invalid_files.append(file_path)
print("\n=== JSON Validation Summary ===")
print(f"Total files tested: {len(json_files)}")
print(f"Valid files: {len(json_files) - len(invalid_files)}")
print(f"Invalid files: {len(invalid_files)}")
if invalid_files:
print("\n❌ Found invalid JSON file(s):")
for file_path in invalid_files:
print(f" - {file_path}")
return False
else:
print("\n✅ All JSON files have valid syntax!")
return True
if __name__ == "__main__":
success = test_json_files()
sys.exit(0 if success else 1)
EOF
build:
if: github.repository == 'community-scripts/ProxmoxVE'
needs: test-json-files
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Configure Next.js for pages
uses: actions/configure-pages@v5
with:
static_site_generator: next
- name: Build with Next.js
run: bun run build
- name: Upload artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: frontend/out
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' && github.repository == 'community-scripts/ProxmoxVE'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
-47
View File
@@ -1,47 +0,0 @@
name: Create Daily Release
on:
schedule:
- cron: '1 0 * * *' # Runs daily at 00:01 UTC
workflow_dispatch:
jobs:
create-daily-release:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clean CHANGELOG (remove HTML header)
run: sed -n '/^## /,$p' CHANGELOG.md > changelog_cleaned.md
- name: Extract relevant changelog section
run: |
YESTERDAY=$(date -u --date="yesterday" +%Y-%m-%d)
echo "Checking for changes on: $YESTERDAY"
# Extract the section from "## $YESTERDAY" until the next "## YYYY-MM-DD"
sed -n "/^## $YESTERDAY/,/^## [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/p" changelog_cleaned.md | head -n -1 > changelog_tmp_full.md
# Truncate the extracted section to 5000 characters
head -c 5000 changelog_tmp_full.md > changelog_tmp.md
echo "=== Extracted Changelog ==="
cat changelog_tmp.md
echo "==========================="
# Abort if no content was found
if [ ! -s changelog_tmp.md ]; then
echo "No changes found for $YESTERDAY, skipping release."
exit 0
fi
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
YESTERDAY=$(date -u --date="yesterday" +%Y-%m-%d)
gh release create "$YESTERDAY" -t "$YESTERDAY" -F changelog_tmp.md
-48
View File
@@ -1,48 +0,0 @@
name: Sync to Gitea
on:
push:
branches:
- main
jobs:
sync:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout source repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Change all links to git.community-scripts.org
run: |
echo "Searching for files containing raw.githubusercontent.com URLs..."
# Find all files containing GitHub raw URLs, excluding certain directories
files_with_github_urls=$(grep -r "https://raw.githubusercontent.com/community-scripts/ProxmoxVE" . --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=.github/workflows --files-with-matches || true)
if [ -n "$files_with_github_urls" ]; then
echo "$files_with_github_urls" | while read file; do
if [ -f "$file" ]; then
sed -i 's|https://raw\.githubusercontent\.com/community-scripts/ProxmoxVE/|https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/|g' "$file"
fi
done
else
echo "No files found containing GitHub raw URLs"
fi
- name: Push to Gitea
run: |
git config --global user.name "Push From Github"
git config --global user.email "actions@github.com"
git remote add gitea https://$GITEA_USER:$GITEA_TOKEN@git.community-scripts.org/community-scripts/ProxmoxVE.git
git add .
git commit -m "Sync to Gitea"
git push gitea --all --force
env:
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
-175
View File
@@ -1,175 +0,0 @@
name: Run Scripts on PVE Node for testing
permissions:
pull-requests: write
on:
pull_request_target:
branches:
- main
paths:
- "install/**.sh"
- "ct/**.sh"
jobs:
run-install-script:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: pvenode
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Add Git safe directory
run: |
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Get Changed Files
run: |
CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
echo "Changed files: $CHANGED_FILES"
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get scripts
id: check-install-script
run: |
ALL_FILES=()
ADDED_FILES=()
for FILE in ${{ env.SCRIPT }}; do
if [[ $FILE =~ ^install/.*-install\.sh$ ]] || [[ $FILE =~ ^ct/.*\.sh$ ]]; then
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
if [[ ! " ${ADDED_FILES[@]} " =~ " $STRIPPED_NAME " ]]; then
ALL_FILES+=("$FILE")
ADDED_FILES+=("$STRIPPED_NAME") # Mark this base file as added (without the path)
fi
fi
done
ALL_FILES=$(echo "${ALL_FILES[@]}" | xargs)
echo "$ALL_FILES"
echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV
- name: Run scripts
id: run-install
continue-on-error: true
run: |
set +e
#run for each files in /ct
for FILE in ${{ env.ALL_FILES }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
echo "Running Test for: $STRIPPED_NAME"
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "$FILE"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
CT_SCRIPT="ct/$STRIPPED_NAME.sh"
if [[ ! -f $CT_SCRIPT ]]; then
echo "No CT script found for $STRIPPED_NAME"
ERROR_MSG="No CT script found for $FILE"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
continue
fi
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "install/$STRIPPED_NAME-install.sh"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
echo "Found CT script for $STRIPPED_NAME"
chmod +x "$CT_SCRIPT"
RUNNING_FILE=$CT_SCRIPT
elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
if [[ ! -f $INSTALL_SCRIPT ]]; then
echo "No install script found for $STRIPPED_NAME"
ERROR_MSG="No install script found for $FILE"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
continue
fi
echo "Found install script for $STRIPPED_NAME"
chmod +x "$INSTALL_SCRIPT"
RUNNING_FILE=$FILE
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "ct/$STRIPPED_NAME.sh"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
fi
git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
git fetch community-scripts
rm -f .github/workflows/scripts/app-test/pr-build.func || true
rm -f .github/workflows/scripts/app-test/pr-install.func || true
rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
chmod +x $RUNNING_FILE
chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
chmod +x .github/workflows/scripts/app-test/pr-install.func
chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
chmod +x .github/workflows/scripts/app-test/pr-build.func
sed -i 's|source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
echo "Executing $RUNNING_FILE"
ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
echo "Finished running $FILE"
if [ -n "$ERROR_MSG" ]; then
echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
fi
done
set -e # Restore exit-on-error
- name: Cleanup PVE Node
run: |
containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}' | awk '{print $1}')
for container_id in $containers; do
status=$(pct status $container_id | awk '{print $2}')
if [[ $status == "running" ]]; then
pct stop $container_id
pct destroy $container_id
fi
done
- name: Post error comments
run: |
ERROR="false"
SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 255:"
# Get all existing comments on the PR
EXISTING_COMMENTS=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '.comments[].body')
for FILE in ${{ env.ALL_FILES }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
if [[ ! -f result_$STRIPPED_NAME.log ]]; then
continue
fi
ERROR_MSG=$(cat result_$STRIPPED_NAME.log)
if [ -n "$ERROR_MSG" ]; then
CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||")
COMMENT_BODY=":warning: The script _**$FILE**_ failed with the following message: <br> <div><strong>${CLEANED_ERROR_MSG}</strong></div>"
# Check if the comment already exists
if echo "$EXISTING_COMMENTS" | grep -qF "$COMMENT_BODY"; then
echo "Skipping duplicate comment for $FILE"
else
echo "Posting error message for $FILE"
gh pr comment ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--body "$COMMENT_BODY"
ERROR="true"
fi
fi
done
echo "ERROR=$ERROR" >> $GITHUB_ENV
-243
View File
@@ -1,243 +0,0 @@
name: Script Format Check
permissions:
pull-requests: write
on:
pull_request_target:
branches:
- main
paths:
- "install/*.sh"
- "ct/*.sh"
jobs:
run-install-script:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: pvenode
steps:
- name: Checkout PR branch (supports forks)
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Add Git safe directory
run: |
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Get Changed Files
run: |
CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
echo "Changed files: $CHANGED_FILES"
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check scripts
id: run-install
continue-on-error: true
run: |
for FILE in ${{ env.SCRIPT }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
echo "Running Test for: $STRIPPED_NAME"
FILE_STRIPPED="${FILE##*/}"
LOG_FILE="result_$FILE_STRIPPED.log"
if [[ $FILE =~ ^ct/.*\.sh$ ]]; then
FIRST_LINE=$(sed -n '1p' "$FILE")
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
SECOND_LINE=$(sed -n '2p' "$FILE")
[[ "$SECOND_LINE" != "source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" ]] &&
echo "Line 2 was $SECOND_LINE | Should be: source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" >> "$LOG_FILE"
THIRD_LINE=$(sed -n '3p' "$FILE")
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
fi
EXPECTED_AUTHOR="# Author:"
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
EXPECTED_SOURCE="# Source:"
EXPECTED_EMPTY=""
for i in {4..7}; do
LINE=$(sed -n "${i}p" "$FILE")
case $i in
4)
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
;;
5)
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
;;
6)
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
;;
7)
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
;;
esac
done
EXPECTED_PREFIXES=(
"APP="
"var_tags="
"var_cpu=" # Must be a number
"var_ram=" # Must be a number
"var_disk=" # Must be a number
"var_os=" # Must be debian, alpine, or ubuntu
"var_version="
"var_unprivileged=" # Must be 0 or 1
)
for i in {8..15}; do
LINE=$(sed -n "${i}p" "$FILE")
INDEX=$((i - 8))
case $INDEX in
2|3|4) # var_cpu, var_ram, var_disk (must be numbers)
if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}<NUMBER>'" >> "$LOG_FILE"
fi
;;
5) # var_os (must be debian, alpine, or ubuntu)
if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE"
fi
;;
7) # var_unprivileged (must be 0 or 1)
if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE"
fi
;;
*) # Other lines (must start with expected prefix)
if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
fi
;;
esac
done
for i in {16..20}; do
LINE=$(sed -n "${i}p" "$FILE")
EXPECTED=(
"header_info \"$APP\""
"variables"
"color"
"catch_errors"
"function update_script() {"
)
[[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE"
done
cat "$LOG_FILE"
elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
FIRST_LINE=$(sed -n '1p' "$FILE")
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
SECOND_LINE=$(sed -n '2p' "$FILE")
[[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE"
THIRD_LINE=$(sed -n '3p' "$FILE")
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
fi
EXPECTED_AUTHOR="# Author:"
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
EXPECTED_SOURCE="# Source:"
EXPECTED_EMPTY=""
for i in {4..7}; do
LINE=$(sed -n "${i}p" "$FILE")
case $i in
4)
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
;;
5)
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
;;
6)
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
;;
7)
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
;;
esac
done
[[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE"
for i in {9..14}; do
LINE=$(sed -n "${i}p" "$FILE")
EXPECTED=(
"color"
"verb_ip6"
"catch_errors"
"setting_up_container"
"network_check"
"update_os"
)
[[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE"
done
[[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE"
[[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE"
LAST_3_LINES=$(tail -n 3 "$FILE")
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE"
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE"
[[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE"
cat "$LOG_FILE"
fi
done
- name: Post error comments
run: |
ERROR="false"
for FILE in ${{ env.SCRIPT }}; do
FILE_STRIPPED="${FILE##*/}"
LOG_FILE="result_$FILE_STRIPPED.log"
echo $LOG_FILE
if [[ ! -f $LOG_FILE ]]; then
continue
fi
ERROR_MSG=$(cat $LOG_FILE)
if [ -n "$ERROR_MSG" ]; then
echo "Posting error message for $FILE"
echo ${ERROR_MSG}
gh pr comment ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--body ":warning: The script _**$FILE**_ has the following formatting errors: <br> <div><strong>${ERROR_MSG}</strong></div>"
ERROR="true"
fi
done
echo "ERROR=$ERROR" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail if error
if: ${{ env.ERROR == 'true' }}
run: exit 1
@@ -1,85 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local line_number="$1"
local command="$2"
SCRIPT_NAME=$(basename "$0")
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
echo -e "\n$error_message"
exit 0
}
verb_ip6() {
STD=""
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
RETRY_NUM=10
RETRY_EVERY=3
i=$RETRY_NUM
setting_up_container() {
while [ $i -gt 0 ]; do
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then
break
fi
echo 1>&2 -en "No Network! "
sleep $RETRY_EVERY
i=$((i - 1))
done
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
echo 1>&2 -e "\n No Network After $RETRY_NUM Tries"
echo -e "Check Network Settings"
exit 1
fi
msg_ok "Set up Container OS"
msg_ok "Network Connected: $(hostname -i)"
}
network_check() {
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
set -e
}
update_os() {
msg_info "Updating Container OS"
$STD apk -U upgrade
msg_ok "Updated Container OS"
}
motd_ssh() {
return
}
customize() {
return
}
@@ -1,260 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
variables() {
NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
}
NEXTID=$(pvesh get /cluster/nextid)
timezone=$(cat /etc/timezone)
header_info() {
return
}
base_settings() {
# Default Settings
CT_TYPE="1"
DISK_SIZE="4"
CORE_COUNT="1"
RAM_SIZE="1024"
VERBOSE="no"
PW=""
CT_ID=$NEXTID
HN=$NSAPP
BRG="vmbr0"
NET="dhcp"
GATE=""
APT_CACHER=""
APT_CACHER_IP=""
DISABLEIP6="no"
MTU=""
SD=""
NS=""
MAC=""
VLAN=""
SSH="no"
SSH_AUTHORIZED_KEY=""
TAGS="community-script;"
# Override default settings with variables from ct script
CT_TYPE=${var_unprivileged:-$CT_TYPE}
DISK_SIZE=${var_disk:-$DISK_SIZE}
CORE_COUNT=${var_cpu:-$CORE_COUNT}
RAM_SIZE=${var_ram:-$RAM_SIZE}
VERB=${var_verbose:-$VERBOSE}
TAGS="${TAGS}${var_tags:-}"
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
if [ -z "$var_os" ]; then
var_os="debian"
fi
if [ -z "$var_version" ]; then
var_version="12"
fi
}
color() {
# Colors
YW=$(echo "\033[33m")
YWB=$(echo "\033[93m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
# Formatting
CL=$(echo "\033[m")
UL=$(echo "\033[4m")
BOLD=$(echo "\033[1m")
BFR="\\r\\033[K"
HOLD=" "
TAB=" "
# Icons
CM="${TAB}✔️${TAB}${CL}"
CROSS="${TAB}✖️${TAB}${CL}"
INFO="${TAB}💡${TAB}${CL}"
OS="${TAB}🖥️${TAB}${CL}"
OSVERSION="${TAB}🌟${TAB}${CL}"
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
DISKSIZE="${TAB}💾${TAB}${CL}"
CPUCORE="${TAB}🧠${TAB}${CL}"
RAMSIZE="${TAB}🛠️${TAB}${CL}"
SEARCH="${TAB}🔍${TAB}${CL}"
VERIFYPW="${TAB}🔐${TAB}${CL}"
CONTAINERID="${TAB}🆔${TAB}${CL}"
HOSTNAME="${TAB}🏠${TAB}${CL}"
BRIDGE="${TAB}🌉${TAB}${CL}"
NETWORK="${TAB}📡${TAB}${CL}"
GATEWAY="${TAB}🌐${TAB}${CL}"
DISABLEIPV6="${TAB}🚫${TAB}${CL}"
DEFAULT="${TAB}⚙️${TAB}${CL}"
MACADDRESS="${TAB}🔗${TAB}${CL}"
VLANTAG="${TAB}🏷️${TAB}${CL}"
ROOTSSH="${TAB}🔑${TAB}${CL}"
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local line_number="$1"
local command="$2"
SCRIPT_NAME=$(basename "$0")
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
echo -e "\n$error_message"
exit 100
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
start() {
base_settings
return
}
build_container() {
# if [ "$VERB" == "yes" ]; then set -x; fi
if [ "$CT_TYPE" == "1" ]; then
FEATURES="keyctl=1,nesting=1"
else
FEATURES="nesting=1"
fi
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-alpine-install.func)"
else
export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-install.func)"
fi
export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP"
export tz=""
export DISABLEIPV6="$DISABLEIP6"
export APPLICATION="$APP"
export app="$NSAPP"
export PASSWORD="$PW"
export VERBOSE="$VERB"
export SSH_ROOT="${SSH}"
export SSH_AUTHORIZED_KEY
export CTID="$CT_ID"
export CTTYPE="$CT_TYPE"
export PCT_OSTYPE="$var_os"
export PCT_OSVERSION="$var_version"
export PCT_DISK_SIZE="$DISK_SIZE"
export tz="$timezone"
export PCT_OPTIONS="
-features $FEATURES
-hostname $HN
-tags $TAGS
$SD
$NS
-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU
-onboot 1
-cores $CORE_COUNT
-memory $RAM_SIZE
-unprivileged $CT_TYPE
$PW
"
echo "Container ID: $CTID"
# This executes create_lxc.sh and creates the container and .conf file
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-create-lxc.sh)"
LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
if [ "$CT_TYPE" == "0" ]; then
cat <<EOF >>$LXC_CONFIG
# USB passthrough
lxc.cgroup2.devices.allow: a
lxc.cap.drop:
lxc.cgroup2.devices.allow: c 188:* rwm
lxc.cgroup2.devices.allow: c 189:* rwm
lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir
lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file
lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file
lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file
lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file
EOF
fi
if [ "$CT_TYPE" == "0" ]; then
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 29:0 rwm
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
EOF
fi
else
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
if [[ -e "/dev/dri/renderD128" ]]; then
if [[ -e "/dev/dri/card0" ]]; then
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
dev0: /dev/dri/card0,gid=44
dev1: /dev/dri/renderD128,gid=104
EOF
else
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
dev0: /dev/dri/card1,gid=44
dev1: /dev/dri/renderD128,gid=104
EOF
fi
fi
fi
fi
# This starts the container and executes <app>-install.sh
msg_info "Starting LXC Container"
pct start "$CTID"
msg_ok "Started LXC Container"
if [[ ! -f "/root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh" ]]; then
msg_error "No install script found for $APP"
exit 1
fi
if [ "$var_os" == "alpine" ]; then
sleep 3
pct exec "$CTID" -- /bin/sh -c 'cat <<EOF >/etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
EOF'
pct exec "$CTID" -- ash -c "apk add bash >/dev/null"
fi
lxc-attach -n "$CTID" -- bash -c "$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh)"
}
description() {
IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
}
@@ -1,163 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="Failure in line $line_number: exit code $exit_code: while executing command $command"
echo -e "\n$error_message"
exit 100
}
verb_ip6() {
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
VALIDCT=$(pvesm status -content rootdir | awk 'NR>1')
if [ -z "$VALIDCT" ]; then
msg_error "Unable to detect a valid Container Storage location."
exit 1
fi
VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1')
if [ -z "$VALIDTMP" ]; then
msg_error "Unable to detect a valid Template Storage location."
exit 1
fi
function select_storage() {
local CLASS=$1
local CONTENT
local CONTENT_LABEL
case $CLASS in
container)
CONTENT='rootdir'
CONTENT_LABEL='Container'
;;
template)
CONTENT='vztmpl'
CONTENT_LABEL='Container template'
;;
*) false || {
msg_error "Invalid storage class."
exit 201
} ;;
esac
# This Queries all storage locations
local -a MENU
while read -r line; do
local TAG=$(echo $line | awk '{print $1}')
local TYPE=$(echo $line | awk '{printf "%-10s", $2}')
local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
local ITEM="Type: $TYPE Free: $FREE "
local OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content $CONTENT | awk 'NR>1')
# Select storage location
if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]}
else
msg_error "STORAGE ISSUES!"
exit 202
fi
}
[[ "${CTID:-}" ]] || {
msg_error "You need to set 'CTID' variable."
exit 203
}
[[ "${PCT_OSTYPE:-}" ]] || {
msg_error "You need to set 'PCT_OSTYPE' variable."
exit 204
}
# Test if ID is valid
[ "$CTID" -ge "100" ] || {
msg_error "ID cannot be less than 100."
exit 205
}
# Test if ID is in use
if pct status $CTID &>/dev/null; then
echo -e "ID '$CTID' is already in use."
unset CTID
msg_error "Cannot use ID that is already in use."
exit 206
fi
TEMPLATE_STORAGE=$(select_storage template) || exit
CONTAINER_STORAGE=$(select_storage container) || exit
pveam update >/dev/null
TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-}
mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V)
[ ${#TEMPLATES[@]} -gt 0 ] || {
msg_error "Unable to find a template when searching for '$TEMPLATE_SEARCH'."
exit 207
}
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
{
msg_error "A problem occurred while downloading the LXC template."
exit 208
}
fi
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
{
msg_error "A problem occurred while re-downloading the LXC template."
exit 208
}
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
msg_error "A problem occurred while trying to create container after re-downloading template."
exit 200
fi
fi
@@ -1,93 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Euo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
error_handler() {
local line_number="$1"
local command="$2"
local error_message="Failure in line $line_number while executing command '$command'"
echo -e "\n$error_message\n" >&2
exit 1
}
verb_ip6() {
STD="silent"
silent() {
"$@" >/dev/null 2>&1 || error_handler "${BASH_LINENO[0]}" "$*"
}
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
RETRY_NUM=10
RETRY_EVERY=3
setting_up_container() {
sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen
locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)
echo "LANG=${locale_line}" >/etc/default/locale
locale-gen >/dev/null
export LANG=${locale_line}
echo $tz >/etc/timezone
ln -sf /usr/share/zoneinfo/$tz /etc/localtime
for ((i = RETRY_NUM; i > 0; i--)); do
if [ "$(hostname -I)" != "" ]; then
break
fi
sleep $RETRY_EVERY
done
if [ "$(hostname -I)" = "" ]; then
echo 1>&2 -e "\nNo Network After $RETRY_NUM Tries"
echo -e "Check Network Settings"
exit 101
fi
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
systemctl disable -q --now systemd-networkd-wait-online.service
}
network_check() {
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
set -e
}
update_os() {
export DEBIAN_FRONTEND=noninteractive
apt-get update >/dev/null 2>&1
apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade >/dev/null
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
}
motd_ssh() {
return
}
customize() {
return
}
@@ -1,50 +0,0 @@
#!/usr/bin/env bash
# Function for generating Figlet headers
generate_headers() {
local base_dir=$1
local target_subdir=$2
local search_pattern=$3
local headers_dir="${base_dir}/headers"
mkdir -p "$headers_dir"
rm -f "$headers_dir"/*
# Recursive or non-recursive search
if [[ "$search_pattern" == "**" ]]; then
shopt -s globstar nullglob
file_list=("${base_dir}"/**/*.sh)
shopt -u globstar
else
file_list=("${base_dir}"/*.sh)
fi
for script in "${file_list[@]}"; do
[[ -f "$script" ]] || continue
app_name=$(grep -oP '^APP="\K[^"]+' "$script" 2>/dev/null)
if [[ -n "$app_name" ]]; then
output_file="${headers_dir}/$(basename "${script%.*}")"
figlet_output=$(figlet -w 500 -f slant "$app_name")
if [[ -n "$figlet_output" ]]; then
echo "$figlet_output" >"$output_file"
echo "Generated: $output_file"
else
echo "Figlet failed for $app_name in $script"
fi
else
echo "No APP name found in $script, skipping."
fi
done
}
# ct
generate_headers "./ct" "headers" "*"
# tools (addon, pve, ...)
generate_headers "./tools" "headers" "**"
# vm
generate_headers "./vm" "headers" "*"
echo "Completed processing all sections."
-20
View File
@@ -1,20 +0,0 @@
#!/bin/bash
FILE=$1
TODAY=$(date -u +"%Y-%m-%d")
if [[ -z "$FILE" ]]; then
echo "No file specified. Exiting."
exit 1
fi
if [[ ! -f "$FILE" ]]; then
echo "File $FILE not found. Exiting."
exit 1
fi
DATE_IN_JSON=$(jq -r '.date_created' "$FILE" 2>/dev/null || echo "")
if [[ "$DATE_IN_JSON" != "$TODAY" ]]; then
jq --arg date "$TODAY" '.date_created = $date' "$FILE" >tmp.json && mv tmp.json "$FILE"
fi
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Verzeichnis, das die JSON-Dateien enthält
json_dir="./json/*.json"
current_date=$(date +"%Y-%m-%d")
for json_file in $json_dir; do
if [[ -f "$json_file" ]]; then
current_json_date=$(jq -r '.date_created' "$json_file")
if [[ "$current_json_date" != "$current_date" ]]; then
echo "Updating $json_file with date $current_date"
jq --arg date "$current_date" '.date_created = $date' "$json_file" >temp.json && mv temp.json "$json_file"
git add "$json_file"
git commit -m "Update date_created to $current_date in $json_file"
else
echo "Date in $json_file is already up to date."
fi
fi
done
git push origin HEAD
-152
View File
@@ -1,152 +0,0 @@
name: Update JSON Date
on:
push:
branches:
- main
paths:
- "frontend/public/json/**.json"
workflow_dispatch:
jobs:
update-app-files:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Generate dynamic branch name
id: timestamp
run: echo "BRANCH_NAME=pr-update-json-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 2 # Ensure we have the last two commits
- name: Get Previous Commit
id: prev_commit
run: |
PREV_COMMIT=$(git rev-parse HEAD^)
echo "Previous commit: $PREV_COMMIT"
echo "prev_commit=$PREV_COMMIT" >> $GITHUB_ENV
- name: Get Newly Added JSON Files
id: new_json_files
run: |
git diff --name-only --diff-filter=A ${{ env.prev_commit }} HEAD | grep '^frontend/public/json/.*\.json$' > new_files.txt || true
echo "New files detected:"
cat new_files.txt || echo "No new files."
- name: Disable file mode changes
run: git config core.fileMode false
- name: Set up Git
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Change JSON Date
id: change-json-date
run: |
current_date=$(date +"%Y-%m-%d")
while IFS= read -r file; do
# Skip empty lines
[[ -z "$file" ]] && continue
if [[ -f "$file" ]]; then
echo "Processing $file..."
current_json_date=$(jq -r '.date_created // empty' "$file")
if [[ -z "$current_json_date" || "$current_json_date" != "$current_date" ]]; then
echo "Updating $file with date $current_date"
jq --arg date "$current_date" '.date_created = $date' "$file" > temp.json && mv temp.json "$file"
else
echo "Date in $file is already up to date."
fi
else
echo "Warning: File $file not found!"
fi
done < new_files.txt
rm new_files.txt
- name: Check if there are any changes
run: |
echo "Checking for changes..."
git add -A
git status
if git diff --cached --quiet; then
echo "No changes detected."
echo "changed=false" >> "$GITHUB_ENV"
else
echo "Changes detected:"
git diff --stat --cached
echo "changed=true" >> "$GITHUB_ENV"
fi
# Step 7: Commit and create PR if changes exist
- name: Commit and create PR if changes exist
if: env.changed == 'true'
run: |
git commit -m "Update date in json"
git checkout -b ${{ env.BRANCH_NAME }}
git push origin ${{ env.BRANCH_NAME }}
gh pr create --title "[core] update date in json" \
--body "This PR is auto-generated by a GitHub Action to update the date in json." \
--head ${{ env.BRANCH_NAME }} \
--base main \
--label "automated pr"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "${{ env.BRANCH_NAME }}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
run: |
git config --global user.name "github-actions-automege[bot]"
git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
- name: No changes detected
if: env.changed == 'false'
run: echo "No changes to commit. Workflow completed successfully."
-162
View File
@@ -1,162 +0,0 @@
name: Validate filenames
on:
pull_request_target:
paths:
- "ct/*.sh"
- "install/*.sh"
- "frontend/public/json/*.json"
jobs:
check-files:
if: github.repository == 'community-scripts/ProxmoxVE'
name: Check changed files
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Get pull request information
if: github.event_name == 'pull_request_target'
uses: actions/github-script@v7
id: pr
with:
script: |
const { data: pullRequest } = await github.rest.pulls.get({
...context.repo,
pull_number: context.payload.pull_request.number,
});
return pullRequest;
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Ensure the full history is fetched for accurate diffing
ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }}
- name: Get changed files
id: changed-files
run: |
if ${{ github.event_name == 'pull_request_target' }}; then
echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | xargs)" >> $GITHUB_OUTPUT
else
echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT
fi
- name: "Validate filenames in ct and install directory"
if: always() && steps.changed-files.outputs.files != ''
id: check-scripts
run: |
CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^(ct|install)/.*\.sh$' || true; })
NON_COMPLIANT_FILES=""
for FILE in $CHANGED_FILES; do
# Skip File "misc/create_lxc.sh"
if [[ "$FILE" == "misc/create_lxc.sh" ]]; then
continue
fi
BASENAME=$(echo "$(basename "${FILE%.*}")")
if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
fi
done
if [ -n "$NON_COMPLIANT_FILES" ]; then
echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
echo "Non-compliant filenames found, change to lowercase:"
for FILE in $NON_COMPLIANT_FILES; do
echo "$FILE"
done
exit 1
fi
- name: "Validate filenames in json directory."
if: always() && steps.changed-files.outputs.files != ''
id: check-json
run: |
CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^json/.*\.json$' || true; })
NON_COMPLIANT_FILES=""
for FILE in $CHANGED_FILES; do
BASENAME=$(echo "$(basename "${FILE%.*}")")
if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
fi
done
if [ -n "$NON_COMPLIANT_FILES" ]; then
echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
echo "Non-compliant filenames found, change to lowercase:"
for FILE in $NON_COMPLIANT_FILES; do
echo "$FILE"
done
exit 1
fi
- name: Post results and comment
if: always() && steps.check-scripts.outputs.files != '' && steps.check-json.outputs.files != '' && github.event_name == 'pull_request_target'
uses: actions/github-script@v7
with:
script: |
const result = "${{ job.status }}" === "success" ? "success" : "failure";
const nonCompliantFiles = {
script: "${{ steps.check-scripts.outputs.files }}",
JSON: "${{ steps.check-json.outputs.files }}",
};
const issueNumber = context.payload.pull_request
? context.payload.pull_request.number
: null;
const commentIdentifier = "validate-filenames";
let newCommentBody = `<!-- ${commentIdentifier}-start -->\n### Filename validation\n\n`;
if (result === "failure") {
newCommentBody += ":x: We found issues in the following changed files:\n\n";
for (const [check, files] of Object.entries(nonCompliantFiles)) {
if (files) {
newCommentBody += `**${check.charAt(0).toUpperCase() + check.slice(1)} filename invalid:**\n${files
.trim()
.split(" ")
.map((file) => `- ${file}`)
.join("\n")}\n\n`;
}
}
newCommentBody +=
"Please change the filenames to lowercase and use only alphanumeric characters and dashes.\n";
} else {
newCommentBody += `:rocket: All files passed filename validation!\n`;
}
newCommentBody += `\n\n<!-- ${commentIdentifier}-end -->`;
if (issueNumber) {
const { data: comments } = await github.rest.issues.listComments({
...context.repo,
issue_number: issueNumber,
});
const existingComment = comments.find(
(comment) => comment.user.login === "github-actions[bot]",
);
if (existingComment) {
if (existingComment.body.includes(commentIdentifier)) {
const re = new RegExp(String.raw`<!-- ${commentIdentifier}-start -->[\s\S]*?<!-- ${commentIdentifier}-end -->`, "");
newCommentBody = existingComment.body.replace(re, newCommentBody);
} else {
newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody;
}
await github.rest.issues.updateComment({
...context.repo,
comment_id: existingComment.id,
body: newCommentBody,
});
} else {
await github.rest.issues.createComment({
...context.repo,
issue_number: issueNumber,
body: newCommentBody,
});
}
}
-77
View File
@@ -1,77 +0,0 @@
# General OS files
.DS_Store
Thumbs.db
# Editor & IDE files (keeping .vscode settings but ignoring unnecessary metadata)
!.vscode/
.vscode/*.workspace
.vscode/*.tmp
# Log and Cache files
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Python-specific exclusions
__pycache__/
*.pyc
*.pyo
*.pyd
*.venv/
venv/
env/
*.env
# Node.js dependencies (frontend folder was excluded, but keeping this rule for reference)
frontend/node_modules/
frontend/.svelte-kit/
frontend/.turbo/
frontend/.vite/
frontend/build/
# API and Backend specific exclusions
api/.env
api/__pycache__/
api/*.sqlite3
# Install scripts and temporary files
install/tmp/
install/*.bak
# VM and Container-specific exclusions
vm/tmp/
vm/*.qcow2
vm/*.img
vm/*.vmdk
vm/*.iso
vm/*.bak
# Miscellaneous temporary or unnecessary files
*.bak
*.swp
*.swo
*.swn
*.tmp
*.backup
# JSON configuration backups
json/*.bak
json/*.tmp
json/.vscode/
# Ignore compiled binaries or packaged artifacts
*.exe
*.dll
*.bin
*.deb
*.rpm
*.tar.gz
*.zip
*.tgz
# Ignore repository metadata or Git itself
.git/
.gitignore
.vscode/settings.json
-16
View File
@@ -1,16 +0,0 @@
; editorconfig.org
root = true
[*]
charset = utf-8
continuation_indent_size = 2
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 120
tab_width = 2
; trim_trailing_whitespace = true ; disabled until files are cleaned up
[*.md]
trim_trailing_whitespace = false
-9
View File
@@ -1,9 +0,0 @@
{
"recommendations": [
"bmalehorn.shell-syntax",
"timonwong.shellcheck",
"foxundermoon.shell-format",
"editorconfig.editorconfig"
],
"unwantedRecommendations": []
}
-11
View File
@@ -1,11 +0,0 @@
{
"files.associations": {
"*.func": "shellscript"
},
"files.eol": "\n",
"files.insertFinalNewline": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
}
}
-8869
View File
File diff suppressed because it is too large. Load diff
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021-2025 tteck | community-scripts ORG
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1 -114
View File
@@ -1,114 +1 @@
<div align="center">
<p align="center">
<a href="#">
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="100px" />
</a>
</p>
</div>
<div style="border: 2px solid #d1d5db; padding: 20px; border-radius: 8px; background-color: #f9fafb;">
<h2 align="center">Proxmox VE Helper-Scripts</h2>
<p align="center">A Community Legacy in Memory of @tteck</p>
<p align="center">
<a href="https://helper-scripts.com">
<img src="https://img.shields.io/badge/Website-4c9b3f?style=for-the-badge&logo=github&logoColor=white" alt="Website" />
</a>
<a href="https://discord.gg/3AnUqsXnmK">
<img src="https://img.shields.io/badge/Discord-7289da?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" />
</a>
<a href="https://ko-fi.com/community_scripts">
<img src="https://img.shields.io/badge/Support-FF5F5F?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Donate" />
</a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/CONTRIBUTING.md">
<img src="https://img.shields.io/badge/Contribute-ff4785?style=for-the-badge&logo=git&logoColor=white" alt="Contribute" />
</a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/USER_SUBMITTED_GUIDES.md">
<img src="https://img.shields.io/badge/Guides-0077b5?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Guides" />
</a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md">
<img src="https://img.shields.io/badge/Changelog-6c5ce7?style=for-the-badge&logo=git&logoColor=white" alt="Changelog" />
</a>
</p>
</div>
---
## 🚀 Project Overview
**Proxmox VE Helper-Scripts** is a collection of tools to simplify the setup and management of Proxmox Virtual Environment (VE). Originally created by [tteck](https://github.com/tteck), these scripts are now continued by the community. Our goal is to preserve and expand upon tteck's work, providing an ongoing resource for Proxmox users worldwide.
---
## 📦 Features
- **Interactive Setup**: Choose between simple and advanced options for configuring VMs and LXC containers.
- **Customizable Configurations**: Advanced setup for fine-tuning your environment.
- **Seamless Integration**: Works seamlessly with Proxmox VE for a smooth experience.
- **Community-driven**: Actively maintained and improved by the Proxmox community.
---
## ✅ Requirements
Ensure your system meets the following prerequisites:
- **Proxmox VE version**: 8.x or higher
- **Linux**: Compatible with most distributions
- **Dependencies**: bash and curl should be installed.
---
## 🚀 Installation
To install the Proxmox Helper Scripts, follow these steps:
1. Visit the [Website](https://helper-scripts.com/).
2. Search for the desired script, e.g., **"Home Assistant OS VM"**.
3. Copy the provided **Bash command** from the **"How To Install"** section.
4. Open the Proxmox shell on your **main node** and paste the command.
5. Press enter to start the installation! 🚀
---
## ❤️ Community and Contributions
We appreciate any contributions to the project—whether it's bug reports, feature requests, documentation improvements, or spreading the word. Your involvement helps keep the project alive and sustainable.
## 💖 Donate to Support the Project
- **Ko-Fi for Community Edition**: [Donate to support this project](https://ko-fi.com/community_scripts) – Donations go towards maintaining the project, testing infrastructure, and charity (cancer research, hospice care). 30% of the funds will be donated to charity.
---
## 💬 Get Help
Join our community for support:
- **Discord**: Join our [Proxmox Helper Scripts Discord server](https://discord.gg/3AnUqsXnmK) for real-time support.
- **GitHub Discussions**: [Ask questions or report issues](https://github.com/community-scripts/ProxmoxVE/discussions).
## 🤝 Report a Bug or Feature Request
If you encounter any issues or have suggestions for improvement, file a new issue on our [GitHub issues page](https://github.com/community-scripts/ProxmoxVE/issues). You can also submit pull requests with solutions or enhancements!
---
## ⭐ Star History
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
</picture>
</a>
## 📜 License
This project is licensed under the [MIT License](LICENSE).
</br>
</br>
<p align="center">
<i style="font-size: smaller;"><b>Proxmox</b>® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a>.</i>
</p>
Screenshots taken by pr-script-test.yml for the PR comments. Not code; never merge this branch.
-64
View File
@@ -1,64 +0,0 @@
# Security Policy
## Supported Versions
This project currently supports the following versions of Proxmox VE (PVE):
| Version | Supported |
| ------- | ------------------ |
| 9.0.x | :white_check_mark: |
| 8.4.x | :white_check_mark: |
| 8.3.x | :white_check_mark: |
| 8.2.x | :white_check_mark: |
| 8.1.x | :white_check_mark: |
| 8.0.x | Limited support* ❕ |
| < 8.0 | :x: |
*Version 8.0.x has limited support. Security updates may not be provided for all issues affecting this version.
---
## Reporting a Vulnerability
Security vulnerabilities must not be reported publicly to avoid potential exploitation.
Instead, please report them privately via one of the following channels:
- **Discord**: Join our [Discord server](https://discord.gg/jsYVk5JBxq) and send a direct message to a maintainer.
- **Email**: Write to us at **contact@community-scripts.org** with the subject line:
`Vulnerability Report - <Project/Script Name>`.
When reporting a vulnerability, please provide:
- A clear description of the issue
- Steps to reproduce the vulnerability
- Affected versions or environments
- (Optional) Suggested fixes or workarounds
---
## Response Process
1. **Acknowledgment**
- We will review and acknowledge your report within **7 business days**.
2. **Assessment**
- The maintainers will verify the issue and classify its severity.
- Depending on impact, a patch may be released immediately or scheduled for the next update.
3. **Resolution**
- Critical security fixes will be prioritized.
- Non-critical issues may be deferred or declined with an explanation.
---
## Disclaimer
Not all reported issues will be treated as vulnerabilities.
Reports may be declined if they are deemed:
- Low-risk
- Out of project scope
- Conflicting with intended design or architecture
---
If you have any questions or concerns about this security policy, please reach out to the maintainers through the contact options above.
-5
View File
@@ -1,5 +0,0 @@
MONGO_USER=
MONGO_PASSWORD=
MONGO_IP=
MONGO_PORT=
MONGO_DATABASE=
-23
View File
@@ -1,23 +0,0 @@
module proxmox-api
go 1.23.2
require (
github.com/gorilla/mux v1.8.1
github.com/joho/godotenv v1.5.1
github.com/rs/cors v1.11.1
go.mongodb.org/mongo-driver v1.17.2
)
require (
github.com/golang/snappy v0.0.4 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/text v0.22.0 // indirect
)
-56
View File
@@ -1,56 +0,0 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM=
go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-450
View File
@@ -1,450 +0,0 @@
// Copyright (c) 2021-2025 community-scripts ORG
// Author: Michel Roegl-Brunner (michelroegl-brunner)
// License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
"github.com/rs/cors"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var client *mongo.Client
var collection *mongo.Collection
func loadEnv() {
if err := godotenv.Load(); err != nil {
log.Fatal("Error loading .env file")
}
}
// DataModel represents a single document in MongoDB
type DataModel struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
DISK_SIZE float32 `json:"disk_size" bson:"disk_size"`
CORE_COUNT uint `json:"core_count" bson:"core_count"`
RAM_SIZE uint `json:"ram_size" bson:"ram_size"`
OS_TYPE string `json:"os_type" bson:"os_type"`
OS_VERSION string `json:"os_version" bson:"os_version"`
DISABLEIP6 string `json:"disableip6" bson:"disableip6"`
NSAPP string `json:"nsapp" bson:"nsapp"`
METHOD string `json:"method" bson:"method"`
CreatedAt time.Time `json:"created_at" bson:"created_at"`
PVEVERSION string `json:"pve_version" bson:"pve_version"`
STATUS string `json:"status" bson:"status"`
RANDOM_ID string `json:"random_id" bson:"random_id"`
TYPE string `json:"type" bson:"type"`
ERROR string `json:"error" bson:"error"`
}
type StatusModel struct {
RANDOM_ID string `json:"random_id" bson:"random_id"`
ERROR string `json:"error" bson:"error"`
STATUS string `json:"status" bson:"status"`
}
type CountResponse struct {
TotalEntries int64 `json:"total_entries"`
StatusCount map[string]int64 `json:"status_count"`
NSAPPCount map[string]int64 `json:"nsapp_count"`
}
// ConnectDatabase initializes the MongoDB connection
func ConnectDatabase() {
loadEnv()
mongoURI := fmt.Sprintf("mongodb://%s:%s@%s:%s",
os.Getenv("MONGO_USER"),
os.Getenv("MONGO_PASSWORD"),
os.Getenv("MONGO_IP"),
os.Getenv("MONGO_PORT"))
database := os.Getenv("MONGO_DATABASE")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var err error
client, err = mongo.Connect(ctx, options.Client().ApplyURI(mongoURI))
if err != nil {
log.Fatal("Failed to connect to MongoDB!", err)
}
collection = client.Database(database).Collection("data_models")
fmt.Println("Connected to MongoDB on 10.10.10.18")
}
// UploadJSON handles API requests and stores data as a document in MongoDB
func UploadJSON(w http.ResponseWriter, r *http.Request) {
var input DataModel
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
input.CreatedAt = time.Now()
_, err := collection.InsertOne(context.Background(), input)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Println("Received data:", input)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
}
// UpdateStatus updates the status of a record based on RANDOM_ID
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
var input StatusModel
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
filter := bson.M{"random_id": input.RANDOM_ID}
update := bson.M{"$set": bson.M{"status": input.STATUS, "error": input.ERROR}}
_, err := collection.UpdateOne(context.Background(), filter, update)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Println("Updated data:", input)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
}
// GetDataJSON fetches all data from MongoDB
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetPaginatedData(w http.ResponseWriter, r *http.Request) {
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
if page < 1 {
page = 1
}
if limit < 1 {
limit = 10
}
skip := (page - 1) * limit
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
options := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
cursor, err := collection.Find(ctx, bson.M{}, options)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetSummary(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
totalCount, err := collection.CountDocuments(ctx, bson.M{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
statusCount := make(map[string]int64)
nsappCount := make(map[string]int64)
pipeline := []bson.M{
{"$group": bson.M{"_id": "$status", "count": bson.M{"$sum": 1}}},
}
cursor, err := collection.Aggregate(ctx, pipeline)
if err == nil {
for cursor.Next(ctx) {
var result struct {
ID string `bson:"_id"`
Count int64 `bson:"count"`
}
if err := cursor.Decode(&result); err == nil {
statusCount[result.ID] = result.Count
}
}
}
pipeline = []bson.M{
{"$group": bson.M{"_id": "$nsapp", "count": bson.M{"$sum": 1}}},
}
cursor, err = collection.Aggregate(ctx, pipeline)
if err == nil {
for cursor.Next(ctx) {
var result struct {
ID string `bson:"_id"`
Count int64 `bson:"count"`
}
if err := cursor.Decode(&result); err == nil {
nsappCount[result.ID] = result.Count
}
}
}
response := CountResponse{
TotalEntries: totalCount,
StatusCount: statusCount,
NSAPPCount: nsappCount,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func GetByNsapp(w http.ResponseWriter, r *http.Request) {
nsapp := r.URL.Query().Get("nsapp")
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{"nsapp": nsapp})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetByDateRange(w http.ResponseWriter, r *http.Request) {
startDate := r.URL.Query().Get("start_date")
endDate := r.URL.Query().Get("end_date")
if startDate == "" || endDate == "" {
http.Error(w, "Both start_date and end_date are required", http.StatusBadRequest)
return
}
start, err := time.Parse("2006-01-02T15:04:05.999999+00:00", startDate+"T00:00:00+00:00")
if err != nil {
http.Error(w, "Invalid start_date format", http.StatusBadRequest)
return
}
end, err := time.Parse("2006-01-02T15:04:05.999999+00:00", endDate+"T23:59:59+00:00")
if err != nil {
http.Error(w, "Invalid end_date format", http.StatusBadRequest)
return
}
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{
"created_at": bson.M{
"$gte": start,
"$lte": end,
},
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetByStatus(w http.ResponseWriter, r *http.Request) {
status := r.URL.Query().Get("status")
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{"status": status})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetByOS(w http.ResponseWriter, r *http.Request) {
osType := r.URL.Query().Get("os_type")
osVersion := r.URL.Query().Get("os_version")
var records []DataModel
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{"os_type": osType, "os_version": osVersion})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
records = append(records, record)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(records)
}
func GetErrors(w http.ResponseWriter, r *http.Request) {
errorCount := make(map[string]int)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cursor, err := collection.Find(ctx, bson.M{"error": bson.M{"$ne": ""}})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var record DataModel
if err := cursor.Decode(&record); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if record.ERROR != "" {
errorCount[record.ERROR]++
}
}
type ErrorCountResponse struct {
Error string `json:"error"`
Count int `json:"count"`
}
var errorCounts []ErrorCountResponse
for err, count := range errorCount {
errorCounts = append(errorCounts, ErrorCountResponse{
Error: err,
Count: count,
})
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(struct {
ErrorCounts []ErrorCountResponse `json:"error_counts"`
}{
ErrorCounts: errorCounts,
})
}
func main() {
ConnectDatabase()
router := mux.NewRouter()
router.HandleFunc("/upload", UploadJSON).Methods("POST")
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
router.HandleFunc("/data/paginated", GetPaginatedData).Methods("GET")
router.HandleFunc("/data/summary", GetSummary).Methods("GET")
router.HandleFunc("/data/nsapp", GetByNsapp).Methods("GET")
router.HandleFunc("/data/date", GetByDateRange).Methods("GET")
router.HandleFunc("/data/status", GetByStatus).Methods("GET")
router.HandleFunc("/data/os", GetByOS).Methods("GET")
router.HandleFunc("/data/errors", GetErrors).Methods("GET")
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST"},
AllowedHeaders: []string{"Content-Type", "Authorization"},
AllowCredentials: true,
})
handler := c.Handler(router)
fmt.Println("Server running on port 8080")
log.Fatal(http.ListenAndServe(":8080", handler))
}
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: jkrgr0
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://docs.2fauth.app/
APP="2FAuth"
var_tags="${var_tags:-2fa;authenticator}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d "/opt/2fauth" ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "2fauth" "Bubka/2FAuth"; then
$STD apt update
$STD apt -y upgrade
msg_info "Creating Backup"
mv "/opt/2fauth" "/opt/2fauth-backup"
if ! dpkg -l | grep -q 'php8.3'; then
cp /etc/nginx/conf.d/2fauth.conf /etc/nginx/conf.d/2fauth.conf.bak
fi
msg_ok "Backup Created"
if ! dpkg -l | grep -q 'php8.3'; then
$STD apt-get install -y \
lsb-release \
gnupg2
PHP_VERSION="8.3" PHP_MODULE="common,ctype,fileinfo,mysql,cli" PHP_FPM="YES" setup_php
sed -i 's/php8.2/php8.3/g' /etc/nginx/conf.d/2fauth.conf
fi
fetch_and_deploy_gh_release "2fauth" "Bubka/2FAuth"
setup_composer
mv "/opt/2fauth-backup/.env" "/opt/2fauth/.env"
mv "/opt/2fauth-backup/storage" "/opt/2fauth/storage"
cd "/opt/2fauth" || return
chown -R www-data: "/opt/2fauth"
chmod -R 755 "/opt/2fauth"
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev --prefer-source
php artisan 2fauth:install
$STD systemctl restart nginx
msg_info "Cleaning Up"
if dpkg -l | grep -q 'php8.2'; then
$STD apt remove --purge -y php8.2*
fi
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleanup Completed"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:80${CL}"
-67
View File
@@ -1,67 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://actualbudget.org/
APP="Actual Budget"
var_tags="${var_tags:-finance}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/actualbudget_version.txt ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
NODE_VERSION="22" setup_nodejs
RELEASE=$(curl -fsSL https://api.github.com/repos/actualbudget/actual/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ -f /opt/actualbudget-data/config.json ]]; then
if [[ ! -f /opt/actualbudget_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/actualbudget_version.txt)" ]]; then
msg_info "Stopping Service"
systemctl stop actualbudget
msg_ok "Stopped Service"
msg_info "Updating ${APP} to ${RELEASE}"
$STD npm update -g @actual-app/sync-server
echo "${RELEASE}" >/opt/actualbudget_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
msg_info "Starting Service"
systemctl start actualbudget
msg_ok "Started Service"
msg_ok "Updated successfully!"
else
msg_info "${APP} is already up to date"
fi
else
msg_info "Old Installation Found, you need to migrate your data and recreate to a new container"
msg_info "Please follow the instructions on the ${APP} website to migrate your data"
msg_info "https://actualbudget.org/docs/backup-restore/backup"
exit
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:5006${CL}"
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://adguard.com/
APP="Adguard"
var_tags="${var_tags:-adblock}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/AdGuardHome ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Adguard Home can only be updated via the user interface."
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: MickLesk (Canbiz)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://adventurelog.app/
APP="AdventureLog"
var_tags="${var_tags:-traveling}"
var_disk="${var_disk:-7}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/adventurelog ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if ! command -v memcached >/dev/null 2>&1; then
$STD apt update
$STD apt install -y memcached libmemcached-tools
fi
if check_for_gh_release "adventurelog" "seanmorley15/adventurelog"; then
msg_info "Stopping Services"
systemctl stop adventurelog-backend
systemctl stop adventurelog-frontend
msg_ok "Services Stopped"
msg_info "Backup Old Installation"
cp -r /opt/adventurelog /opt/adventurelog-backup
rm -rf /opt/adventurelog
msg_ok "Backup done"
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog"
PYTHON_VERSION="3.13" setup_uv
msg_info "Updating ${APP}"
cp /opt/adventurelog-backup/backend/server/.env /opt/adventurelog/backend/server/.env
cp -r /opt/adventurelog-backup/backend/server/media /opt/adventurelog/backend/server/media
cd /opt/adventurelog/backend/server || exit
if [[ ! -x .venv/bin/python ]]; then
$STD uv venv .venv
$STD .venv/bin/python -m ensurepip --upgrade
fi
$STD .venv/bin/python -m pip install --upgrade pip
$STD .venv/bin/python -m pip install -r requirements.txt
$STD .venv/bin/python -m manage collectstatic --noinput
$STD .venv/bin/python -m manage migrate
cp /opt/adventurelog-backup/frontend/.env /opt/adventurelog/frontend/.env
cd /opt/adventurelog/frontend || exit
$STD pnpm i
$STD pnpm build
msg_ok "Updated ${APP}"
msg_info "Starting Services"
systemctl daemon-reexec
systemctl start adventurelog-backend
systemctl start adventurelog-frontend
msg_ok "Services Started"
msg_info "Cleaning Up"
rm -rf /opt/adventurelog-backup
msg_ok "Cleaned"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-63
View File
@@ -1,63 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.ispyconnect.com/
APP="AgentDVR"
var_tags="${var_tags:-dvr}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-0}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/agentdvr ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -fsSL "https://www.ispyconnect.com/api/Agent/DownloadLocation4?platform=Linux64&fromVersion=0" | grep -o 'https://.*\.zip')
if [[ "${RELEASE}" != "$(cat ~/.agentdvr 2>/dev/null)" ]] || [[ ! -f ~/.agentdvr ]]; then
msg_info "Stopping service"
systemctl stop AgentDVR
msg_ok "Service stopped"
msg_info "Updating $APP"
cd /opt/agentdvr/agent
curl -fsSL "$RELEASE" -o $(basename "$RELEASE")
$STD unzip -o Agent_Linux64*.zip
chmod +x ./Agent
echo $RELEASE >~/.agentdvr
rm -rf Agent_Linux64*.zip
msg_ok "Updated $APP"
msg_info "Starting service"
systemctl start AgentDVR
msg_ok "Service started"
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8090${CL}"
-46
View File
@@ -1,46 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://adguardhome.com/
APP="Alpine-AdGuard"
var_tags="${var_tags:-alpine;adblock}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating AdGuard Home"
$STD /opt/AdGuardHome/AdGuardHome --update
msg_ok "Updated AdGuard Home"
msg_info "Restarting AdGuard Home"
$STD rc-service adguardhome restart
msg_ok "Restarted AdGuard Home"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/bitmagnet-io/bitmagnet
APP="Alpine-bitmagnet"
var_tags="${var_tags:-alpine;torrent}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-3}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /opt/bitmagnet ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -fsSL https://api.github.com/repos/bitmagnet-io/bitmagnet/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [ "${RELEASE}" != "$(cat /opt/bitmagnet_version.txt)" ] || [ ! -f /opt/bitmagnet_version.txt ]; then
msg_info "Backing up database"
rm -f /tmp/backup.sql
$STD sudo -u postgres pg_dump \
--column-inserts \
--data-only \
--on-conflict-do-nothing \
--rows-per-insert=1000 \
--table=metadata_sources \
--table=content \
--table=content_attributes \
--table=content_collections \
--table=content_collections_content \
--table=torrent_sources \
--table=torrents \
--table=torrent_files \
--table=torrent_hints \
--table=torrent_contents \
--table=torrent_tags \
--table=torrents_torrent_sources \
--table=key_values \
bitmagnet \
>/tmp/backup.sql
mv /tmp/backup.sql /opt/
msg_ok "Database backed up"
msg_info "Updating ${APP} from $(cat /opt/bitmagnet_version.txt) to ${RELEASE}"
$STD apk -U upgrade
$STD service bitmagnet stop
[ -f /opt/bitmagnet/.env ] && cp /opt/bitmagnet/.env /opt/
[ -f /opt/bitmagnet/config.yml ] && cp /opt/bitmagnet/config.yml /opt/
rm -rf /opt/bitmagnet/*
temp_file=$(mktemp)
curl -fsSL "https://github.com/bitmagnet-io/bitmagnet/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
tar zxf "$temp_file" --strip-components=1 -C /opt/bitmagnet
cd /opt/bitmagnet
VREL=v$RELEASE
$STD go build -ldflags "-s -w -X github.com/bitmagnet-io/bitmagnet/internal/version.GitTag=$VREL"
chmod +x bitmagnet
[ -f "/opt/.env" ] && cp "/opt/.env" /opt/bitmagnet/
[ -f "/opt/config.yml" ] && cp "/opt/config.yml" /opt/bitmagnet/
rm -f "$temp_file"
echo "${RELEASE}" >/opt/bitmagnet_version.txt
$STD service bitmagnet start
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3333${CL}"
-46
View File
@@ -1,46 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: cobalt (cobaltgit)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://caddyserver.com/
APP="Alpine-Caddy"
var_tags="${var_tags:-webserver}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-3}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /etc/caddy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating $APP LXC"
$STD apk -U upgrade
msg_ok "Updated $APP LXC"
msg_info "Restarting Caddy"
rc-service caddy restart
msg_ok "Restarted Caddy"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:80${CL}"
-52
View File
@@ -1,52 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.docker.com/
APP="Alpine-Docker"
var_tags="${var_tags:-docker;alpine}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-2}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \
"1" "Check for Docker Updates" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
$STD apk -U upgrade
msg_ok "Updated successfully!"
exit
;;
esac
done
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Johann3s-H (An!ma)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://forgejo.org/
APP="Alpine-Forgejo"
var_tags="${var_tags:-alpine;git}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Forgejo"
$STD apk upgrade forgejo
msg_ok "Updated Forgejo"
msg_info "Restarting Forgejo"
$STD rc-service forgejo restart
msg_ok "Restarted Forgejo"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-63
View File
@@ -1,63 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://garagehq.deuxfleurs.fr/
APP="Alpine-Garage"
var_tags="${var_tags:-alpine;object-storage}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-5}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -f /usr/local/bin/garage ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
GITEA_RELEASE=$(curl -fsSL https://api.github.com/repos/deuxfleurs-org/garage/tags | jq -r '.[0].name')
if [[ "${GITEA_RELEASE}" != "$(cat ~/.garage 2>/dev/null)" ]] || [[ ! -f ~/.garage ]]; then
msg_info "Stopping Service"
rc-service garage stop || true
msg_ok "Stopped Service"
msg_info "Backing Up Data"
cp /usr/local/bin/garage /usr/local/bin/garage.old 2>/dev/null || true
cp /etc/garage.toml /etc/garage.toml.bak 2>/dev/null || true
msg_ok "Backed Up Data"
msg_info "Updating Garage"
curl -fsSL "https://garagehq.deuxfleurs.fr/_releases/${GITEA_RELEASE}/x86_64-unknown-linux-musl/garage" -o /usr/local/bin/garage
chmod +x /usr/local/bin/garage
echo "${GITEA_RELEASE}" >~/.garage
msg_ok "Updated Garage"
msg_info "Starting Service"
rc-service garage start || rc-service garage restart
msg_ok "Started Service"
msg_ok "Updated successfully!"
else
msg_ok "No update required. Garage is already at ${GITEA_RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
-61
View File
@@ -1,61 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/TwiN/gatus
APP="Alpine-gatus"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-3}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /opt/gatus ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -s https://api.github.com/repos/TwiN/gatus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [ "${RELEASE}" != "$(cat /opt/gatus_version.txt)" ] || [ ! -f /opt/gatus_version.txt ]; then
msg_info "Updating ${APP} LXC"
$STD apk -U upgrade
$STD service gatus stop
mv /opt/gatus/config/config.yaml /opt
rm -rf /opt/gatus/*
temp_file=$(mktemp)
curl -fsSL "https://github.com/TwiN/gatus/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
tar zxf "$temp_file" --strip-components=1 -C /opt/gatus
cd /opt/gatus
$STD go mod tidy
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gatus .
setcap CAP_NET_RAW+ep gatus
mv /opt/config.yaml config
rm -f "$temp_file"
echo "${RELEASE}" >/opt/gatus_version.txt
$STD service gatus start
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
-46
View File
@@ -1,46 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://gitea.io
APP="Alpine-Gitea"
var_tags="${var_tags:-alpine;git}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Gitea"
apk upgrade gitea
msg_ok "Updated Gitea"
msg_info "Restarting Gitea"
rc-service gitea restart
msg_ok "Restarted Gitea"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-69
View File
@@ -1,69 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://grafana.com/
APP="Alpine-Grafana"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \
"1" "Check for Grafana Updates" \
"2" "Allow 0.0.0.0 for listening" \
"3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
$STD apk -U upgrade
msg_ok "Updated successfully!"
exit
;;
2)
sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=0.0.0.0/g" /etc/conf.d/grafana
service grafana restart
msg_ok "Allowed listening on all interfaces!"
exit
;;
3)
sed -i -e "s/cfg:server.http_addr=.*/cfg:server.http_addr=$LXCIP/g" /etc/conf.d/grafana
service grafana restart
msg_ok "Allowed listening only on ${LXCIP}!"
exit
;;
esac
done
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://${IP}:3000${CL} \n"
-54
View File
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: nicedevil007 (NiceDevil)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://it-tools.tech/
APP="Alpine-IT-Tools"
var_tags="${var_tags:-alpine;development}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [ ! -d /usr/share/nginx/html ]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -fsSL https://api.github.com/repos/sharevb/it-tools/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
if [ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ] || [ ! -f /opt/${APP}_version.txt ]; then
msg_info "Updating ${APP} LXC"
curl -fsSL "https://github.com/sharevb/it-tools/releases/download/${RELEASE}/it-tools-${RELEASE#v}.zip" -o it-tools.zip
mkdir -p /usr/share/nginx/html
rm -rf /usr/share/nginx/html/*
$STD unzip it-tools.zip -d /tmp
cp -r /tmp/dist/* /usr/share/nginx/html
rm -rf /tmp/dist
rm -f it-tools.zip
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
-69
View File
@@ -1,69 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://komo.do
APP="Alpine-Komodo"
var_tags="${var_tags:-docker,alpine}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-10}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
[[ -d /opt/komodo ]] || {
msg_error "No ${APP} Installation Found!"
exit
}
msg_info "Updating ${APP}"
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
if [[ -z "$COMPOSE_FILE" ]]; then
msg_error "No valid compose file found in /opt/komodo!"
exit
fi
COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
msg_error "❌ Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
echo -e "${YW}Please follow the migration guide:${CL}"
echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
exit
fi
BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
exit
}
GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}"
if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then
msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!"
mv "$BACKUP_FILE" "$COMPOSE_FILE"
exit
fi
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
msg_ok "Updated Alpine-Komodo"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9120${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://mariadb.org
APP="Alpine-MariaDB"
var_tags="${var_tags:-alpine;database}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating MariaDB"
$STD apk upgrade mariadb mariadb-client
msg_ok "Updated MariaDB"
msg_info "Restarting MariaDB"
$STD rc-service mariadb restart
msg_ok "Restarted MariaDB"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}${IP}:3306${CL}"
-62
View File
@@ -1,62 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nextcloud.com/
APP="Alpine-Nextcloud"
var_tags="${var_tags:-alpine;cloud}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-2}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if [[ ! -d /usr/share/webapps/nextcloud ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
while true; do
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \
"1" "Nextcloud Login Credentials" ON \
"2" "Renew Self-signed Certificate" OFF \
3>&1 1>&2 2>&3)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
cat nextcloud.creds
exit
;;
2)
openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj "/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local" >/dev/null 2>&1
rc-service nginx restart
exit
;;
esac
done
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${APP} should be reachable by going to the following URL.
${BL}https://${IP}${CL} \n"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nodered.org
APP="Alpine-Node-RED"
var_tags="${var_tags:-alpine;automation}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Node.js and npm"
$STD apk upgrade nodejs npm
msg_ok "Updated Node.js and npm"
msg_info "Updating Node-RED"
$STD npm install -g --unsafe-perm node-red
msg_ok "Updated Node-RED"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:1880${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://postgresql.org/
APP="Alpine-PostgreSQL"
var_tags="${var_tags:-alpine;database}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating PostgreSQL"
$STD apk upgrade postgresql postgresql-contrib
msg_ok "Updated PostgreSQL"
msg_info "Restarting PostgreSQL"
$STD rc-service postgresql restart
msg_ok "Restarted PostgreSQL"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}${IP}:5432${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://prometheus.io/
APP="Alpine-Prometheus"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Prometheus"
$STD apk upgrade prometheus
msg_ok "Updated Prometheus"
msg_info "Restarting Prometheus"
$STD rc-service prometheus restart
msg_ok "Restarted Prometheus"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9090${CL}"
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/rclone/rclone
APP="Alpine-rclone"
var_tags="${var_tags:-alpine;backup}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [ ! -d /opt/rclone ]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -s https://api.github.com/repos/rclone/rclone/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [ "${RELEASE}" != "$(cat /opt/rclone_version.txt)" ] || [ ! -f /opt/rclone_version.txt ]; then
msg_info "Updating ${APP} LXC"
temp_file=$(mktemp)
curl -fsSL "https://github.com/rclone/rclone/releases/download/v${RELEASE}/rclone-v${RELEASE}-linux-amd64.zip" -o "$temp_file"
$STD unzip -o "$temp_file" '*/**' -d /opt/rclone
rm -f "$temp_file"
echo "${RELEASE}" >/opt/rclone_version.txt
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-72
View File
@@ -1,72 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://redis.io/
APP="Alpine-Redis"
var_tags="${var_tags:-alpine;database}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Redis Management" --menu "Select option" 11 58 3 \
"1" "Update Redis" \
"2" "Allow 0.0.0.0 for listening" \
"3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
msg_info "Updating Redis"
apk update && apk upgrade redis
rc-service redis restart
msg_ok "Updated successfully!"
exit
;;
2)
msg_info "Setting Redis to listen on all interfaces"
sed -i 's/^bind .*/bind 0.0.0.0/' /etc/redis.conf
rc-service redis restart
msg_ok "Redis now listens on all interfaces!"
exit
;;
3)
msg_info "Setting Redis to listen only on ${LXCIP}"
sed -i "s/^bind .*/bind ${LXCIP}/" /etc/redis.conf
rc-service redis restart
msg_ok "Redis now listens only on ${LXCIP}!"
exit
;;
esac
done
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${APP} should be reachable on port 6379.
${BL}redis-cli -h ${IP} -p 6379${CL} \n"
-55
View File
@@ -1,55 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: andrej-kocijan (Andrej Kocijan)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/redlib-org/redlib
APP="Alpine-Redlib"
var_tags="${var_tags:-alpine;frontend}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_resources
if [[ ! -d /opt/redlib ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Stopping Service"
$STD rc-service redlib stop
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
msg_info "Starting Service"
$STD rc-service redlib start
msg_ok "Started Service"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5252${CL}"
-74
View File
@@ -1,74 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/rustdesk/rustdesk-server
APP="Alpine-RustDeskServer"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-3}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /opt/rustdesk-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
if [ "${RELEASE}" != "$(cat ~/.rustdesk-server 2>/dev/null)" ] || [ ! -f ~/.rustdesk-server ]; then
msg_info "Updating RustDesk Server to v${RELEASE}"
$STD apk -U upgrade
$STD service rustdesk-server-hbbs stop
$STD service rustdesk-server-hbbr stop
temp_file1=$(mktemp)
curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
$STD unzip "$temp_file1"
cp -r amd64/* /opt/rustdesk-server/
echo "${RELEASE}" >~/.rustdesk-server
$STD service rustdesk-server-hbbs start
$STD service rustdesk-server-hbbr start
rm -rf amd64
rm -f $temp_file1
msg_ok "Updated RustDesk Server successfully"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi
if [ "${APIRELEASE}" != "$(cat ~/.rustdesk-api)" ] || [ ! -f ~/.rustdesk-api ]; then
msg_info "Updating RustDesk API to v${APIRELEASE}"
$STD service rustdesk-api stop
temp_file2=$(mktemp)
curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
$STD tar zxvf "$temp_file2"
cp -r release/* /opt/rustdesk-api
echo "${APIRELEASE}" >~/.rustdesk-api
$STD service rustdesk-api start
rm -rf release
rm -f $temp_file2
msg_ok "Updated RustDesk API"
else
msg_ok "No update required. RustDesk API is already at v${APIRELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:21114${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://syncthing.net/
APP="Alpine-Syncthing"
var_tags="${var_tags:-alpine;networking}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Syncthing"
$STD apk upgrade syncthing
msg_ok "Updated Syncthing"
msg_info "Restarting Syncthing"
$STD rc-service syncthing restart
msg_ok "Restarted Syncthing"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8384${CL}"
-57
View File
@@ -1,57 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: tremor021 (Slaviša Arežina)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://teamspeak.com/en/
APP="Alpine-TeamSpeak-Server"
var_tags="${var_tags:-alpine;communication}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-2}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /opt/teamspeak-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
set +o pipefail && RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | head -1) && set -o pipefail
if [ "${RELEASE}" != "$(cat ~/.teamspeak-server)" ] || [ ! -f ~/.teamspeak-server ]; then
msg_info "Updating ${APP} LXC"
$STD apk -U upgrade
$STD service teamspeak stop
curl -fsSL "https://files.teamspeak-services.com/releases/server/${RELEASE}/teamspeak3-server_linux_amd64-${RELEASE}.tar.bz2" -o ts3server.tar.bz2
tar -xf ./ts3server.tar.bz2
cp -ru teamspeak3-server_linux_amd64/* /opt/teamspeak-server/
rm -f ~/ts3server.tar.bz*
rm -rf teamspeak3-server_linux_amd64
echo "${RELEASE}" >~/.teamspeak-server
$STD service teamspeak start
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}${IP}:9987${CL}"
-62
View File
@@ -1,62 +0,0 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021) | Co-Author: Stavros (steveiliop56)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/steveiliop56/tinyauth
APP="Alpine-Tinyauth"
var_tags="${var_tags:-alpine;auth}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-2}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if [[ ! -d /opt/tinyauth ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating packages"
$STD apk -U upgrade
msg_ok "Updated packages"
RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [ "${RELEASE}" != "$(cat ~/.tinyauth 2>/dev/null)" ] || [ ! -f ~/.tinyauth ]; then
msg_info "Stopping Service"
$STD service tinyauth stop
msg_ok "Service Stopped"
msg_info "Updating Tinyauth"
rm -f /opt/tinyauth/tinyauth
curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth
chmod +x /opt/tinyauth/tinyauth
echo "${RELEASE}" >~/.tinyauth
msg_ok "Updated Tinyauth"
msg_info "Restarting Tinyauth"
$STD service tinyauth start
msg_ok "Restarted Tinyauth"
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
-42
View File
@@ -1,42 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://alpinelinux.org/
APP="Alpine-Traefik"
var_tags="${var_tags:-os;alpine}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating traefik from edge"
$STD apk add traefik --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
msg_ok "Updated traefik"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} WebUI Access (if configured) - using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080/dashboard${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://transmissionbt.com/
APP="Alpine-Transmission"
var_tags="${var_tags:-alpine;torrent}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "Updating Transmission"
$STD apk upgrade transmission-daemon
msg_ok "Updated Transmission"
msg_info "Restarting Transmission"
$STD rc-service transmission-daemon restart
msg_ok "Restarted Transmission"
msg_ok "Updated successfully!"
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9091${CL}"
-69
View File
@@ -1,69 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/dani-garcia/vaultwarden
APP="Alpine-Vaultwarden"
var_tags="${var_tags:-alpine;vault}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 2 \
"1" "Update Vaultwarden" \
"2" "Reset ADMIN_TOKEN" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
$STD apk -U upgrade
rc-service vaultwarden restart -q
exit
;;
2)
if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then
if [[ -z "$NEWTOKEN" ]]; then exit-script; fi
if ! command -v argon2 >/dev/null 2>&1; then apk add argon2 &>/dev/null; fi
TOKEN=$(echo -n "${NEWTOKEN}" | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1)
if [[ ! -f /var/lib/vaultwarden/config.json ]]; then
sed -i "s|export ADMIN_TOKEN=.*|export ADMIN_TOKEN='${TOKEN}'|" /etc/conf.d/vaultwarden
else
sed -i "s|\"admin_token\": .*|\"admin_token\": \"${TOKEN}\",|" /var/lib/vaultwarden/config.json
fi
rc-service vaultwarden restart -q
fi
clear
exit
;;
esac
done
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${APP} should be reachable by going to the following URL.
${BL}https://${IP}:8000${CL} \n"
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.wireguard.com/
APP="Alpine-Wireguard"
var_tags="${var_tags:-alpine;vpn}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
var_tun="${var_tun:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
msg_info "update wireguard-tools"
$STD apk add --no-cache --upgrade wireguard-tools
msg_ok "wireguard-tools updated"
if [[ -d /etc/wgdashboard/src ]]; then
msg_info "update WGDashboard"
cd /etc/wgdashboard/src
echo "y" | ./wgd.sh update >/dev/null 2>&1
$STD ./wgd.sh start
msg_ok "WGDashboard updated"
fi
exit 0
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} WGDashboard Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:10086${CL}"
-50
View File
@@ -1,50 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.zigbee2mqtt.io/
APP="Alpine-Zigbee2MQTT"
var_tags="${var_tags:-alpine;zigbee;mqtt;smarthome}"
var_disk="${var_disk:-1}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-0}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \
"1" "Check for Zigbee2MQTT Updates" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
$STD apk -U upgrade
exit
;;
esac
done
}
start
build_container
description
msg_ok "Completed Successfully!\n"
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://alpinelinux.org/
APP="Alpine"
var_tags="${var_tags:-os;alpine}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.22}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
UPD=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \
"1" "Check for Alpine Updates" ON \
3>&1 1>&2 2>&3
)
header_info
if [ "$UPD" == "1" ]; then
$STD apk -U upgrade
msg_ok "Updated successfully!"
exit 0
fi
}
start
build_container
description
msg_ok "Completed Successfully!\n"
-39
View File
@@ -1,39 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://cassandra.apache.org/_/index.html
APP="Apache-Cassandra"
var_tags="${var_tags:-database;NoSQL}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/cassandra.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://couchdb.apache.org/
APP="Apache-CouchDB"
var_tags="${var_tags:-database}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/couchdb.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5984/_utils/${CL}"
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: | MIT https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://guacamole.apache.org/
APP="Apache-Guacamole"
var_tags="${var_tags:-webserver;remote}"
var_disk="${var_disk:-4}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/apache-guacamole ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080/guacamole${CL}"
-64
View File
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Andy Grunwald (andygrunwald)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/apache/tika/
APP="Apache-Tika"
var_tags="${var_tags:-document}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/apache-tika.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE="$(curl -fsSL https://dlcdn.apache.org/tika/ | grep -oP '(?<=href=")[0-9]+\.[0-9]+\.[0-9]+(?=/")' | sort -V | tail -n1)"
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Stopping Service"
systemctl stop apache-tika
msg_ok "Stopped Service"
msg_info "Updating ${APP} to v${RELEASE}"
cd /opt/apache-tika
curl -fsSL -o tika-server-standard-${RELEASE}.jar "https://dlcdn.apache.org/tika/${RELEASE}/tika-server-standard-${RELEASE}.jar"
mv --force tika-server-standard.jar tika-server-standard-prev-version.jar
mv tika-server-standard-${RELEASE}.jar tika-server-standard.jar
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to v${RELEASE}"
msg_info "Starting Service"
systemctl start apache-tika
msg_ok "Started Service"
msg_info "Cleaning Up"
rm -rf /opt/apache-tika/tika-server-standard-prev-version.jar
msg_ok "Cleanup Completed"
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9998${CL}"
-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (Canbiz)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://tomcat.apache.org/
APP="Apache-Tomcat"
var_tags="${var_tags:-webserver}"
var_disk="${var_disk:-5}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if ! ls -d /opt/tomcat-* >/dev/null 2>&1; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://wiki.debian.org/AptCacherNg
APP="Apt-Cacher-NG"
var_tags="${var_tags:-caching}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /var ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating $APP LXC"
$STD apt-get update
$STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3142/acng-report.html${CL}"
Loaded 100 of 2033 files, more files were not shown because too many files have changed in this diff. Show more