## Docker in MyScript WebServices Mathieu Ruellan - https://github.com/mathieuruellan
## Activity We are selling technology around handwriting recognition: - Text - Maths - Shapes - Music [Visit our dev-portal: https://dev.myscript.com/](https://dev.myscript.com/ "Visit dev-portal!")
## Products - SDK: C, java, .net - Widgets: IOS, Android (and soon windows 10) - Services: Recognition with REST or WebSockets [Visit our dev-portal: https://dev.myscript.com/](https://dev.myscript.com/ "Visit dev-portal!")
## What we do with Docker? - MyScript Cloud (online recognition) - MyScript ATK (certificate provider for mobile apps embedding our widgets) - Builds
## Who is using Docker? - developers - testers - production (AWS/EC2 environment)
## What do we need in production? - Backend - DB (mongodb) - SMTP relay (Postfix) - HAProxy (load balancing) - logger (rsyslog - elasticsearch/logstash/kibana) - Varnish - static content (nginx)
## Deliveries are Docker Images - Environment agnostic (thanks to environment variables) - Build results are pushed in a local registry (it's also a docker container) - Production deployment on private S3 with **`docker save`** and **`docker load`** - Possibility to run a production-like environment with fig/docker-compose
## Best practices - One process per container - Pipe the process stdout/stderr to logger otherwise mount a /dev/log volume (deprecated with --log-driver since 1.6) - In Production, use **`docker run --net=host ...`**
## **Do not believe it's secured!!!** ![Docker disaster](images/docker-disaster.GIF "Docker disaster")
## Docker and test

It's light, fast and everything is scriptable!

## Example: Mailing testing ![AWS](images/AWS.svg "AWS")
## Faking AWS services 1/2 - Creating a smtp/pop3 container - Creating AWS/ELB fake with HAProxy
## Faking AWS services 2/2 ![mailtesing](images/mailtesting.svg "MailTesting")
## Automatic tests with a Makefile ``` _waittcp: @echo -n "Waiting for TCP Port on IP:$(WAIT_IP):$(WAIT_PORT) " && \ CPT=0 && \ while ! nc -w 1 $(WAIT_IP) $(WAIT_PORT); do \ ((CPT++)); \ if [ $$CPT -gt 60 ]; then \ echo "timeout"; \ exit 1; \ fi; \ sleep 1; \ echo -n .; \ done; \ echo " Found!" _start-mailtest: @echo -n "starting mailtest container. " && \ docker run $(DOCKER_MAILTEST_PARAMETERS) -d -h test.myscript.com -e maildomain=myscript.com -e user=qawebservices:qawebservices,test1:test1,test2:test2,test3:test3 --name $(TEST_DOCKER_MAILTEST_INSTANCE_NAME) webtest:5000/myscript-webservices-mailtest:$(DOCKERTAG) && \ MAILTESTIP=$$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(TEST_DOCKER_MAILTEST_INSTANCE_NAME)) && \ $(MAKE) WAIT_IP=$${MAILTESTIP} WAIT_PORT=110 _waittcp && \ $(MAKE) WAIT_IP=$${MAILTESTIP} WAIT_PORT=25 _waittcp _start-license-volumes: @echo -n "Starting license-7.0 volume. " && docker run -d --name $(TEST_DOCKER_LICENSE_7_0_INSTANCE_NAME) webtest:5000/myscript-cloud-volume-licensekey-7.0:$(DOCKERTAG) _start-mongo-docker: @echo -n "Starting mongo container. " && docker run $(DOCKER_MONGO_PARAMETERS) -d -h mongo --name $(TEST_DOCKER_MONGO_INSTANCE_NAME) mongo:2.6 --smallfiles --replSet "testreplset" @MONGOIP=$$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(TEST_DOCKER_MONGO_INSTANCE_NAME)) && \ $(MAKE) WAIT_IP=$${MONGOIP} WAIT_PORT=27017 _waittcp && \ echo "Initializing ReplicaSet." && \ docker exec $(TEST_DOCKER_MONGO_INSTANCE_NAME) mongo --quiet --eval "rs.initiate();" > /dev/null _start-backend-docker: @echo -n "Starting current version backend container. " && \ MAILTESTIP=$$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(TEST_DOCKER_MAILTEST_INSTANCE_NAME)) && \ docker run \ $(DOCKER_BACKEND_PARAMETERS) \ -d \ --volumes-from $(TEST_DOCKER_LICENSE_7_0_INSTANCE_NAME) \ --link $(TEST_DOCKER_MONGO_INSTANCE_NAME):mongo \ -e "MYSCRIPT_CLOUD_LOGGER_HOST=" \ -e "MYSCRIPT_CLOUD_SMTP_SERVER=$${MAILTESTIP}" \ -e "MYSCRIPT_CLOUD_SEND_EMAIL_TO_USER=false" \ -e "MYSCRIPT_CLOUD_ACTIVATION_EMAIL_QAWEBERVICES=qawebservices@myscript.com" \ --name $(TEST_DOCKER_BACKEND_INSTANCE_NAME) \ webtest:5000/myscript-cloud-backend:$(DOCKERTAG) @BACKENDIP=$$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(TEST_DOCKER_BACKEND_INSTANCE_NAME)) && \ $(MAKE) WAIT_IP=$${BACKENDIP} WAIT_PORT=8894 _waittcp ```
## Builds - The jenkins is deployed in a docker container! - Everybody can test the jenkins on his workstation!
## And What about the production? Only one AMI! The EC2 AMI is a stable debian with: - docker.io - jq - awscli EC2 instances run a script injected through user-data, configured with tags - clean containers and images - docker load from S3 repository - launch dockers with environment variables
## Monitoring User-data scripts create cron jobs to - check host states (disk, cpu etc.) - docker containers status - launch periodic backups (it's also a docker)
## Difficulties - Docker comes with a DevOps approach. Changing actual practices - Workstation must be linux - New tool to learn (testers have to get IT knowledge) - Tools to help them - Can't migrate everything in one step, still working with the past
## Benefits - Force people to have good practices - provide something testable - no more 'preprod' for testers - Update deployment facilities - Less stress for IT

Thank you!