Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker at Code Climate

Docker at Code Climate

Docker is heavily utilized at Code Climate. We use Docker for development, testing, and running services in production. Docker also plays a starting role within the Code Climate Platform as our plugin packaging mechanism.

See all the ways in which we're taking advantage of Docker at Code Climate.

Avatar for Devon Blandin

Devon Blandin

April 20, 2017
Tweet

More Decks by Devon Blandin

Other Decks in Programming

Transcript

  1. What is Docker? Docker is an open-source project that automates

    the deployment of applications inside software containers. A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it. Containers are an abstraction at the app layer that packages code and dependencies together.
  2. We use Docker a lot! - Development Environment - Continuous

    Integration - Production Services - DevOps and ChatOps - The Code Climate Platform
  3. Development Environment - Uses Docker Compose - Simple setup -

    Only host dependency required is docker - Scales well - Shared dev configuration
  4. Development Environment $ bin/setup * Cloning projects * Building project

    images * Initializing the database * Setting data volume permissions * Setup complete * Some services were started already, * start the rest in the way you normally would.
  5. Development Environment $ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------------------------

    harness_api_1 passenger start --port=4000 Up 0.0.0.0:4000->4000/tcp, 443/tcp, 80/tcp harness_app-resque_1 bundle exec rake environme ... Up 443/tcp, 80/tcp harness_app_1 passenger start --log-file ... Up 0.0.0.0:3000->3000/tcp, 443/tcp, 80/tcp harness_fetcher_1 /usr/src/app/bin/fetcher Up harness_finalizer_1 /usr/src/app/bin/finalizer Up harness_kafka_1 start-kafka.sh Up harness_mailcatcher_1 mailcatcher --ip=0.0.0.0 - ... Up 1025/tcp, 0.0.0.0:1080->1080/tcp harness_memcached_1 docker-entrypoint.sh memcached Up 11211/tcp harness_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp harness_scheduler-2_1 /usr/src/app/bin/scheduler Up harness_scheduler_1 /usr/src/app/bin/scheduler Up harness_tokumx_1 mongod --smallfiles Up 27017/tcp, 28017/tcp harness_wally_1 /usr/src/app/bin/wally Up harness_worker_1 bundle exec sidekiq --conf ... Up 443/tcp, 80/tcp harness_zookeeper_1 /opt/zookeeper/bin/zkServe ... Up 2181/tcp, 2888/tcp, 3888/tcp
  6. Development Environment service1: image: example/service1 build: ../service1 environment: SERVICE1_DEBUG: 1

    SERVICE1_KAFKA_BROKERS: kafka:9092 SERVICE1_MONGODB_URL: mongodb://mongodb/example_development SERVICE1_REDIS_URL: redis://redis:6379/0 depends_on: - kafka - mongodb - redis
  7. Development Environment app: image: example/app-development build: context: ../app dockerfile: Dockerfile.development

    volumes: - ../app:/app environment: APP_API_URL: http://api:4000/v1/ APP_ASSET_HOST: http://localhost:3000 APP_CANONICAL_URL: http://localhost:3000 APP_KAFKA_BROKERS: kafka:9092 APP_MONGODB_URL: mongodb://mongodb/example_development APP_REDIS_URL: redis://redis:6379/0 Volume mount your working code Use an image that does not COPY your code
  8. Development Environment test: development docker run \ --rm \ --interactive

    \ --tty \ --network harness_default \ --volume /tmp:/tmp \ --volume $(PWD):/app \ codeclimate/app-development rspec $(RSPEC_ARGS) $ make test $ RSPEC_ARGS="spec/models/user_spec.rb" make test $ RSPEC_ARGS="--tag focus" make test
  9. Development Environment FROM ruby:2.4-alpine WORKDIR /usr/src/app COPY . ./ RUN

    bundle install --jobs 4 CMD ["/usr/src/app/bin/start"]
  10. Development Environment FROM ruby:2.4-alpine WORKDIR /usr/src/app COPY Gemfile* ./ RUN

    bundle install --jobs 4 COPY . ./ CMD ["/usr/src/app/bin/start"]
  11. Continuous Integration - CircleCI builds, tests, and deploys our docker

    images - Better control over dependencies via docker images - Test against the same data services you’re running in production - Deploying artifacts is more reliable that deploying commit SHAs - Deploy exactly what you test!
  12. Continuous Integration dependencies: override: docker build codeclimate/api . test: override:

    docker run codeclimate/api bundle exec rspec deployment: registry: branch: master commands: - docker tag codeclimate/api codeclimate/api:b$CIRCLE_BUILD_NUM - docker push codeclimate/api:b$CIRCLE_BULID_NUM Configuration for testing a dockerized project on CircleCI Build docker image Test docker image Push docker image to registry
  13. Production Services - We use Amazon’s EC2 Container Service in

    production ECS, given a group of registered EC2 instances: - Balance and monitor docker tasks - Control deployments and load balancer registration - Robust API - Reliable
  14. Production Services ECS is fantastic for stateless services. If you

    need state: - Amazon’s Elastic File System (EFS), networked storage by Amazon which you can mount to EC2 instances. - Run stateful services on the same network and delegate state to them
  15. DevOps and ChatOps - Shared docker image with operational tooling

    - Complex dependencies - Our chat bot uses the same tooling as engineers use
  16. DevOps and ChatOps master commit! test Build passed! deploy! Okay,

    I’ll put it over here! Automated deployments Amazon ECS shipbot
  17. DevOps and ChatOps tools $ docker run codeclimate/toolbox builders.list [ip-10-20-51-168.ec2.internal]

    Executing task '_list_builders' Builder Versions: 2948,29420,29530 ID URL LOAD ddbaa2cb-900f-40d2-8228-88d931edbb8c tcp://10.20.52.115:2375 10 76005340-b8a3-47a3-b8a3-e4f682204979 tcp://10.20.52.136:2375 17 a34f9d8c-70de-45f1-ac12-90e7fd4eb0ad tcp://10.20.51.23:2375 11 a95b89bd-c8ab-4747-ba09-7316ee8ea13c tcp://10.20.51.80:2375 16 7a654d26-b5c7-4783-a609-dc0200810080 tcp://10.20.50.54:2375 12 ce3be509-4c0a-4bc0-bf4c-54c2ea84262c tcp://10.20.50.148:2375 15 Done. Disconnecting from [email protected]... done.
  18. DevOps and ChatOps tools $ docker run codeclimate/toolbox fab -l

    | grep ecs ecs.cat Display task definiti... ecs.instances List ec2 instances fo... ecs.kick Re-deploy the current... ecs.list List services on clus... ecs.run Run a command on a ta... ecs.scale Update desired count ... ecs.stop Scale services to 0 t... ecs.config.replace Replace parts of ENV ... ecs.config.set Set ENV vars for a se... ecs.config.show Show ENV vars for a s... ecs.config.unset Unset ENV vars for a ... ecs.deploy Update Docker image f... ecs.deploy.deploy Update Docker image f... ecs.image.set Set container image u... ecs.image.show Show container images... ecs.res.cpu.set Set CPU units for ser... … lots more
  19. DevOps and ChatOps tools - Operational tooling should be isolated

    from Slack/Hipchat/IRC - Delegate out from your chatbot to your tools
  20. Code Climate Platform - Packaging strategy for Code Climate engines

    - Code Climate engines are deployed as docker images - Scheduling service to dispatch containers - Analysis containers run their own engine containers
  21. The Code Climate Platform def run Builder.logger.tagged(Builder.config[:snapshot_id]) do clone #

    docker run codeclimate/builder bin/clone pull_engines # docker pull codeclimate/codeclimate-eslint analyze # docker run codeclimate/codeclimate-eslint end end