Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content

Feature Requests

New ideas, Feature Requests

659 Topics 5.1k Posts
  • [Mail] Offer complete Autodiscover (Outlook)

    1
    1 Votes
    1 Posts
    14 Views
    No one has replied
  • 2 Votes
    8 Posts
    191 Views
    dsp76D

    Yes, randomly the WordPress Dev instance is crashing on the well powered system, while it was running on a native vServer stable before. The application log is not telling much about the reason - how can I see the Apache log for instance? I read https://docs.cloudron.io/packaging/cheat-sheet/#logging but have trouble understanding it, @girish

  • Read only mysql access in cloudron - possible?

    Moved
    6
    0 Votes
    6 Posts
    60 Views
    nebulonN

    You should be able to create such a user if you operate with the mysql admin credentials which exist in the mysql service container. You can get a terminal into that via docker exec -ti mysql /bin/bash in an SSH session to the host system. However probably don't play around with this in a production system for a start.

  • 0 Votes
    3 Posts
    36 Views
    J

    @nebulon Just the log. I need to be able to prove, that a certain mail is send or received. Another cool thing would be to add the time column of the log to the search function. So that if I type the date in the search, I can also search for the date.

  • [Mail] Single address relay

    1
    0 Votes
    1 Posts
    29 Views
    No one has replied
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • Add Filebase as Backup

    10
    5 Votes
    10 Posts
    689 Views
    girishG

    I split storj as a separate request to https://forum.cloudron.io/topic/11670/add-storj-as-backup-option

  • Implement a Down for Maintenance screen

    10
    8 Votes
    10 Posts
    414 Views
    LanhildL

    What about a "Turn on maitenance mode" like @girish suggested, but you'd be able to specify which page from the /home/yellowtent/boxdata/custom_pages you want displayed. This would allow a lot more flexibility and even let you have app-specific maintenance pages that you made beforehand.

  • 3 Votes
    11 Posts
    119 Views
    E

    Yes, I know that failed backup notifications are already raised in the dashboard, but that requires me to go and look there. I have a mission-critical app that should update every day and I literally had the case that while I was on vacation, it failed one day. Nothing happened, it backed up the next day, but I simply didn't look into the dashboard that day like usually.

    That's where the feature request is coming from.

  • proxyAuth for any app

    1
    0 Votes
    1 Posts
    23 Views
    No one has replied
  • add deSEC as DNS Provider

    Solved
    10
    4 Votes
    10 Posts
    341 Views
    H

    @girish said in add deSEC as DNS Provider:

    deSEC integration is implemented for next release.

    That is the best message of the day. Thank you!

  • Email forwarding for active mailbox

    1
    3 Votes
    1 Posts
    45 Views
    No one has replied
  • 1 Votes
    3 Posts
    115 Views
    M

    Out of curiosity I've built what @luckow suggested, only with Cloudron API (notifications endpoint) -> n8n -> some magic -> ntfy.sh-app and it looks like this:

    f036453c-4190-48d2-bae2-33c5e16133b5-image.png

    Action gets triggered (either automatically or manually), n8n checks the cloudron api https://my.example1.com/api/v1/notifications (create a readonly access token in your profile and update the Bearer token with it) with the parameters acknowledged = false, so only unread notifications are collected.

    The code-node does the following (filteredTitles because I don't care about app-updates, only actual issues, can be adjusted of course):

    const notifications = items[0].json.notifications; const types = notifications.map(notification => notification.type); const titles = notifications.map(notification => notification.title); // Filter notifications to remove those with type "appUpdated" const filteredNotifications = notifications.filter(notification => notification.type != "appUpdated"); // Extract titles of the filtered notifications const filteredTitles = filteredNotifications.map(notification => notification.title); //return [{ json: { types, titles } }]; return [{ json: { filteredTitles } }];

    This will result in an array of current notifications, e.g.

    [ { "filteredTitles": [ "Email is not configured properly", "The app at cms.example.com ran out of memory." ] } ] The if-node checks if there's actual content. If it's empty, nothing will happen, if it's not, it will make a http request to your nfty instance and topic of your choice (saved credentials in n8n) and send the notifications:

    2ae64242-ff94-44d3-843d-fb0154436eed-image.png

    Since I was working with readonly tokens, I had no intentions of marking the notifications as read after sending out the message. So there's room for improvement, but I thought I would throw it in here as a PoC 🙂

    Complete code (My_Cloudron_workflow.json) is here:

    { "name": "My Cloudron workflow", "nodes": [ { "parameters": {}, "id": "0dcf1d60-f8e7-4ffe-be14-64399a5c924d", "name": "When clicking \"Test workflow\"", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ 240, 620 ] }, { "parameters": { "url": "https://my.example1.com/api/v1/notifications", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "acknowledged", "value": "false" } ] }, "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer 123" } ] }, "sendBody": true, "bodyParameters": { "parameters": [ {} ] }, "options": {} }, "id": "073de174-b658-480e-bb3c-6be103304bd9", "name": "EX1", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 460, 620 ], "alwaysOutputData": false }, { "parameters": { "url": "https://my.example2.com/api/v1/notifications", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "acknowledged", "value": "false" } ] }, "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer 456" } ] }, "sendBody": true, "bodyParameters": { "parameters": [ {} ] }, "options": {} }, "id": "c29eae02-51b5-417c-a103-d35b4bcb15e8", "name": "EX2", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 460, 780 ], "alwaysOutputData": false }, { "parameters": { "url": "https://my.example3.com/api/v1/notifications", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "acknowledged", "value": "false" } ] }, "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer 789" } ] }, "sendBody": true, "bodyParameters": { "parameters": [ {} ] }, "options": {} }, "id": "a00d01ae-fca9-41e8-b16f-3456459f414a", "name": "EX3", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 460, 460 ], "alwaysOutputData": false }, { "parameters": { "jsCode": "const notifications = items[0].json.notifications;\nconst types = notifications.map(notification => notification.type);\nconst titles = notifications.map(notification => notification.title);\n\n// Filter notifications to remove those with type \"appUpdated\"\nconst filteredNotifications = notifications.filter(notification => notification.type != \"appUpdated\");\n\n// Extract titles of the filtered notifications\nconst filteredTitles = filteredNotifications.map(notification => notification.title);\n\n//return [{ json: { types, titles } }];\nreturn [{ json: { filteredTitles } }];" }, "id": "fb776916-d0d4-46b6-8a7d-7de5694e650c", "name": "Code", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 620, 460 ] }, { "parameters": { "jsCode": "const notifications = items[0].json.notifications;\nconst types = notifications.map(notification => notification.type);\nconst titles = notifications.map(notification => notification.title);\n\n// Filter notifications to remove those with type \"appUpdated\"\nconst filteredNotifications = notifications.filter(notification => notification.type != \"appUpdated\");\n\n// Extract titles of the filtered notifications\nconst filteredTitles = filteredNotifications.map(notification => notification.title);\n\n//return [{ json: { types, titles } }];\nreturn [{ json: { filteredTitles } }];" }, "id": "968f2566-7983-46ef-b14a-3677a3a6fc88", "name": "Code1", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 620, 620 ] }, { "parameters": { "jsCode": "const notifications = items[0].json.notifications;\nconst types = notifications.map(notification => notification.type);\nconst titles = notifications.map(notification => notification.title);\n\n// Filter notifications to remove those with type \"appUpdated\"\nconst filteredNotifications = notifications.filter(notification => notification.type != \"appUpdated\");\n\n// Extract titles of the filtered notifications\nconst filteredTitles = filteredNotifications.map(notification => notification.title);\n\n//return [{ json: { types, titles } }];\nreturn [{ json: { filteredTitles } }];" }, "id": "5463ace4-ed1f-408a-a13c-a153fbda2ca3", "name": "Code2", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 620, 780 ] }, { "parameters": { "method": "POST", "url": "https://ntfy.nftyserver.com/cloudron-notifications", "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Title", "value": "Current example3.com notifications" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "Title", "body": "={{ $json.filteredTitles.join(\"\\n\"); }}", "options": {} }, "id": "83bc0ca8-d7e1-4fb5-8dd9-0b3360f6763e", "name": "HTTP Request", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 940, 460 ], "credentials": { "httpBasicAuth": { "id": "5tUu1DjoNUxl0M5a", "name": "ntfy token" } } }, { "parameters": { "method": "POST", "url": "https://ntfy.nftyserver.com/cloudron-notifications", "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Title", "value": "Current example1.com notifications" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "Title", "body": "={{ $json.filteredTitles.join(\"\\n\"); }}", "options": {} }, "id": "92815612-9381-444f-86b5-7c3c3cf8a371", "name": "HTTP Request1", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 940, 620 ], "credentials": { "httpBasicAuth": { "id": "5tUu1DjoNUxl0M5a", "name": "ntfy token" } } }, { "parameters": { "method": "POST", "url": "https://ntfy.nftyserver.com/cloudron-notifications", "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Title", "value": "Current example2.com notifications" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "Title", "body": "={{ $json.filteredTitles.join(\"\\n\"); }}", "options": {} }, "id": "bc221e4f-8817-4c19-a74d-9333a4783319", "name": "HTTP Request2", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 940, 780 ], "credentials": { "httpBasicAuth": { "id": "5tUu1DjoNUxl0M5a", "name": "ntfy token" } } }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "43482a2f-b2b0-4f0a-b970-7b11e8f6ee03", "leftValue": "={{ $json.filteredTitles }}", "rightValue": "", "operator": { "type": "array", "operation": "notEmpty", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "af3ebb14-32db-4afb-8c9d-84eb593eae96", "name": "If1", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [ 780, 620 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "1811bb6f-55ca-4b2d-9f6b-97c489ef4d21", "leftValue": "={{ $json.filteredTitles }}", "rightValue": "", "operator": { "type": "array", "operation": "notEmpty", "singleValue": true } } ], "combinator": "or" }, "options": {} }, "id": "e354d631-5daf-495d-a5e2-e0fb64ef212d", "name": "If2", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [ 780, 780 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "43482a2f-b2b0-4f0a-b970-7b11e8f6ee03", "leftValue": "={{ $json.filteredTitles }}", "rightValue": "", "operator": { "type": "array", "operation": "notEmpty", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "a3fc1a27-f94d-4651-884f-34c683b0a2da", "name": "If", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [ 780, 460 ] } ], "pinData": {}, "connections": { "When clicking \"Test workflow\"": { "main": [ [ { "node": "EX1", "type": "main", "index": 0 }, { "node": "EX2", "type": "main", "index": 0 }, { "node": "EX3", "type": "main", "index": 0 } ] ] }, "EX1": { "main": [ [ { "node": "Code1", "type": "main", "index": 0 } ] ] }, "EX2": { "main": [ [ { "node": "Code2", "type": "main", "index": 0 } ] ] }, "EX3": { "main": [ [ { "node": "Code", "type": "main", "index": 0 } ] ] }, "Code1": { "main": [ [ { "node": "If1", "type": "main", "index": 0 } ] ] }, "Code2": { "main": [ [ { "node": "If2", "type": "main", "index": 0 } ] ] }, "Code": { "main": [ [ { "node": "If", "type": "main", "index": 0 } ] ] }, "If1": { "main": [ [ { "node": "HTTP Request1", "type": "main", "index": 0 } ] ] }, "If2": { "main": [ [ { "node": "HTTP Request2", "type": "main", "index": 0 } ] ] }, "If": { "main": [ [ { "node": "HTTP Request", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1" }, "versionId": "b1689af0-81c6-453c-a8aa-1d7c84d7a85e", "meta": { "templateCredsSetupCompleted": true, "instanceId": "8903125d64295093a384f52f480a1738308c71ada8db56c53efba4894aefbff2" }, "id": "I2Mq9Y8GOPIDIh8i", "tags": [] }

    I threw out a module last minute, so hopefully no oversights in there. Improvements are welcome! 😉

    TL;DR: Adjust the URLs to your Cloudrons, create and add readonly tokens, add a ntfy token to your n8n credentials and adjust the URL to your ntfy instance.

  • 5 Votes
    5 Posts
    112 Views
    L

    I would like to be able to leave a note alongside a particular application backup, too.

  • Add a Text Field notes per apps

    Locked Solved
    2
    2 Votes
    2 Posts
    35 Views
    girishG

    @jrl-abstract27 Dup of https://forum.cloudron.io/topic/11559/possibility-to-add-app-notes-for-admins-operators-users/ .

    We have already implemented this for next release. Feel free to comment in the other thread, please.

  • Branding Limitations

    6
    8 Votes
    6 Posts
    425 Views
    girishG

    For the last point about the "Login with Cloudron" button in apps, we have introduced a new environment variable (just last week) in next release - https://git.cloudron.io/cloudron/box/-/commit/daa8a60da282fc3c8bbccd4b2b1a4920c2b06812 . After the release, we have to adjust the apps to use the text in the environment variable. And then, Branding view will set that variable.

  • WebFinger support for OIDC

    Moved Solved
    7
    2 Votes
    7 Posts
    201 Views
    M

    Never mind, my misunderstanding. I was able to use the wordpress-plugin "webfinger" on my main domain and just put in the my.<domain>-issuer-URL into the response, works fine!

  • LDAP for Discourse (and NodeBB)

    Solved
    4
    5 Votes
    4 Posts
    412 Views
    girishG

    Discourse has OIDC by now. NodeBB has no "supported" plugin, this has to be opened upstream.

  • 10 Votes
    4 Posts
    291 Views
    girishG

    Let's continue at https://forum.cloudron.io/topic/6195/granular-per-app-backup-schedules

  • Add INWX as DNS provider

    7
    5 Votes
    7 Posts
    238 Views
    BushidoB

    They are inexpensive but also professional. Changes to the name servers are implemented in seconds. I have had negative experiences with Netcup, for example, where changes took hours. You can also create multiple domain contacts and assign domains to your customers.