Slide 1

Slide 1 text

Build and Development Environments with Nix and Docker Christine Koppelt [email protected] Linuxwochen Wien 2018

Slide 2

Slide 2 text

About Me ● Software Developer for 10 years ● Senior Consultant at INNOQ ● Regularly working with Docker ● Using NixOS in my free time for ~2 years ● Started using Nix in commercial projects some months ago

Slide 3

Slide 3 text

Developing an application ... REST API Web Application

Slide 4

Slide 4 text

… often requires some infrastructure services ... Postgres Database REST API Web Application Kafka Cluster Kafka Cluster Kafka Cluster

Slide 5

Slide 5 text

… and a lot of development tools Postgres Database BPMN Dateien REST API Web Application pgAdmin kafkacat Camunda Modeler OpenJDK Maven curl Kafka Cluster Kafka Cluster Kafka Cluster

Slide 6

Slide 6 text

Working on more than one application ... ● Use the same service versions for develoment and production ● Tools and services need to be available in multiple versions ● Hassle-free switching between projects

Slide 7

Slide 7 text

Working in a team ... ● Default: Every team member works with the same versions ● Environment should be reproducible & updatable ● Fast start for new developers

Slide 8

Slide 8 text

Not so good Options ● Manual installation ● Package manager of your Linux distribution ● Programming language specific package managers ● Hand-written scripts

Slide 9

Slide 9 text

Step 1: Automate Services Setup Using Docker

Slide 10

Slide 10 text

Goal REST API Web Application Postgres Docker Container Kafka Docker Container

Slide 11

Slide 11 text

Docker in a Nutshell ● Software can be installed & started inside separated „boxes“ called containers ● Central repository with premade containers ● Open-Source, available for Linux, Mac and Windows ● Provides uniform interface for starting applications

Slide 12

Slide 12 text

Example: Running PostgreSQL docker run ­d \ ­e POSTGRES_PASSWORD=secret \ ­p 5432:5432 \ postgres:10.3

Slide 13

Slide 13 text

Script it with Docker Compose stack.yml version: '3.1' services: db: image: postgres:10.3 restart: always environment: POSTGRES_PASSWORD: secret kafka: image: ...

Slide 14

Slide 14 text

docker­compose ­f stack.yml up

Slide 15

Slide 15 text

Benefits ✔ Scripted, versionable & reproducible ✔ Setting up multiple services in one step ✔ Isolated, doesn't affect operating system ✔ Multiple service versions in parallel ✔ Keep versions in sync within the development team ✔ … and with the Continuous Integration & production servers

Slide 16

Slide 16 text

Caveats ✗ Custom-made images are somewhat cumbersome to manage

Slide 17

Slide 17 text

Step 2: Automate Tooling Setup Using Docker

Slide 18

Slide 18 text

A good idea? REST API Web Application Postgres Docker Container Kafka Docker Container Tools Container Java 8, Maven, kafkacat, pgAdmin, curl, Camunda Modeler

Slide 19

Slide 19 text

Approach ● Tools are installed within the container ● Mount your local src directory into the container ● Call the tool within the container

Slide 20

Slide 20 text

Example: Running Maven (basic version) docker run ­it ­­rm \ ­v "$(pwd)":/usr/src/mymaven \ ­w /usr/src/mymaven \ maven:3.3­jdk­8 \ mvn clean install

Slide 21

Slide 21 text

It becomes only more ugly ● Graphical tools ● User permissions ● Caching files

Slide 22

Slide 22 text

No cool solutions ● Aliases? ● Develop completely within the container? – SSH Shell or Shell via Docker exec – Graphical tools?

Slide 23

Slide 23 text

Benefits ✔ Setting up multiple tools in one step ✔ Isolated, doesn't affect operating system ✔ Multiple tool versions in parallel ✔ Keep versions in sync within the development team

Slide 24

Slide 24 text

Caveats ✗ Ugly command line calls ✗ Adding new tools to the Docker image needs a rebuild of the Docker image ✗ Graphical tools even more cumbersome

Slide 25

Slide 25 text

Step 2: Alternative Automate tooling Setup Using Nix

Slide 26

Slide 26 text

What is Nix? ● Package manager ● Contains a broad range of tools – ~13.000 packages – Own packages can be added ● Own configuration language ● Works on Mac and Linux ● Immutable package store, multi-version support

Slide 27

Slide 27 text

Stored separately REST API Web Application Postgres Docker Container Kafka Docker Container /nix/store 4k3ah­openjdk­9.0.4 15Jns­maven 3Byd1­kafkacat ghlhk­pgAdmin Lsn08­curl jicnp­camunda_modeler

Slide 28

Slide 28 text

Loading tools on the fly ck@ck­innoq:~/myproject$ java ­version openjdk version "1.8.0_131" ck@ck­innoq:~/myproject$ nix­shell ­p openjdk9 maven [nix­shell:~/myproject]$ java ­version openjdk version "9.0.4­internal" nix-shell -p a_package

Slide 29

Slide 29 text

What happens ● Downloads packages ● Stores them at /nix/store Example: /nix/store/2fiavk609lgb9wsr560lkjf6wyx7d9a3­apache­maven­3.5.2 ● Sets Links [nix­shell:~/Dokumente/microxchg]$ which mvn /nix/store/2fiavk609lgb9wsr560lkjf6wyx7d9a3­apache­ maven­3.5.2/bin/mvn

Slide 30

Slide 30 text

Write a default.nix script with import {}; stdenv.mkDerivation { name = "my­service"; buildInputs = [openjdk9 maven kafkacat curl]; }

Slide 31

Slide 31 text

Loading configuration nix­shell default.nix

Slide 32

Slide 32 text

Define new package (schematic) camunda_modeler = stdenv.mkDerivation { name = "camunda_modeler"; src = pkgs.fetchurl { url = "https://..."; sha256 = "..."; } installPhase = '' tar ­xzf $src ''; };

Slide 33

Slide 33 text

Add it to buildInputs stdenv.mkDerivation { name = "my­service"; buildInputs = [openjdk9 maven kafkacat curl camunda_modeler]; }

Slide 34

Slide 34 text

Version Pinning let hostPkgs = import {}; nixpkgs = (hostPkgs.fetchFromGitHub { owner = "NixOS"; repo = "nixpkgs­channels"; rev = "9c31c72cafe536e0c21238b2d47a23bfe7d1b033"; sha256 = "0pn142js99ncn7f53bw7hcp99ldjzb2m7xhjrax00xp72zswzv2n"; }); in with import nixpkgs {};

Slide 35

Slide 35 text

Configure Tools with import {}; let curl = pkgs.curl.override { zlibSupport = true; sslSupport = true; http2Support = false; }; in stdenv.mkDerivation { name = "my­service"; buildInputs = [ openjdk9 maven kafkacat curl camunda_modeler ]; }

Slide 36

Slide 36 text

Benefits ✔ Low overhead ✔ Setting up multiple tools in one step ✔ Hardly affects host system ✔ Multiple tool versions in parallel ✔ Keep versions in sync within the development team

Slide 37

Slide 37 text

Combination of Docker & Nix ● Docker – Fast development setup for services like message broker, databases and custom services ● Nix – Setup of development tools like custom editors, database & messaging clients, networking tools

Slide 38

Slide 38 text

More information about Docker ● Official documentation https://docs.docker.com/ ● Central container image hub https://hub.docker.com/

Slide 39

Slide 39 text

More information about Nix ● Official Website https://nixos.org ● My Twitter Account @nixos_muc ● Meetups Europe: Munich, Berlin, Amsterdam, London

Slide 40

Slide 40 text

Questions? [email protected]