diff --git a/swarm/Dockerfile b/swarm/Dockerfile new file mode 100644 index 0000000..82659ec --- /dev/null +++ b/swarm/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.7-alpine +ADD . /code +WORKDIR /code +RUN pip install -r requirements.txt +CMD ["python", "app.py"] \ No newline at end of file diff --git a/swarm/README.md b/swarm/README.md index 3303e85..7b07cb9 100755 --- a/swarm/README.md +++ b/swarm/README.md @@ -1,36 +1,136 @@ -* to install Docker swarm container: +### Check the file from the project -```docker run swarm --help``` +The app used in this guide is based on the hit counter app in the Get started with Docker Compose guide. It consists of a Python app which maintains a counter in a Redis instance and increments the counter whenever you visit it. -* To run the consul container on the manager node: +### Check the file from the project -```docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap``` +Check a file called app.py in the project directory and paste this in: -* To run the swarm manage node on the master: +```shell +from flask import Flask +from redis import Redis -```docker run -d -p 4000:4000 swarm manage -H :4000 --advertise 192.168.0.248:4000 consul://192.168.0.248:8500 ``` +app = Flask(__name__) +redis = Redis(host='redis', port=6379) -* To run swarm join on the agent2 +@app.route('/') +def hello(): + count = redis.incr('hits') + return 'Hello World! I have been seen {} times.\n'.format(count) -```docker run -d swarm join --advertise=192.168.0.246:2375 consul://192.168.0.248:8500``` +if __name__ == "__main__": + app.run(host="0.0.0.0", port=8000, debug=True) +``` -* To run swarm join on the agent3 - -```docker run -d swarm join --advertise=192.168.0.247:2375 consul://192.168.0.248:8500``` +Create a file called requirements.txt and paste these two lines in: -* see cluster status +```shell +flask +redis +``` -```docker -H :4000 info``` +Create a file called Dockerfile and paste this in: -* Run on a container on your swarm cluster: +```shell +FROM python:3.4-alpine +ADD . /code +WORKDIR /code +RUN pip install -r requirements.txt +CMD ["python", "app.py"] +``` -```docker -H :4000 run -p 3000:3000 -d wardviaene/nodejs-demo``` +Create a file called docker-compose.yml and paste this in: -* List containers: +```shell +version: '3' -```docker -H :4000 ps``` +services: + web: + image: 127.0.0.1:5000/stackdemo + build: . + ports: + - "8000:8000" + redis: + image: redis:alpine +``` -* Connect to the nodejs-demo container +The image for the web app is built using the Dockerfile defined above. It’s also tagged with 127.0.0.1:5000 - the address of the registry created earlier. This is important when distributing the app to the swarm. -```curl 192.168.0.247:3000``` +### Test the app with Compose +Start the app with docker-compose up. This builds the web app image, pull the Redis image if you don’t already have it, and create two containers. +You see a warning about the Engine being in swarm mode. This is because Compose doesn’t take advantage of swarm mode, and deploys everything to a single node. You can safely ignore this. + +```shell +vagrant@docker$ docker-compose up -d +``` + +WARNING: The Docker Engine you're using is running in swarm mode. + +Compose does not use swarm mode to deploy services to multiple nodes in +a swarm. All containers are scheduled on the current node. + +To deploy your application across the swarm, use `docker stack deploy`. + +Creating network "stackdemo_default" with the default driver + +```shell +Building web +...(build output)... +Creating stackdemo_redis_1 +Creating stackdemo_web_1 +``` + +Check that the app is running with docker-compose ps: + +```shell +vagrant@docker$ docker-compose ps + + Name Command State Ports +----------------------------------------------------------------------------------- +stackdemo_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp +stackdemo_web_1 python app.py Up 0.0.0.0:8000->8000/tcp +``` + +You can test the app with curl: + +```shell +vagrant@docker$ curl http://localhost:8000 +Hello World! I have been seen 1 times. + +vagrant@docker$ curl http://localhost:8000 +Hello World! I have been seen 2 times. + +vagrant@docker$ curl http://localhost:8000 +Hello World! I have been seen 3 times. +``` + +Bring the app down: + +```shell +$ docker-compose down --volumes + +Stopping stackdemo_web_1 ... done +Stopping stackdemo_redis_1 ... done +Removing stackdemo_web_1 ... done +Removing stackdemo_redis_1 ... done +Removing network stackdemo_default +Push the generated image to the registry +``` + +### Optional +To distribute the web app’s image across the swarm, it needs to be pushed to the registry you set up earlier. With Compose, this is very simple: + +```shell +$ docker-compose push + +Pushing web (127.0.0.1:5000/stackdemo:latest)... +The push refers to a repository [127.0.0.1:5000/stackdemo] +5b5a49501a76: Pushed +be44185ce609: Pushed +bd7330a79bcf: Pushed +c9fc143a069a: Pushed +011b303988d2: Pushed +latest: digest: sha256:a81840ebf5ac24b42c1c676cbda3b2cb144580ee347c07e1bc80e35e5ca76507 size: 1372 +The stack is now ready to be deployed. +``` \ No newline at end of file diff --git a/swarm/app.py b/swarm/app.py new file mode 100644 index 0000000..bca218a --- /dev/null +++ b/swarm/app.py @@ -0,0 +1,13 @@ +from flask import Flask +from redis import Redis + +app = Flask(__name__) +redis = Redis(host='redis', port=6379) + +@app.route('/') +def hello(): + count = redis.incr('hits') + return 'Hello World! I have been seen {} times.\n'.format(count) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=8000, debug=True) \ No newline at end of file diff --git a/swarm/docker-compose.yml b/swarm/docker-compose.yml new file mode 100644 index 0000000..bd3f06b --- /dev/null +++ b/swarm/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3' + +services: + web: + image: 127.0.0.1:5000/stackdemo + build: . + ports: + - "8000:8000" + redis: + image: redis:alpine \ No newline at end of file diff --git a/swarm/requirements.txt b/swarm/requirements.txt new file mode 100644 index 0000000..eadf80f --- /dev/null +++ b/swarm/requirements.txt @@ -0,0 +1,2 @@ +flask +redis \ No newline at end of file