Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/freaker2k7/dockerserver

Super lightweight & simple RESTFul distributed server for running docker containers on a remote machine(s).
https://github.com/freaker2k7/dockerserver

Last synced: about 2 months ago
JSON representation

Super lightweight & simple RESTFul distributed server for running docker containers on a remote machine(s).

Awesome Lists containing this project

README

        

# DockerServer
Super lightweight & simple RESTFul stateless server for running [docker](https://docker.com/ "docker") containers on a remote machine(s) in a secure way.

[![npm version](https://badge.fury.io/js/docker-server.svg)](https://badge.fury.io/js/docker-server)
[![node version](https://img.shields.io/node/v/docker-server)](https://www.npmjs.com/package/docker-server)
[![npm downloads](https://img.shields.io/npm/dw/docker-server.svg)](https://www.npmjs.com/package/docker-server)
[![Gitter](https://badges.gitter.im/freaker2k7-dockerserver/community.svg)](https://gitter.im/freaker2k7-dockerserver/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/freaker2k7/dockerserver.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/freaker2k7/dockerserver/alerts/)
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/freaker2k7/dockerserver.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/freaker2k7/dockerserver/context:javascript)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/freaker2k7/dockerserver/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/freaker2k7/dockerserver/?branch=master)
[![License](https://img.shields.io/badge/license-Apache-brightgreen.svg)](https://opensource.org/licenses/Apache-2.0)
[![Bungle size](https://img.shields.io/bundlephobia/minzip/docker-server)](https://bundlephobia.com/result?p=docker-server)
[![Repo size](https://img.shields.io/github/repo-size/freaker2k7/dockerserver)](https://github.com/freaker2k7/dockerserver)
[![Build status](https://ci.appveyor.com/api/projects/status/rwbo4jvqp4032boj/branch/master?svg=true)](https://ci.appveyor.com/project/freaker2k7/dockerserver/branch/master)
[![Beerpay](https://beerpay.io/freaker2k7/dockerserver/badge.svg?style=flat)](https://beerpay.io/freaker2k7/dockerserver)
[![Liberapay](http://img.shields.io/liberapay/receives/evgy.svg?logo=liberapay)](https://liberapay.com/evgy/)
[![GitHub stars](https://img.shields.io/github/stars/freaker2k7/dockerserver.svg?style=social&label=Stars)](https://github.com/freaker2k7/dockerserver/stargazers/)
[![Known Vulnerabilities](https://snyk.io//test/github/freaker2k7/dockerserver/badge.svg?targetFile=package.json)](https://snyk.io//test/github/freaker2k7/dockerserver)


DockerServer Logo

## Install
`npm i -g docker-server`

Or

`docker run -d -p 1717:1717 --restart=always --name=docker-server -v /var/run/docker.sock:/var/run/docker.sock -e "DS_TOKEN=my_secret_token" evgy/dockerserver`

## Background
I needed to run a couple of containers on a remote machine and came to these conclusions:
* Kubernetes is an overkill !
* docker-machine is also complicated !
* I just want to run a few containers on a remote machine.

## Approach
Built a small REST server with NodeJS, using the `express` and `docker-cli-js` packages as a base.

### Design Principles
* Keep the business logic **simple**!
* It must be **stateless**!
* **Docker** is (a) present.

### Current architecture

How things work today

The cluster diagram demonstrates a PUT request.

#### Notes for the Cluster Mode:

*\*0 - Connection between the load balancer and the docker-server.*

*\*1 - Save the machine load to a [JSON](https://json.org "JSON") file in a shared folder (among all the machines).*

**PUT method**

*1 - Requests comes to any free (according to the load balancer) node to answer.*

*2 - Get the most free (according to actual cpu-mem ratio) node (from redis or the shared storage, possibly on S3).*

*3 - Resend the current request to that node (or process if it's the current node) and return the answer.*

**For the rest of the methods**

*Resent the current request to all the nodes and return the merged results.*

## Usage
Install DockerServer on the machine that you want to run your containers.

DockerServer can be run for a single session with:

`$ docker-server`

or as a service using [PM2](https://pm2.keymetrics.io/ "PM2"):

`$ pm2 start /usr/lib/node_modules/docker-server/pm2.config.js`

and if you want in addition to start it on startup just run:

`$ pm2 startup`

And of-course, as mentioned before, but using params, via docker itself:

`$ docker run -d -p 1717:1717 --restart=always --name=docker-server -v /var/run/docker.sock:/var/run/docker.sock evgy/dockerserver docker-server --token my_secret_token`

Or you can run in **HTTPS** mode:

(Note that in this example I'm using [Let's Encrypt](https://letsencrypt.org/ "Let's Encrypt") and I'm using `readlink` because these files are symbolic links)

`$ docker run -d -p 443:1717 --privileged --restart=always --name=docker-server -v /var/run/docker.sock:/var/run/docker.sock
-v $(readlink -f /home/user/letsencrypt/config/live/your-domain.com/cert.pem):/certs/cert.pem:ro
-v $(readlink -f /home/user/letsencrypt/config/live/your-domain.com/chain.pem):/certs/chain.pem:ro
-v $(readlink -f /home/user/letsencrypt/config/live/your-domain.com/privkey.pem):/certs/privkey.pem:ro
evgy/dockerserver docker-server --token my_secret_token --https`

Note: The **--privileged** argument is only needed in order to use the 443 port, because all ports below 1024 are reserved by root.

Moreover, you can run in a **Cluster mode** when you have a couple of machines to use:

`$ docker run -d -p 1717:1717 --privileged --restart=always --name=docker-server -v /var/run/docker.sock:/var/run/docker.sock
-v /some/shared/folder:/my/somewhy/custom/path evgy/dockerserver docker-server --token my_secret_token --cluster --folder /my/somewhy/custom/path`

Or simply:

`$ docker run -d -p 1717:1717 --privileged --restart=always --name=docker-server -v /var/run/docker.sock:/var/run/docker.sock
-v /some/shared/folder:/tmp/docker-server evgy/dockerserver docker-server --token my_secret_token --cluster`

Note: `/tmp/docker-server` is the default folder so you can easily and safely run it even without docker.

Now, you can do "remote" docker operation using simple HTTP requests:


HTTP Method
Endpoint
Desc.
Docker cmd


HEAD
/:id*
Pull an image
docker pull :id


GET
/
List all the containers
docker ps -a


GET
/:id
Show the logs of a specific container
docker logs :id


PUT
/
Run a container
docker run...


POST
/:id
Execute a command in a container
docker exec...


DELETE
/:id
Delete a container with such a name or an ID
docker rm -f :id


## Options
### Environment
You can set the following environment variables to configure DockerServer:


Environment Var.
Desc.
Default


DS_PORT
The port on which the DockerServer is running
1717


DS_TOKEN
The secret token for the authorization
xxxxxx

### Parameters
Also, you can start DockerServerwith these parameters:


Param
Desc.
Default


--port [num]
The port on which the DockerServer is running
1717


--token [string]
The secret token for the authorization
xxxxxx


--low_burst [num]
Max number of requests per minute for Low burst.
60


--mid_burst [num]
Max number of requests per minute for Mid burst.
180


--high_burst [num]
Max number of requests per minute for High burst.
300


--https

Enable HTTPS mode.

For this you must have the following files:

    a. /certs/cert.pem

    b. /certs/privkey.pem

    c. /certs/chain.pem (optional, to support self-signed certs)

false


--cluster
Enable Cluster mode.
false


--refresh_rate [num]
Milliseconds between writes to the shared memory
30000


--cache_interval [num]
Milliseconds to cache reads of all the machines
3000


--folder [path]
Shared folder between all docker-servers. (Used only in cluster mode)
/tmp/docker-server


--redis [hostname]

Shared redis server hostname.

If set, the `--folder` param. becomes the key prefix (default: "DSC:")

null


--db_port [num]

Shared server port number.


6379


--s3 [bucket-name]

S3 bucket name, use with high refresh_rate.

If set, the `--folder` param. becomes the Key.

null


--log_lovel [option]
Log level [trace|debug|info|warn|error|fatal]
info


--log_expiry [num]
Time for a log to live in days.
14


--log_max_size [num]
Max log size in MB
25


--help
Show he
 


--version
Show current version
 

### PUT Data
When sending the PUT request, the following parameters are supported:


Param
Desc.
Default
Docker cmd


image
The image for the run. (required)
null
 


name
The name of the container.
uuid4()
--name


remove
Flag to remove the container when it finishes --rm
false
--rm


detach
Flag to detach the container -d
false
-d


ports
Map of ports to publish.
null
-p


volumes
Map of volumes to mount.
null
-v


data
CMD to run inside the container.
null
 

### POST Data
When sending the POST request, the following parameters are supported:


Param
Desc.
Default
Docker cmd


tty
Flag to enable TTY mode
false
-t


interactive
Flag to enable interactive mode
false
-i


data
CMD to run inside the container
null
 

## Examples
NOTE: In the examples I assumed you're using the default port.

1. Get a list of all the containers:

`$ curl -X GET http://1.2.3.4:1717/ -H 'Authorization: Basic base64EncodedToken'`

2. Run redis on the remote machine:

`$ curl -X PUT http://1.2.3.4:1717/ -H 'Authorization: Basic base64EncodedToken' --data 'name=p-redis&image=redis&ports[1234]=6379'`

And/or

`$ curl -X PUT http://1.2.3.4:1717/ -H 'Authorization: Basic base64EncodedToken' --data 'name=v-redis&image=redis&volumes[/tmp/data]=/data'`

3. Remove our created container(s):

`$ curl -X DELETE http://1.2.3.4:1717/p-redis -H 'Authorization: Basic base64EncodedToken'`

And/or

`$ curl -X DELETE http://1.2.3.4:1717/v-redis -H 'Authorization: Basic base64EncodedToken'`

## Changelog

1.9.0 - Added optional **[Redis](https://redis.io) support** for big clusters (recommended for clusters with more than 50 workers/hosts).

1.8.9 - Fixed CVE issue with docker-cli-js v2.5.2 ==> v2.5.3 & removed package-lock.json

[See full changelog](https://github.com/freaker2k7/dockerserver/blob/master/CHANGELOG.md)

## Roadmap
* Queue (for heavy loads)
* Autoscaling

## License
APACHE-2.0 (see the LICENSE files in the repository).

## Donate
Running dockers is free, but **beer** is always welcome
Beerpay

or directly donate to our cause
Donate using Liberapay