Mais conteúdo relacionado

Apresentações para você(20)

Similar a Docker for Development(20)


Docker for Development

  1. D O C K E R F O R D E V E L O P M E N T J E F F N I C K O L O F F
  2. • To provide a simple scaffold for: • rapid iteration • build, test, lint… release pipeline automation • Dependency (library, service, etc) management W H A T I S T H E G O A L ? A D E V E L O P M E N T E N V I R O N M E N T
  3. • Runtime environment realism • Develop and iterate in isolation B E S T P R A C T I C E S A D E V E L O P M E N T E N V I R O N M E N T
  4. • Build tool management • “Did you install <tool X>?” “I dunno bud. It works in IntelliJ” • “We’re upgrading from Maven to <whatever>” *eyes roll* • Multi-day new team member ramp-up • Service dependency modeling (database, etc) • Remote resources: “I need VPN so I can work from the coffee shop / home / etc.” • Service state (data mutation, schema version) • Isolation from other local environments • Environment variable collisions • Log file collisions • Port collisions • Shared (remote) databases C H A L L E N G E S A D E V E L O P M E N T E N V I R O N M E N T
  5. – E V E R Y O N E A T S O M E P O I N T “I know! We’ll just Dockerize the things…”
  6. F I R S T Y O U M A K E A N I M A G E R I G H T ? • “It is easy! I just put my binaries in an image right?” • “Wait, you mean I have to rebuild my image every time?” • “Do my build tools need to go all the way to production if I use them in my development env?”
  7. F I R S T , T H I N K A B O U T Y O U R P R O B L E M • I want to iterate quickly when I’m developing local • I want to model my service dependencies locally • I want to version my build tooling and configuration • I want to automate a local build/launch pipeline
  8. T H R E E I M A G E / C O N T A I N E R P A T T E R N S • Static(ish) iteration tooling, variable source • heavy use of volumes • Static(ish) source, full build tooling • ONBUILD images • Release quality artifact, minimal overhead, minimal attack surface • FROM scratch or alpine
  9. E X A M P L E E N V I R O N M E N T • Owned by a team named, “team” • Go based service named, “proj” • Repo is “go getable” • Binaries can be produced outside of the context of a Go workspace • Build tools: • Node and GulpJS for workflow automation • Mocha for integration testing
  10. L O C A L . D F ( F O R I T E R A T I O N ) # Based on minimal Go tooling FROM golang:alpine # Environment modeling (Go workspace, path, and runtime flags) ENV GOPATH=/src/proj PATH=$PATH:/src/proj/bin GODEBUG=netdns=cgo RUN mkdir -p /src/proj/src/ && mkdir -p /src/proj/bin # Install Git (to pull library deps), Node, and Gulp (for build automation) RUN apk --update add --no-cache git nodejs RUN npm install --global gulp # Install library dependencies in image. RUN go get && go get && go get && go get && go get # Explicitly define volumes that should be overridden at runtime VOLUME ["/src/proj/src/", "/src/proj/pkg", "/src/proj/bin"] # Set the context for local iteration WORKDIR /src/proj/src/ # Gulp has the iterative build instructions # The iterative build instructions can change without rebuilding this image CMD ["gulp"]
  11. B U I L D . D F ( F O R B U I L D I N G B I N S ) # Based on minimal Go tooling FROM golang:alpine # Install Git for pulling library dependencies RUN apk --update add git # Basic environment stuffs ENV GODEBUG=netdns=cgo CMD proj --debug serve # Copy in sources (and just the sources) COPY *.go /go/src/ COPY common /go/src/ COPY service /go/src/ # Set context, install deps, and (simple) build WORKDIR /go/src/ RUN go get ./... && go install
  12. R E L E A S E . D F ( R U N N A B L E I M A G E ) # No Go tooling, just a minimal Linux FROM alpine # Set the context and runtime flags WORKDIR / ENV PATH=$PATH:/ GODEBUG=netdns=cgo CMD proj serve # Add other stuff like EXPOSE / USER here # Copy in the binary built in another container. # In a warm env, this is the only layer that should # ever change. (Fast) COPY ./bin/proj-exported /proj
  13. T H R E E I M A G E / C O N T A I N E R P A T T E R N S • Nobody said you could only use one image, container, etc. • Each of the three patterns is appropriate for a different development phase (see demo). • Nobody said you can ONLY use Docker. • Use other common tools like Make or Compose
  14. M O D E L E N V I R O N M E N T S W I T H C O M P O S E • Local development is an environment • Model service dependencies with known initial state • Include special tooling like integration tests • Include as many components to mirror a realistic runtime as possible (databases, dashboards, logging, mock traffic, etc)
  15. D O C K E R - C O M P O S E . Y M L ( I T E R A T E ) lb: image: nginx volumes: - ./myconf.conf:/etc/nginx/conf.d/myconf.conf ports: - 8080:80 proj: build: . dockerfile: local.df
  16. D O C K E R - C O M P O S E . Y M L ( I T E R A T E )lb: image: nginx volumes: - ./proj-proxy.conf:/etc/nginx/conf.d/proj-proxy.conf ports: - 8080:80 links: - proj:proj proj: build: . dockerfile: local.df links: - db:dbhostname - cache:cachehostname db: image: postgres cache: image: redis integ-test: build: ./integ links: - proj:proj
  17. P U T T I N G I T A L L T O G E T H E R • All of the tools in the stack should be accessible to the developer. • Few of those tools should “define” the experience. • Pick a primary touch point: • docker? docker-compose? make? Eclipse? something else?
  18. A M A K E F I L E PWD := $(shell pwd) # cleanup the environment clean: rm bin/proj-exported docker rmi team/proj:dev # Run NPM in a container and install tools (Gulp & Mocha) in the PWD prepare: docker run -it --rm -v "$(shell pwd)":/work -w /work node:4.1.2 npm install # Start iterating live. This uses docker-compose.yml and local.df. # GulpJS is performing a full format/build/spawn workflow on every source change. iterate: docker-compose up -d # Stop iterating. stop: docker-compose stop # Build proj during image build. Produce runnable image & copy out the binary build: docker build -t team/proj:dev -f dev.df . docker run --rm -v $(PWD)/bin:/xfer team/proj:dev cp /go/bin/proj /xfer/proj-exported # Produce a production quality image by injecting only the binary release: build docker build -t team/proj -f release.df .
  19. D E M O