# mantis-cli
Mantis is a CLI (command line interface) tool designed as a wrapper upon docker and docker compose commands for your project.
Using few commands you can:
- encrypt and decrypt your environment files
- build and push docker images
- create docker contexts
- zero-downtime deploy your application
- print logs of your containers
- connect to bash of your containers using SSH
- clean docker resources
- use specific commands using Django, PostgreSQL and Nginx extensions
- and much more
## Installation
```bash
pip install mantis-cli
```
## Configuration
Create a **mantis.json** configuration file in JSON format.
You can use ``<MANTIS>`` variable in your paths if needed as a relative reference to your mantis file.
### Explanation of config arguments
| argument | type | description |
|--------------------------|--------|--------------------------------------------------------------|
| manager_class | string | class path to mantis manager class |
| extensions | dict | Django, Postgres, Nginx |
| encryption | dict | encryption settings |
| encryption.deterministic | bool | if True, encryption hash is always the same for same value |
| encryption.folder | bool | path to folder with your environment files |
| configs | dict | configuration settings |
| configs.folder | string | path to folder with your configuration files |
| build | dict | build settings |
| build.tool | string | "docker" or "compose" |
| compose | dict | docker compose settings |
| compose.command | string | standalone "docker-compose" or "docker compose" plugin |
| compose.folder | string | path to folder with compose files |
| environment | dict | environment settings |
| environment.folder | string | path to folder with environment files |
| environment.file_prefix | string | file prefix of environment files |
| zero_downtime | array | list of services to deploy with zero downtime |
| project_path | string | path to folder with project files on remote server |
| connections | dict | definition of your connections for each environment |
TODO:
- default values
See [template file](https://github.com/PragmaticMates/mantis-cli/blob/master/mantis/mantis.tpl) for exact JSON structure.
### Connections
Connection for each environment except localhost can be defined either as an SSH or Docker context:
For example:
```json
"connections": {
"stage": "context://<context_name>",
"production": "ssh://<user>@<host>:<port>"
}
```
### Encryption
If you plan to use encryption and decryption of your environment files, you need to create encryption key.
Generation of new key:
```bash
mantis --generate-key
```
Save key to **mantis.key** file:
```bash
echo <MANTIS_KEY> > /path/to/encryption/folder/mantis.key
```
Then you can encrypt your environment files using symmetric encryption.
Every environment variable is encrypted separately instead of encrypting the whole file for better tracking of changes in VCS.
```bash
mantis <ENVIRONMENT> --encrypt-env
```
Decryption is easy like this:
```bash
mantis <ENVIRONMENT> --decrypt-env
```
When decrypting, mantis prompts user for confirmation.
You can bypass that by forcing decryption which can be useful in CI/CD pipeline:
```bash
mantis <ENVIRONMENT> --decrypt-env:force
```
## Usage
General usage of mantis-cli has this format:
```bash
mantis [--mode=remote|ssh|host] [environment] --command[:params]
```
### Modes
Mantis can operate in 3 different modes depending on a way it connects to remote machhine
#### Remote mode ```--mode=remote```
Runs commands remotely from local machine using DOCKER_HOST or DOCKER_CONTEXT (default)
#### SSH mode ```--mode=ssh```
Connects to host via ssh and run all mantis commands on remote machine directly (nantis-cli needs to be installed on server)
#### Host mode ```--mode=host```
Runs mantis on host machine directly without invoking connection (used as proxy for ssh mode)
### Environments
Environment can be either *local* or any custom environment like *stage*, *production* etc.
The environment is also used as an identifier for remote connection.
### Commands
| Command / Shortcut | Description |
|----------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| --bash:params | Runs bash in container |
| --build[:params] / -b | Builds all services with Dockerfiles |
| --check-config | Validates config file according to template |
| --check-env | Compares encrypted and decrypted env files |
| --check-health:container | Checks current health of given container |
| --clean[:params] / -c | Clean images, containers, networks |
| --contexts | Prints all docker contexts |
| --create-context | Creates docker context using user inputs |
| --decrypt-env[:params,env_file,return_value] | Decrypts all environment files (force param skips user confirmation) |
| --deploy[:dirty] / -d | Runs deployment process: uploads files, pulls images, runs zero-downtime deployment, removes suffixes, reloads webserver, clean |
| --down[:params] | Calls compose down (with optional params) |
| --encrypt-env[:params,env_file,return_value] | Encrypts all environment files (force param skips user confirmation) |
| --exec:params | Executes command in container |
| --generate-key | Creates new encryption key |
| --get-container-name:service | Constructs container name with project prefix for given service |
| --get-container-suffix:service | Returns the suffix used for containers for given service |
| --get-deploy-replicas:service | Returns default number of deploy replicas of given services |
| --get-healthcheck-config:container | Prints health-check config (if any) of given container |
| --get-healthcheck-start-period:container | Returns healthcheck start period for given container (if any) |
| --get-image-name:service | Constructs image name for given service |
| --get-image-suffix:service | Returns the suffix used for image for given service |
| --get-number-of-containers:service | Prints number of containers for given service |
| --get-service-containers:service | Prints container names of given service |
| --has-healthcheck:container | Checks if given container has defined healthcheck |
| --healthcheck[:container] / -hc | Execute health-check of given project container |
| --kill[:params] | Kills all or given project container |
| --logs[:params] / -l | Prints logs of all or given project container |
| --manage:params | Runs Django manage command |
| --networks / -n | Prints docker networks |
| --pg-dump[:data_only,table] | Backups PostgreSQL database [data and structure] |
| --pg-dump-data[:table] | Backups PostgreSQL database [data only] |
| --pg-restore[:filename,table] | Restores database from backup [data and structure] |
| --pg-restore-data:params | Restores database from backup [data only] |
| --psql | Starts psql console |
| --pull[:params] / -p | Pulls required images for services |
| --push[:params] | Push built images to repository |
| --read-key | Returns value of mantis encryption key |
| --remove[:params] | Removes all or given project container |
| --remove-suffixes[:prefix] | Removes numerical suffixes from container names (if scale == 1) |
| --restart[:service] | Restarts all containers by calling compose down and up |
| --restart-service:service | Stops, removes and recreates container for given service |
| --run:params | Calls compose run with params |
| --scale:service,scale | Scales service to given scale |
| --send-test-email | Sends test email to admins using Django 'sendtestemail' command |
| --services | Prints all defined services |
| --services-to-build | Prints all services which will be build |
| --sh:params | Runs sh in container |
| --shell | Runs and connects to Django shell |
| --start[:params] | Starts all or given project container |
| --status / -s | Prints images and containers |
| --stop[:params] | Stops all or given project container |
| --try-to-reload-webserver | Tries to reload webserver (if suitable extension is available) |
| --up[:params] | Calls compose up (with optional params) |
| --upload / -u | Uploads mantis config, compose file <br/>and environment files to server |
| --zero-downtime[:service] | Runs zero-downtime deployment of services (or given service) |
| --backup-volume:volume | Backups volume to a file |
| --restore-volume:volume,file | Restores volume from a file |
Few examples:
```bash
mantis --version
mantis local --encrypt-env
mantis stage --build
mantis production --logs:container-name
# you can also run multiple commands at once
mantis stage --build --push --deploy -s -l
```
Check ``mantis --help`` for more details.
## Flow
### 1. Build
Once you define mantis config for your project and optionally create encryption key, you can build your docker images:
```bash
mantis <ENVIRONMENT> --build
```
Mantis either uses ```docker-compose --build``` or ```docker build``` command depending on build tool defined in your config.
Build image names use '_' as word separator.
### 2. Push
Built images needs to be pushed to your repository defined in compose file (you need to authenticate)
```bash
mantis <ENVIRONMENT> --push
```
### 3. Deployment
Deployment to your remote server is being executed by calling simple command:
```bash
mantis <ENVIRONMENT> --deploy
```
The deployment process consists of multiple steps:
- If using --mode=ssh, mantis uploads mantis config, environment files and compose file to server
- pulling docker images from repositories
- [zero-downtime deployment](https://github.com/PragmaticMates/mantis-cli?tab=readme-ov-file#zero-downtime-deployment) of running containers (if any)
- calling docker compose up to start containers
- removing numeric suffixes from container names (if scale==1)
- reloading webserver (if found suitable extension)
- cleaning docker resources (without volumes)
Docker container names use '-' as word separator (docker compose v2 convention).
### 4. Inspect
Once deployed, you can verify the container status:
```bash
mantis <ENVIRONMENT> --status
```
list all docker networks:
```bash
mantis <ENVIRONMENT> --networks
```
and also check all container logs:
```bash
mantis <ENVIRONMENT> --logs
```
If you need to follow logs of a specific container, you can do it by passing container name to command:
```bash
mantis <ENVIRONMENT> --logs:<container-name>
```
### 5. Another useful commands
Sometimes, instead of calling whole deployment process, you just need to call compose commands directly:
```bash
mantis <ENVIRONMENT> --up
mantis <ENVIRONMENT> --down
mantis <ENVIRONMENT> --restart
mantis <ENVIRONMENT> --stop
mantis <ENVIRONMENT> --kill
mantis <ENVIRONMENT> --start
mantis <ENVIRONMENT> --clean
```
Commands over a single container:
```bash
mantis <ENVIRONMENT> --bash:container-name
mantis <ENVIRONMENT> --sh:container-name
mantis <ENVIRONMENT> --run:params
```
## Zero-downtime deployment
Mantis has own zero-downtime deployment implementation without any third-party dependencies.
It uses docker compose service scaling and docker health-checks.
Works as follows:
- a new service container starts using scaling
- mantis waits until the new container is healthy by checking its health status. If not health-check is defined, it waits X seconds defined by start period
- reloads webserver (to proxy requests to new container)
- once container is healthy or start period ends the old container is stopped and removed
- new container is renamed to previous container's name
- webserver is reloaded again
## Release notes
Mantis uses semantic versioning. See more in [changelog](https://github.com/PragmaticMates/mantis-cli/blob/master/CHANGES.md).
Raw data
{
"_id": null,
"home_page": "https://github.com/PragmaticMates/mantis-cli",
"name": "mantis-cli",
"maintainer": "Pragmatic Mates",
"docs_url": null,
"requires_python": null,
"maintainer_email": "info@pragmaticmates.com",
"keywords": "management deployment docker command",
"author": "Erik Telepovsk\u00fd",
"author_email": "info@pragmaticmates.com",
"download_url": "https://files.pythonhosted.org/packages/87/82/34fd2599f16b6b20df5d8ffca023968304ef0bb541289d5d8efe683a6390/mantis_cli-19.1.7.tar.gz",
"platform": null,
"description": "# mantis-cli\n\nMantis is a CLI (command line interface) tool designed as a wrapper upon docker and docker compose commands for your project.\n\nUsing few commands you can:\n- encrypt and decrypt your environment files\n- build and push docker images\n- create docker contexts\n- zero-downtime deploy your application\n- print logs of your containers\n- connect to bash of your containers using SSH \n- clean docker resources\n- use specific commands using Django, PostgreSQL and Nginx extensions\n- and much more\n\n## Installation\n\n```bash\npip install mantis-cli\n```\n\n## Configuration\n\nCreate a **mantis.json** configuration file in JSON format.\nYou can use ``<MANTIS>`` variable in your paths if needed as a relative reference to your mantis file.\n\n### Explanation of config arguments\n\n| argument | type | description |\n|--------------------------|--------|--------------------------------------------------------------|\n| manager_class | string | class path to mantis manager class |\n| extensions | dict | Django, Postgres, Nginx |\n| encryption | dict | encryption settings |\n| encryption.deterministic | bool | if True, encryption hash is always the same for same value |\n| encryption.folder | bool | path to folder with your environment files |\n| configs | dict | configuration settings |\n| configs.folder | string | path to folder with your configuration files |\n| build | dict | build settings |\n| build.tool | string | \"docker\" or \"compose\" |\n| compose | dict | docker compose settings |\n| compose.command | string | standalone \"docker-compose\" or \"docker compose\" plugin |\n| compose.folder | string | path to folder with compose files |\n| environment | dict | environment settings |\n| environment.folder | string | path to folder with environment files |\n| environment.file_prefix | string | file prefix of environment files |\n| zero_downtime | array | list of services to deploy with zero downtime |\n| project_path | string | path to folder with project files on remote server |\n| connections | dict | definition of your connections for each environment |\n\nTODO:\n- default values\n\nSee [template file](https://github.com/PragmaticMates/mantis-cli/blob/master/mantis/mantis.tpl) for exact JSON structure.\n\n### Connections\n\nConnection for each environment except localhost can be defined either as an SSH or Docker context:\n\nFor example:\n\n```json\n\"connections\": {\n \"stage\": \"context://<context_name>\",\n \"production\": \"ssh://<user>@<host>:<port>\"\n}\n```\n\n### Encryption\n\nIf you plan to use encryption and decryption of your environment files, you need to create encryption key.\n\nGeneration of new key:\n\n```bash\nmantis --generate-key\n```\n\nSave key to **mantis.key** file:\n\n```bash\necho <MANTIS_KEY> > /path/to/encryption/folder/mantis.key\n```\n\nThen you can encrypt your environment files using symmetric encryption. \nEvery environment variable is encrypted separately instead of encrypting the whole file for better tracking of changes in VCS.\n\n```bash\nmantis <ENVIRONMENT> --encrypt-env\n```\n\nDecryption is easy like this:\n\n```bash\nmantis <ENVIRONMENT> --decrypt-env\n```\n\nWhen decrypting, mantis prompts user for confirmation. \nYou can bypass that by forcing decryption which can be useful in CI/CD pipeline:\n\n```bash\nmantis <ENVIRONMENT> --decrypt-env:force\n```\n\n## Usage\n\nGeneral usage of mantis-cli has this format:\n\n```bash\nmantis [--mode=remote|ssh|host] [environment] --command[:params]\n```\n\n### Modes\n\nMantis can operate in 3 different modes depending on a way it connects to remote machhine\n\n\n#### Remote mode ```--mode=remote``` \n\nRuns commands remotely from local machine using DOCKER_HOST or DOCKER_CONTEXT (default)\n\n#### SSH mode ```--mode=ssh```\n\nConnects to host via ssh and run all mantis commands on remote machine directly (nantis-cli needs to be installed on server)\n\n\n#### Host mode ```--mode=host```\n\nRuns mantis on host machine directly without invoking connection (used as proxy for ssh mode)\n\n\n### Environments\n\nEnvironment can be either *local* or any custom environment like *stage*, *production* etc.\nThe environment is also used as an identifier for remote connection.\n\n### Commands\n\n| Command / Shortcut | Description |\n|----------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|\n| --bash:params | Runs bash in container |\n| --build[:params] / -b | Builds all services with Dockerfiles |\n| --check-config | Validates config file according to template |\n| --check-env | Compares encrypted and decrypted env files |\n| --check-health:container | Checks current health of given container |\n| --clean[:params] / -c | Clean images, containers, networks |\n| --contexts | Prints all docker contexts |\n| --create-context | Creates docker context using user inputs |\n| --decrypt-env[:params,env_file,return_value] | Decrypts all environment files (force param skips user confirmation) |\n| --deploy[:dirty] / -d | Runs deployment process: uploads files, pulls images, runs zero-downtime deployment, removes suffixes, reloads webserver, clean |\n| --down[:params] | Calls compose down (with optional params) |\n| --encrypt-env[:params,env_file,return_value] | Encrypts all environment files (force param skips user confirmation) |\n| --exec:params | Executes command in container |\n| --generate-key | Creates new encryption key |\n| --get-container-name:service | Constructs container name with project prefix for given service |\n| --get-container-suffix:service | Returns the suffix used for containers for given service |\n| --get-deploy-replicas:service | Returns default number of deploy replicas of given services |\n| --get-healthcheck-config:container | Prints health-check config (if any) of given container |\n| --get-healthcheck-start-period:container | Returns healthcheck start period for given container (if any) |\n| --get-image-name:service | Constructs image name for given service |\n| --get-image-suffix:service | Returns the suffix used for image for given service |\n| --get-number-of-containers:service | Prints number of containers for given service |\n| --get-service-containers:service | Prints container names of given service |\n| --has-healthcheck:container | Checks if given container has defined healthcheck |\n| --healthcheck[:container] / -hc | Execute health-check of given project container |\n| --kill[:params] | Kills all or given project container |\n| --logs[:params] / -l | Prints logs of all or given project container |\n| --manage:params | Runs Django manage command |\n| --networks / -n | Prints docker networks |\n| --pg-dump[:data_only,table] | Backups PostgreSQL database [data and structure] |\n| --pg-dump-data[:table] | Backups PostgreSQL database [data only] |\n| --pg-restore[:filename,table] | Restores database from backup [data and structure] |\n| --pg-restore-data:params | Restores database from backup [data only] |\n| --psql | Starts psql console |\n| --pull[:params] / -p | Pulls required images for services |\n| --push[:params] | Push built images to repository |\n| --read-key | Returns value of mantis encryption key |\n| --remove[:params] | Removes all or given project container |\n| --remove-suffixes[:prefix] | Removes numerical suffixes from container names (if scale == 1) |\n| --restart[:service] | Restarts all containers by calling compose down and up |\n| --restart-service:service | Stops, removes and recreates container for given service |\n| --run:params | Calls compose run with params |\n| --scale:service,scale | Scales service to given scale |\n| --send-test-email | Sends test email to admins using Django 'sendtestemail' command |\n| --services | Prints all defined services |\n| --services-to-build | Prints all services which will be build |\n| --sh:params | Runs sh in container |\n| --shell | Runs and connects to Django shell |\n| --start[:params] | Starts all or given project container |\n| --status / -s | Prints images and containers |\n| --stop[:params] | Stops all or given project container |\n| --try-to-reload-webserver | Tries to reload webserver (if suitable extension is available) |\n| --up[:params] | Calls compose up (with optional params) |\n| --upload / -u | Uploads mantis config, compose file <br/>and environment files to server |\n| --zero-downtime[:service] | Runs zero-downtime deployment of services (or given service) |\n| --backup-volume:volume | Backups volume to a file |\n| --restore-volume:volume,file | Restores volume from a file |\n\nFew examples:\n\n```bash\nmantis --version\nmantis local --encrypt-env\nmantis stage --build\nmantis production --logs:container-name\n\n# you can also run multiple commands at once\nmantis stage --build --push --deploy -s -l\n```\n\nCheck ``mantis --help`` for more details.\n\n## Flow\n\n### 1. Build\n\nOnce you define mantis config for your project and optionally create encryption key, you can build your docker images:\n\n```bash\nmantis <ENVIRONMENT> --build\n```\n\nMantis either uses ```docker-compose --build``` or ```docker build``` command depending on build tool defined in your config.\nBuild image names use '_' as word separator.\n\n### 2. Push\n\nBuilt images needs to be pushed to your repository defined in compose file (you need to authenticate)\n\n```bash\nmantis <ENVIRONMENT> --push\n```\n\n### 3. Deployment\n\nDeployment to your remote server is being executed by calling simple command:\n\n```bash\nmantis <ENVIRONMENT> --deploy\n```\n\nThe deployment process consists of multiple steps:\n\n- If using --mode=ssh, mantis uploads mantis config, environment files and compose file to server\n- pulling docker images from repositories\n- [zero-downtime deployment](https://github.com/PragmaticMates/mantis-cli?tab=readme-ov-file#zero-downtime-deployment) of running containers (if any)\n- calling docker compose up to start containers\n- removing numeric suffixes from container names (if scale==1)\n- reloading webserver (if found suitable extension)\n- cleaning docker resources (without volumes)\n\nDocker container names use '-' as word separator (docker compose v2 convention).\n\n### 4. Inspect\n\nOnce deployed, you can verify the container status:\n\n```bash\nmantis <ENVIRONMENT> --status\n```\n\nlist all docker networks:\n\n```bash\nmantis <ENVIRONMENT> --networks\n```\n\nand also check all container logs:\n\n```bash\nmantis <ENVIRONMENT> --logs\n```\n\nIf you need to follow logs of a specific container, you can do it by passing container name to command:\n\n```bash\nmantis <ENVIRONMENT> --logs:<container-name>\n```\n\n### 5. Another useful commands\n\nSometimes, instead of calling whole deployment process, you just need to call compose commands directly:\n\n```bash\nmantis <ENVIRONMENT> --up\nmantis <ENVIRONMENT> --down\nmantis <ENVIRONMENT> --restart\nmantis <ENVIRONMENT> --stop\nmantis <ENVIRONMENT> --kill\nmantis <ENVIRONMENT> --start\nmantis <ENVIRONMENT> --clean\n```\n\nCommands over a single container:\n\n```bash\nmantis <ENVIRONMENT> --bash:container-name\nmantis <ENVIRONMENT> --sh:container-name\nmantis <ENVIRONMENT> --run:params\n```\n\n## Zero-downtime deployment\n\nMantis has own zero-downtime deployment implementation without any third-party dependencies. \nIt uses docker compose service scaling and docker health-checks.\n\nWorks as follows:\n\n- a new service container starts using scaling\n- mantis waits until the new container is healthy by checking its health status. If not health-check is defined, it waits X seconds defined by start period \n- reloads webserver (to proxy requests to new container)\n- once container is healthy or start period ends the old container is stopped and removed\n- new container is renamed to previous container's name\n- webserver is reloaded again\n\n## Release notes\n\nMantis uses semantic versioning. See more in [changelog](https://github.com/PragmaticMates/mantis-cli/blob/master/CHANGES.md).\n",
"bugtrack_url": null,
"license": "GNU General Public License (GPL)",
"summary": "Management command to build and deploy webapps, especially based on Django",
"version": "19.1.7",
"project_urls": {
"Homepage": "https://github.com/PragmaticMates/mantis-cli"
},
"split_keywords": [
"management",
"deployment",
"docker",
"command"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "878234fd2599f16b6b20df5d8ffca023968304ef0bb541289d5d8efe683a6390",
"md5": "f928eb8f53a279116e16cbff723cc5be",
"sha256": "9cfd7b55c9dcdc24772c6733dadc7aeb373508aaa5f8a2dfbc3e46371a67dd1f"
},
"downloads": -1,
"filename": "mantis_cli-19.1.7.tar.gz",
"has_sig": false,
"md5_digest": "f928eb8f53a279116e16cbff723cc5be",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 39556,
"upload_time": "2024-10-15T19:50:10",
"upload_time_iso_8601": "2024-10-15T19:50:10.869870Z",
"url": "https://files.pythonhosted.org/packages/87/82/34fd2599f16b6b20df5d8ffca023968304ef0bb541289d5d8efe683a6390/mantis_cli-19.1.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-15 19:50:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "PragmaticMates",
"github_project": "mantis-cli",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "mantis-cli"
}