docker / app

Make your Docker Compose applications reusable, and share them on Docker Hub
Apache License 2.0
1.58k stars 177 forks source link

Installed apps show up as stacks #645

Open thaJeztah opened 4 years ago

thaJeztah commented 4 years ago

Apps that were installed with docker app install show up both as app, and as stack;

docker app ls
INSTALLATION   APPLICATION        LAST ACTION RESULT  CREATED    MODIFIED  REFERENCE
myinstallation myotherapp (0.1.0) upgrade     success 12 minutes 8 minutes 

docker stack ls
NAME                SERVICES            ORCHESTRATOR
myinstallation      1                   Swarm
mystack             1                   Swarm

Do we want stacks and apps to work in the same "namespace"? Or should we prevent users from interacting with apps through docker stack xxx commands (and vice-versa)?

I guess there's two possible angles;

  1. apps and stacks are separate things
  2. apps and stacks form a hierarchy; an app consists of 1 (or perhaps in future more than 1) stacks (and stacks consist of 1 or more services, volumes, etc.)

If 2., then stacks that are part of an app should likely show up under docker stack ls, but we should think how users can/are allows to interact with them.

I think in both cases, we should add additional metadata/labels to (both stacks, and) apps so that we can distinguish apps from stacks, allowing use to filter and/or provide info about the stack/app separate from the local storage in ~/.docker/apps.

thaJeztah commented 4 years ago

Note that adding additional metadata/labels to the deployed apps would also help with https://github.com/docker/app/issues/604

Looking at the information stored (~/.docker/app/installations/37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f/myinstallation.json)

From the myinstallation.json (shown below, collapsed);

```json { "name": "myinstallation", "revision": "01DNS4S9HPYSTS1FCG77WVJCXT", "created": "2019-09-27T12:34:06.685081+02:00", "modified": "2019-09-27T12:38:08.950407+02:00", "bundle": { "name": "myotherapp", "version": "0.1.0", "description": "", "maintainers": [ { "name": "sebastiaan", "email": "sebastiaan@docker.com" } ], "invocationImages": [ { "imageType": "docker", "image": "myotherapp:0.1.0-invoc" } ], "images": { "hello": { "imageType": "docker", "image": "hashicorp/http-echo", "description": "hashicorp/http-echo" } }, "actions": { "com.docker.app.inspect": { "stateless": true }, "com.docker.app.render": { "stateless": true }, "com.docker.app.status": {} }, "parameters": { "com.docker.app.kubernetes-namespace": { "type": "string", "default": "", "metadata": { "description": "Namespace in which to deploy" }, "destination": { "env": "DOCKER_KUBERNETES_NAMESPACE" }, "apply-to": [ "install", "upgrade", "uninstall", "com.docker.app.status" ] }, "com.docker.app.orchestrator": { "type": "string", "default": "", "allowedValues": [ "", "swarm", "kubernetes" ], "metadata": { "description": "Orchestrator on which to deploy" }, "destination": { "env": "DOCKER_STACK_ORCHESTRATOR" }, "apply-to": [ "install", "upgrade", "uninstall", "com.docker.app.status" ] }, "com.docker.app.render-format": { "type": "string", "default": "yaml", "allowedValues": [ "yaml", "json" ], "metadata": { "description": "Output format for the render command" }, "destination": { "env": "DOCKER_RENDER_FORMAT" }, "apply-to": [ "com.docker.app.render" ] }, "com.docker.app.share-registry-creds": { "type": "bool", "default": false, "metadata": { "description": "Share registry credentials with the invocation image" }, "destination": { "env": "DOCKER_SHARE_REGISTRY_CREDS" } }, "hello.port": { "type": "string", "default": "8080", "destination": { "env": "docker_param1" } }, "hello.text": { "type": "string", "default": "Hello myotherapp!", "destination": { "env": "docker_param2" } } }, "credentials": { "com.docker.app.registry-creds": { "path": "/cnab/app/registry-creds.json" }, "docker.context": { "path": "/cnab/app/context.dockercontext" } } }, "result": { "message": "", "action": "upgrade", "status": "success" }, "parameters": { "com.docker.app.kubernetes-namespace": "default", "com.docker.app.orchestrator": "", "com.docker.app.render-format": "yaml", "com.docker.app.share-registry-creds": false, "hello.port": "8080", "hello.text": "Hello myapp!" }, "files": null } ```

Possibly;

thaJeztah commented 4 years ago

/cc @chris-crone @silvin-lubecki

thaJeztah commented 4 years ago

Hm, actually, looks like the 37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f is not an ID (or at least, the same ID is created when re-deploying the application after removing the local store); is it a hash of the name, not a UUID/random ID?

thaJeztah commented 4 years ago

So, looks like interacting through docker stack is indeed problematic, because docker app currently relies on the local store;

$ docker stack rm myinstallation
Removing service myinstallation_hello
Removing network myinstallation_default

$ docker app ls
INSTALLATION   APPLICATION        LAST ACTION RESULT  CREATED   MODIFIED       REFERENCE
myinstallation myotherapp (0.1.0) upgrade     success 7 minutes About a minute 

$ docker app status myinstallation
INSTALLATION
------------
Name:         myinstallation
Created:      10 minutes
Modified:     4 minutes
Revision:     01DNS7WG2EJP1Q1KTM1DATP5SD
Last Action:  upgrade
Result:       SUCCESS
Orchestrator: swarm

APPLICATION
-----------
Name:      myotherapp
Version:   0.1.0
Reference: 

PARAMETERS
----------
hello.port: 8080
hello.text: Hello myapp!

STATUS
------
silvin-lubecki commented 4 years ago

@thaJeztah your last result is weird, status should have failed, not being able to reach the rmed stack.

silvin-lubecki commented 4 years ago

37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f could be stored as ID (e.g. com.docker.app.id)

Actually 37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f is the id of the installation context šŸ˜… The installation store is split by context ids, and inside you will find all the named installations.

thaJeztah commented 4 years ago

Ah! Gotcha šŸ‘ Guess having a GUID stored somewhere would work for IDs

kinghuang commented 4 years ago

At a high level, I like the idea of 2 where an app consists of one or more stacks. But, I feel that might lead to confusion about apps vs stacks.

I think labeling app-based deployments so that existing stack/service commands can work with them would ease adoption, and make them interoperable with third-party tools like Portainer out of the box.

Perhaps a bigger gain for apps and stacks as a whole would be to create a resource type and APIs for it (as a combined entity). Right now, there is no actual stack resource in the Docker API. The concept of stacks only exist in the Docker CLI. A new resource type could hold the information that's currently being stored locally in ~/.docker/app/installations/, and finally provide an API that external tools can use.