This is a CLI utility written in Python that makes developing microservices with Docker easy. The CLI utilizes docker-compose to orchestrate multiple services, and offers additional functionality like pulling code, Docker images, and starting groups of services. It handles the core interactions between services and the code, git, and docker-compose.
Note: This is very much a work in progress and everything in this project is liable to change so don't depend on this project yet for anything mission critical.
Coming soon. For now you can clone the repo and run pip install -e .
from inside the microservices_cli/
directory.
Each service being orchestrated must have a docker-compose.yml
file in the root of the project, and all of the projects must be siblings of each other in a single directory.
All configuration lives in a file located at ~/.ms
and is formatted with JSON. The only config variable that needs to be set is BASE_DIR
which is the parent folder of all services. An example of the bare minimum .ms
file would look like this:
{
"BASE_DIR": "/Users/tony/Documents/Development/microservices_project"
}
Once that is set, there are several commands available to start working with the services:
Usage: ms start [-h] [services [services ...]]
The start command will take one or more services and start them simultaneously. If no services are specified, the command will start all services inside the root project directory that has a docker-compose.yml
file in it.
Additionally, a "service constellation" can be substituted in place of a service name, which can be used to start a group of services instead of needing to type out the names of each service individually. Constellations can be set by specifying them with the SERVICE_CONSTELLATIONS
configuration option.
Usage: ms kill [--service <service>] [--keep]
By default, kills all services specified in the generated docker-compose
file.
Optionally, specify --service <service>
to only kill that service.
Optionally, specify --keep
to keep the generated docker-compose
around after killing.
Usage: ms attach [-h] service
Attach will take a single service attempt to drop you into a bash shell in a running container. The container you are trying to attach to must be currently running.
Usage: ms pull [-h] [services [services ...]]
Pull will pull Docker images from DockerHub for the service(s) specified in the command. If no services are passed, the command will pull images for all services.
Usage: ms gitpull [-h] [services [services ...]]
Gitpull will take a list of services (defaulting to all if no services are passed) and pull the master branch for each of the repositories. If any repositories are on a branch that is not master, they will checkout master, pull, and then checkout the original branch leaving the repository as it was before the pull.
Usage: ms logs [-f] [services [services ...]]
Logs will output a service's logs, (defaulting to all services if no services are passed). The -f option will prevent the command from exiting, and will continue to output any new content in the logs.
There are a number of configuration variables that can be set in the ~/.ms
file to change the way the CLI behaves.
If true
, keep the generated temporary docker-compose
file around after things like shutting down containers,
pressing Ctrl + C
after starting containers, etc.
Useful if you have a service that loads the file into memory, like running Docker via Pycharm
This is the only required configuration option for the operation of the CLI. The base directory is the root directory that contains all the services beneath it as children.
microservices_proj/
|-- service1/
|-- service2/
|-- service3/
In this case, microservices_proj
would be the base directory of the project.
Default: BASE_DIR/docker-compose-tmp.yml
This is an optional configuration option that allows changing the location of the temporary docker-compose file that is created by the microservices CLI when it runs. When services are started, this temporary file is created at this location and when the stack is brought down it is automatically removed.
The service mapping configuration option allows you to specify a name for you services that differs from the folder name that they are in. This is a JSON object that simply maps directory name to desired service name. An example is:
"SERVICE_MAPPING": {
"my-service": "service"
}
Service constellations allow you to specify groups, or subsets, of all services in your base directory that you would like to bring up. If you're developing something that only needs a handful of your services, or if you regularly only need to start a certain subset of services this option can help simplify things. An example is:
"SERVICE_CONSTELLATIONS": {
"mygroup": [
"service1/",
"service2/",
"service3/"
]
}
With this constellation set, you can now run ms start mygroup
instead of needing to run ms start service1 service2 service3
.
Singleton services allow you to specify services that should only be started a single time, despite how many times they show up in the docker-compose.yml
files of the individual services. This is useful in situations where each service may individually specify rabbitmq
or redis
, which is needed when running a service on its own, but all services need to share a single rabbitmq
instance when running multiple at a time.
Example:
"SINGLETON_SERVICES": ["rabbitmq", "redis"]
Plugins are dynamically loaded based on the value of this configuration variable. Plugins can be installed via pip, and then be added here and will be available from within the command.
For a plugin to work, it should be available on your Python path (you should be able to open a Python interpreter and type import <plugin_name>
without seeing any errors).
Example:
"PLUGINS": ["myplugin"]
{
"KEEP_DOCKER_COMPOSE_FILE_ON_SHUTDOWN": true,
"BASE_DIR": "/Users/jeffrey/code",
"SERVICE_MAPPING": {
"server_1": "s1",
"server_2": "s2",
"front_end": "fe"
},
"SERVICE_CONSTELLATIONS": {
"full": [
"server_1",
"server_2",
"front_end"
],
"backend": [
"server_1",
"server_2",
]
},
"PLUGINS": ["my_cool_plugin"],
"SINGLETON_SERVICES": ["memcached", "rabbitmq", "redis"]
}
The plugin system is designed to make the microservices CLI endlessly extensible by anyone who has a particular use case that they'd like to build off of the base CLI.
Anyone wishing to create a plugin need only implement a module compatible with argparse. The microservices CLI will call the add_commands()
method on modules specified in the PLUGINS
config variable.
Plugins can interact with the base CLI utilizing the utils
module of the package. Anything that interacts with the code, services, git, or docker should be done through the built-in utils. If there is any functionality that is missing belonging to any of these domains, please open an issue or a PR to add it. Plugins can implement their own utils that handle interactions with other areas. An example plugin may handle hooking up microservices with Heroku, so this plugin's utils would manage any interactions with Heroku, but call the microservices CLI utils to do anything related to the services on disk.
This is a work in progress and Issues and Pull Requests are welcome.
The microservices CLI is free software, and may be redistributed under the terms specified in the LICENSE file.