caprover / caprover-cli

Command Line Interface for https://github.com/caprover/caprover
72 stars 40 forks source link

Create new app via API call: what is "detached"? plus other questions... #55

Closed drmrbrewer closed 4 years ago

drmrbrewer commented 4 years ago

I'm trying to create a new app via the CLI (or rather in a script), and see that I need to use a custom api call, as explained here and here.

When looking here for the right parameters to pass, I think it is the registerNewApp() method that is relevant. But what does the detached query string part mean?

What I have so far is:

CAPROVER_PWD="notmypassword"
CAPROVER_ROOT_DOMAIN="myserver.domain.com"
CAPROVER_API_PATH="/user/apps/appDefinitions/register"
CAPROVER_API_METHOD="POST"
CAPROVER_APP_NAME="mynewapp"
CAPROVER_API_DATA="{\"appName\":\"${CAPROVER_APP_NAME}\",\"hasPersistentData\":true}"
caprover api --caproverUrl "https://captain.${CAPROVER_ROOT_DOMAIN}" --caproverPassword "${CAPROVER_PWD}" --path "${CAPROVER_API_PATH}" --method "${CAPROVER_API_METHOD}" --data "${CAPROVER_API_DATA}"

Is the above correct so far, and does the path need to include ?detached=1?

The app I am trying to create has persistent data... I'm specifying that already above via the data argument.

But the app also needs:

How do I set those up via the caprover api call?

githubsaturn commented 4 years ago

detached means that the HTTP call returns as soon as CapRover engines receives the http call. Not passing detached causes the HTTP call to wait until the app is successfully created and setup before returning the HTTP call.

Clicking on Update and Save calls this method: https://github.com/caprover/caprover-frontend/blob/5e9eede7b19478fe5542262dc52150ab18b4d66c/src/api/ApiManager.ts#L178-L218

All of the updates you want to perform are in this method.

drmrbrewer commented 4 years ago

According to this:

Note: It will not be possible to carry through with the 'caprover serversetup' if you've already forced https on your CapRover instance. In such case go straight to logging in with the caprover login command. To change the password go to the settings menu in the app.

In my case the default .htaccess does indeed redirect all http to https. So it's not possible to run caprover serversetup? Why is that? It doesn't seem to have been a problem for me before. When I'm trying now, the first call of caprover serversetup --assumeYes --configFile config.json results in an error (html basically saying "nothing here yet"), but the second call of the same command does seem to set up the server OK.

And when creating an app, I'm trying to pass the whole config via a json file with caprover api --configFile myconfig.json, where myconfig.json is:

{
    "data": {
        "appName": "...",
        "hasPersistentData": true,
        "envVars": [
            {
                "key": "abc",
                "value": "def"
            },
            {
                "key": "ghi",
                "value": "jkl"
            }
        ],
        "ports": [
            {
                "hostPort": 8080,
                "containerPort": 8080
            }
        ]
    },
    "caproverUrl": "...",
    "caproverPassword": "...",
    "path": "/user/apps/appDefinitions/register",
    "method": "POST"
}

This creates the app OK, with persistent data checked, but it doesn't add the env vars and ports. What am I doing wrong?

githubsaturn commented 4 years ago

Two separate things here:

1- .htaccess ?? What is this for? CapRover doesn't use apache.

2- Regarding the api call: you cannot register the app and update the configs in one go. You have to first register the app. Wait a big and then update your config through calling user/apps/appDefinitions/update as mentioned in my comment above.

drmrbrewer commented 4 years ago
  1. how true. I have no idea what is redirecting http to https then (type 302 redirect). DNS for this domain is handled by cloudflare, and "always use https" is definitely off. And when I run serversetup, why does the message "Enabling SSL..." show? I haven't done anything explicitly to enable SSL: image. I'm also getting letsencrypt error messages now about too many attempts to create ssl cert for this captain domain... despite never having knowingly tried to enable ssl.

  2. OK thanks.

githubsaturn commented 4 years ago

Try using a different root domain.

Also try experimenting to see if the issue is happening when you setup your server manually as well - or it's only happening when you're using the config file.

drmrbrewer commented 4 years ago

I now see why letsencrypt was setting up a certificate... I am of course passing an email via --certificateEmail, and this is a required parameter so I can't not. So it seems that https is mandatory on the caprover console.

try using a different root domain

I think that helped, but having done more attempts I'm not so sure, because I seem to get an error when I run serversetup for the first time on any root domain... or maybe different ones under the same domain (e.g. one.mydomain.com vs two.mydomain.com vs one.anotherdomain.com). See point (3) below.

Remaining questions:

(1) after doing caprover serversetup (and before each subsequent caprover api call), it seems that I need to caprover logout, or else it complains. It's not a big deal, but is there a way of avoiding this, and just taking the login credentials passed with the api call, without forcing a logout?

(2) usually I enable https on all apps that I create, but there doesn't seem to be a parameter for this in the update path? There is a forceSsl parameter but I assume that relates to the Force HTTPS by redirecting all HTTP traffic to HTTPS option on the app page rather than the Enable HTTPS button? Is there any way of enabling https on the app via the api call?

(3) is there any way of making this work for the same root domain again, even soon after the previous attempt? I am finding that if I try to use the same root domain again (or maybe even the same main domain but different sub-domain e.g. one.mydomain.com vs two.mydomain.com), I get an error the first time I call serversetup but if I run the same command again, it works.

So, when I delete the host server and spin up a new one, now when I run caprover serversetup first time I get:

# caprover serversetup --assumeYes --caproverIP "xx.yyy.zzz.aa" --caproverPassword "captain42" --caproverRootDomain "server.domain.com" --newPassword "mypassword" --certificateEmail "me@domain.com" --caproverName "greatname"

Setup CapRover machine on your server...

✖ Enabling SSL... Takes a few seconds...

Error: StatusCodeError: 404 - "<!doctype html>\n<html>\n\n<head>\n    <meta charset=utf-8>\n    <meta content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\" name=viewport>\n    <title>Powered by CapRover</title>\n    <style>\n        html,\n        body {\n            font-family: sans-serif;\n            -ms-text-size-adjust: 100%;\n            -webkit-text-size-adjust: 100%;\n            background-color: #F7F8FB;\n            height: 100%;\n            -webkit-font-smoothing: antialiased;\n        }\n\n        body {\n            margin: 0;\n            padding: 0;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n        }\n\n        .message {\n            text-align: center;\n            align-self: center;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            padding: 20px;\n            max-width: 550px;\n        }\n\n        .message__title {\n            font-size: 32px;\n            font-weight: 100;\n            margin-top: 15px;\n            color: #47494E;\n            margin-bottom: 8px;\n        }\n\n        .btn {\n            text-decoration: none;\n            padding: 11px 25px;\n            border-radius: 11px;\n            margin-top: 110px;\n            font-size: 19px;\n            color: #7F828B;\n        }\n\n        body.defaultpagebody {\n            background: -webkit-linear-gradient(-45deg, #1d5b85 0%, #3295c7 100%);\n            background: linear-gradient(135deg, #1d5b85 0%, #3295c7 100%);\n        }\n\n        .message__title {\n            color: #fff;\n        }\n\n        .message {\n            padding: 25px;\n            color: #fff;\n        }\n\n        body.defaultpagebody p {\n            color: rgba(255, 255, 255, 0.6);\n        }\n\n        body.defaultpagebody .info {\n            fill: rgba(255, 255, 255, 0.9);\n        }\n\n        body.defaultpagebody .btn {\n            color: #fff;\n            border: 2px solid rgba(255, 255, 255, 0.7);\n        }\n    </style>\n    <base target=_parent />\n</head>\n\n<body class=defaultpagebody>\n    <div class=message>\n        <div class=message__title>\n            Nothing here yet :/\n        </div>\n        <div class=message>\n            \n        </div>\n        <a href=\"https://caprover.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"btn\">\n            Read Docs</a>\n    </div>\n</body>\n\n</html>"

And yes, I did give it plenty of time before running this, despite the Nothing here yet message in the above html.

Another time I saw:

Setup CapRover machine on your server...

- Enabling SSL... Takes a few seconds...
✖ Enabling SSL... Takes a few seconds...

Error Code: 1000  Message: Another operation is in process for Certbot. Please wait a few seconds and try again.

But when I run the very same serversetup command again immediately, it goes fine:

Setup CapRover machine on your server...

CapRover server setup completed: it is available as greatname at https://captain.server.domain.com

For more details and docs see CapRover.com

So in my script I just run the serversetup twice, leaving a time gap in between, and it seems to work reliably.

Any idea why? Something to do with having set up ssl the previous time messing up the next time, even for e.g. one.mydomain.com and then two.mydomain.com? Why does it work second time? Any way avoiding this error completely, without the workaround of calling the setup command twice?

githubsaturn commented 4 years ago

(1) after doing caprover serversetup (and before each subsequent caprover api call), it seems that I need to caprover logout, or else it complains. It's not a big deal, but is there a way of avoiding this, and just taking the login credentials passed with the api call, without forcing a logout?

What is the error message? And what are the steps to repro the isse?

(2) usually I enable https on all apps that I create, but there doesn't seem to be a parameter for this in the update path? There is a forceSsl parameter but I assume that relates to the Force HTTPS by redirecting all HTTP traffic to HTTPS option on the app page rather than the Enable HTTPS button? Is there any way of enabling https on the app via the api call?

There is enableSslForCustomDomain and enableSslForBaseDomain in the ApiManager class. All API calls are available there.

Regarding your 3rd issue: It's not very clear to me how you're getting into that state. Basically what you're seeing should be applicable to "all serversetup calls". When you're using a different subdomain, it's a completely different domain in CapRover's view. Does the issue happen for a new domain as well? i.e. when:

Is there any change you're recycling your old IP and you have a caching layer in the middle?

drmrbrewer commented 4 years ago

Re (1):

What is the error message? And what are the steps to repro the isse?

Actually it seems to be an info message and not an error message:

# caprover serversetup --assumeYes --configFile config-server.json 
...
# caprover api --configFile config-app-register.json

Call generic CapRover API [Experimental Feature]...

Ensuring authentication...

Can't store store login credentials: https://captain.abc.mydomain.com already exist as abc in your currently logged in machines. If you want to replace the existing entry, you have to first use <logout> command, and then re-login.

API call completed successfully!

{}

So actually it seems that the call completes, so I can probably just ignore the message.

Re (2): thanks, I'll have a look at those.

Re (3):

Does the issue happen for a new domain as well?

It seems to work the first time for a new domain (rather than subdomain), but for subsequent server setups (even with a different subdomain name) the issue happens again.

Is there any change you're recycling your old IP and you have a caching layer in the middle?

Hmm, it's possible I suppose. Well it definitely is the case that the cloud server provider keeps re-allocating the same IP address to me, each time I spin up a new server (at least for today). DNS is handled by cloudflare, but the DNS entry is set to "DNS only" (not "Proxied") so I don't think there is any caching going on as such. But I suppose that re-using the IP for the new server might still cause its own issues. I would understand if it required a certain length of time to propagate, but the issue is solved by running caprover serversetup twice, rather than waiting any length of time.

githubsaturn commented 4 years ago

Your setup is a bit complex, but basically what you're describing could be reproducible by simply wiping the CapRover server and reinstalling CapRover. This is the steps that are equivalent to what you're doing:

Can you confirm if the issue is reproducible via running through these steps. If so, let's create a new issue with these exact repro steps and I'll look into it

drmrbrewer commented 4 years ago

After "remove and re-install CapRover", before running caprover serversetup using the same config file I have to caprover logout, but other than that, yes, the above steps do get me to the 404 error again.