{"action":"created","issue":{"url":"https://api.github.com/repos/progrium/dokku/issues/854","labels_url":"https://api.github.com/repos/progrium/dokku/issues/854/labels{/name}","comments_url":"https://api.github.com/repos/progrium/dokku/issues/854/comments","events_url":"https://api.github.com/repos/progrium/dokku/issues/854/events","html_url":"https://github.com/progrium/dokku/issues/854","id":53151148,"number":854,"title":"Proposal for a common attached-services concept","user":{"login":"miraculixx","id":859611,"avatar_url":"https://avatars.githubusercontent.com/u/859611?v=3","gravatar_id":"","url":"https://api.github.com/users/miraculixx","html_url":"https://github.com/miraculixx","followers_url":"https://api.github.com/users/miraculixx/followers","following_url":"https://api.github.com/users/miraculixx/following{/other_user}","gists_url":"https://api.github.com/users/miraculixx/gists{/gist_id}","starred_url":"https://api.github.com/users/miraculixx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miraculixx/subscriptions","organizations_url":"https://api.github.com/users/miraculixx/orgs","repos_url":"https://api.github.com/users/miraculixx/repos","events_url":"https://api.github.com/users/miraculixx/events{/privacy}","received_events_url":"https://api.github.com/users/miraculixx/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/progrium/dokku/labels/rfc","name":"rfc","color":"5319e7"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":23,"created_at":"2014-12-30T22:05:35Z","updated_at":"2015-09-19T09:58:03Z","closed_at":"2015-08-25T16:47:50Z","body":"I'm not sure proposals like this are warranted, so please let me know if not. This is born out of the observation (and some frustration ;-) that various dokku plugins take different (and somewhat conflicting) approaches in both naming convention, command syntax and functionality. \r\n\r\n### Goal\r\n\r\nFacilitate an ecosystem of dokku plugins that provide [attached services](http://12factor.net/backing-services) that follow a common pattern in building such plugins, their use cases and a common command syntax. This is intended as a minimum level.\r\n\r\n### Rationale\r\nCurrently there seem to be different ways for attached services. Some prefer to attach a service to a single app by default, while the dokku-link plugin allows one service to be linked to multiple apps. Also there are various ways for service plugins to name their environment variables.\r\n\r\nThis is to propose a standard for attached services, as follows. Ammendments, feedback and proposals welcome.\r\n\r\n### Definition\r\n\r\n1. A service is a dokku-plugin that, upon plugin installation, builds a base image to run the service in its own container.\r\n2. A service can be linked to any number of dokku apps, but it can also be created without any app specified (deferred linking).\r\n3. When linked, the service is to expose its connection URL to app containers as a single environment variable that follows this dokku-args standard: `-e <SERVICE>_URL=<service>://<user>:<password>@<ip>[/<path>]`, where service is the service name (e.g. MYSQL, RABBITMQ etc.), user/password the access credentials or tokens, ip the linked container's address, and the optional path any further information required.\r\n4. Services can expose further name-spaced env variables via dokku-args or dokku's `config:set` command, e.g. `-e <SERVICE>_SOMEVAR=some-value`. Such variables are to be documented in the plugin's README for easy reference\r\n5. Upon startup of the service container, the plugin creates a credentials file in $DOKKU_ROOT/.$SERVICE/credentials\r\n6. Upon link of a service to an app, the plugin uses dokku-link to create the link\r\n7. Upon removal of a service link from an app, the plugin uses dokku-link to remove the link\r\n8. A service maintains its persistent data (if any) in $DOKKU_ROOT/.$SERVICE/volume, which it maps in its container as /var/$SERVICE. Such volumes are to be recorded in $DOKKU_ROOT/.$SERVICE/volumes\r\n9. A service offers import and export commands to allow users to import/export service state (e.g. backup of persistent data or configuration).\r\n10. A service can be cloned. Cloning means to create a new service that exactly matches the specification of the old service, and copies all data (i.e. does <service>:export <old>, followed by <service>:import <new>>`.\r\n\r\n### Common command syntax\r\n\r\n`<service>:create <name> [<options>]` => create the service, no link to an app. options are optional and service-specific\r\n`<service>:link <name> <app>` => link the service to an app\r\n`<service>:unlink <name> <app>` => unlink the service from an app\r\n`<service>:delete> <name>` => if there are no links left, delete the service and stop its container\r\n`<service>:export <name>` => return a the export filename that can be used by import  (URL?)\r\n`<service>:import <name> <file>` => import file into the service (deleting all previous data first)\r\n`<service>:logs <name>` => print the most recent log(s) for this service\r\n`<service>:restart <name>` => graceful shutdown and restart of the service container. graceful means it will only work if no other containers/apps are currently using the service.\r\n`<service>:info <name>` => print the connection information\r\n`<service>:list` => list all services of this type\r\n`<service>:clone <existing-name> <new-name> [config | data | both]` => shortcut for :create the service new-name by copying the config (default), the data (do :export <name>, then :import <new-name>), or both from the existing service <name> . The new service shall *not* be linked to any apps. \r\n`<service>:expose <name> port` => expose the service on port. By default a service does not publicly expose any ports and can only be access via docker links. \r\n\r\n### Benefits\r\n- attached services follow a common pattern that is simple and effective, making it easier for users to build upon the respective plugins.\r\n- makes it easier to implement services as you don't have to re-invent the wheel\r\n- by specifically using the `docker link` facilities services become first class citizen in the docker and dokku universes (like apps).\r\n\r\n### Acknowledgment \r\n\r\nThis is meant as a constructive first step, and very much in appreciation of all those who have provided service plugins. In particular this is inspired and builds upon the fine work done by the authors of [dokku-redis](https://github.com/luxifer/dokku-redis-plugin), [dokku-mysql](https://github.com/hughfletcher/dokku-mysql-plugin), [dokku-rabbitmq](https://github.com/jlachowski/dokku-rabbitmq-plugin) and [dokku-link](https://github.com/rlaneve/dokku-link).\r\n\r\nUpdates\r\n* added :clone syntax\r\n* added :expose syntax as [patrickjahn](https://github.com/progrium/dokku/issues/854#issuecomment-94611560) suggested"},"comment":{"url":"https://api.github.com/repos/progrium/dokku/issues/comments/141642578","html_url":"https://github.com/progrium/dokku/issues/854#issuecomment-141642578","issue_url":"https://api.github.com/repos/progrium/dokku/issues/854","id":141642578,"user":{"login":"miraculixx","id":859611,"avatar_url":"https://avatars.githubusercontent.com/u/859611?v=3","gravatar_id":"","url":"https://api.github.com/users/miraculixx","html_url":"https://github.com/miraculixx","followers_url":"https://api.github.com/users/miraculixx/followers","following_url":"https://api.github.com/users/miraculixx/following{/other_user}","gists_url":"https://api.github.com/users/miraculixx/gists{/gist_id}","starred_url":"https://api.github.com/users/miraculixx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miraculixx/subscriptions","organizations_url":"https://api.github.com/users/miraculixx/orgs","repos_url":"https://api.github.com/users/miraculixx/repos","events_url":"https://api.github.com/users/miraculixx/events{/privacy}","received_events_url":"https://api.github.com/users/miraculixx/received_events","type":"User","site_admin":false},"created_at":"2015-09-19T09:58:03Z","updated_at":"2015-09-19T09:58:03Z","body":"@josegonzales :1 thanks for following up on this and making it awesome!"}}