SlideShare a Scribd company logo
1 of 33
Download to read offline
Automating Mendix
application
deployments with
Nix
Sander van der Burg
Software Engineer
Modeling applications bring value to a broader
audience than just developers
Deployment is an important
activity in an application’s
development process
Without deployment, an application can not be used by
end users
Deployment looks quite convenient for Mendix
cloud portal users
Actually managing app deployments is not
Fortunately, there are automated deployment
solutions
No deployment solution is
perfect
So we must keep an open mind when integrating
solutions
The Nix project
• Family of declarative deployment tools:
• Nix. A purely functional package manager
• NixOS. Nix-based GNU/Linux distribution
• Hydra. Nix-based continuous integration service
• NixOps. NixOS-based multi-cloud deployment
tool
• Disnix. Nix-based distributed service
deployment tool
The Nix package manager
• The basis of all tools in the Nix project
• Nix is a package manager borrowing
concepts from purely functional
programming languages
• 𝑥 = 𝑦 → 𝑓 𝑥 = 𝑓(𝑦)
• Reliably deploying a package = Invoking a pure
function
• Nix provides its own purely functional DSL
Example Nix expression
• A package is a function definition
• Function parameters correspond
to build dependencies
• The mkDerivation {} function
invocation composes a “pure”
build environment
• In a build environment, we can
invoke almost any build/test tool
we want
{ stdenv, fetchurl, acl }:
stdenv.mkDerivation {
name = "gnutar-1.30";
src = fetchurl {
url = http://ftp.gnu.org/tar/tar-1.30.tar.xz;
sha256 = "1lyjyk8z8hdddsxw0ikchrsfg3i0…";
};
buildCommand = ''
tar xfv $src
cd tar-1.30
./configure --prefix=$out --with-acl=${acl}
make
make install
'';
}
Composing packages
• We must compose packages
by providing the desired
versions of the dependencies
as function parameters
• Dependencies are composed
in a similar way
• Top level expression is an
attribute set of function
invocations
rec {
stdenv = import ...
fetchurl = import ...
acl = import ../pkgs/os-specific/linux/acl {
inherit stdenv fetchurl …;
};
gnutar = import ../pkgs/tools/archivers/gnutar {
inherit stdenv fetchurl acl;
};
...
}
Enforcing purity
• Nix imposes restrictions on builds:
• Every package is stored in an isolated directory, not in global
directories, such as /lib, /bin or C:WindowsSystem32
• Files are made read-only after build completion
• Timestamps are reset to 1 second after the epoch
• Search environment variables are cleared and configured explicitly, e.g.
PATH
• Private temp folders and designated output directories
• Network access is restricted (except when an output hash is given)
• Running builds as unprivileged users
• Chroot environments, namespaces, bind-mounting dependency
packages
The Nix store
• Every package is stored in
isolation in the Nix store
• Every package is prefixed by a
160-bit cryptographic hash of all
inputs, such as:
• Sources
• Libraries
• Compilers
• Build scripts
Invoke nix-build to build a package
rec {
stdenv = import ...
fetchurl = import ...
acl = import ../pkgs/os-specific/linux/acl {
inherit stdenv fetchurl;
};
gnutar = import ../pkgs/tools/archivers/gnutar {
inherit stdenv fetchurl acl;
};
...
}
Some benefits of the purely functional model
• Strong dependency completeness guarantees
• Strong reproducibility guarantees
• Build only the packages and dependencies that you need
• Packages that don’t depend on each other can be built in
parallel
• Because of purity, we can also download a substitute from a
remote machine (e.g. build server) if the hash prefix is identical
• Because of purity, we can delegate a build to a remote machine
Nix user environments
• Users have convenient access
to packages through a symlink
tree (and generation symlinks)
Packaging the Mendix runtime and mxbuild
• Simply extract tarball and
move content into the Nix
store
• I created a wrapper script
that launches the runtime
for convenience
• I used a similar approach
for mxbuild
{stdenv, fetchurl, jre}:
stdenv.mkDerivation {
name = "mendix-7.13.1";
src = fetchurl {
url = https://download.mendix.com/runtimes/mendix-7.13.1.tar.gz;
sha256 = "1v620zmxm1s50p5jhpl74xvr0jv4j334cg1yfvy0mvgz4x0jrr7y";
};
installPhase = ''
cd ..
mkdir -p $out/libexec/mendix
mv 7.13.1 $out/libexec/mendix
mkdir -p $out/bin
# Create wrapper script for the runtime launcher
cat > $out/bin/runtimelauncher <<EOF
#! ${stdenv.shell} -e
export MX_INSTALL_PATH=$out/libexec/mendix/7.13.1
${jre}/bin/java –jar 
$out/libexec/mendix/7.13.1/runtime/launcher/runtimelauncher.jar 
"$@"
EOF
chmod +x $out/bin/runtimelauncher
'';
}
Creating a function abstraction for building
MDAs
• We can create a Nix
function abstraction that
builds MDA (Mendix
Deployment Archive)
bundles from Mendix
projects
{stdenv, mxbuild, jdk, nodejs}:
{name, mendixVersion, looseVersionCheck ? false, ...}@args:
let
mxbuildPkg = mxbuild."${mendixVersion}";
in
stdenv.mkDerivation ({
buildInputs = [ mxbuildPkg nodejs ];
installPhase = ''
mkdir -p $out
mxbuild --target=package --output=$out/${name}.mda 
--java-home ${jdk} --java-exe-path ${jdk}/bin/java 
${stdenv.lib.optionalString looseVersionCheck "--loose-
version-check"} 
"$(echo *.mpr)"
'';
} // args)
Building an MDA from a Mendix project with Nix
• We can invoke our function
abstraction to build MDAs
for any Mendix project we
want.
{packageMendixApp}:
packageMendixApp {
name = "conferenceschedule";
src = /home/sbu/ConferenceSchedule-main;
mendixVersion = "7.13.1";
}
Declarative deployment
• Nix package deployment can be considered declarative
deployment
• You specify how packages are built from source and what their
dependencies are
• You don’t specify the deployment activities or the order in which builds
need to be carried out
• Being declarative means expressing what you want, not how to
do something
• Declarativity is a spectrum – hard to draw a line between what and how
• Producing an MDA is not entirely what we want – we want a
running system
NixOS: deploying a Linux distribution
declaratively
{pkgs, ...}:
{
boot.loader.grub.device = "/dev/sda";
fileSystems."/".device = "/dev/sda1";
services = {
openssh.enable = true;
xserver = {
enable = true;
displayManager.sddm.enable = true;
desktopManager.plasma5.enable = true;
};
};
environment.systemPackages = [
pkgs.firefox
];
}
NixOS: deploying a Linux distribution
declaratively
• Nix deploys all packages, configuration files and other static
system parts in the Nix store. Generates a Nix user
environment that contains all static parts of a system.
• A bundled activation script takes care of setting up the
dynamic parts of a system, e.g. starting systemd jobs, setting
up /var etc.
• Changing configuration.nix and running nixos-rebuild again ->
upgrade
NixOS: bootloader
Running an MDA
• Unzip MDA file to a directory
• Add writable state sub directories, e.g. data/files, data/tmp
• Configure admin interface settings
• Start runtime with the unpacked directory as parameter (Mendix
7.x)
export M2EE_ADMIN_PORT=9000
export M2EE_ADMIN_PASS=secret
java -jar $out/libexec/mendix/7.13.1/runtime/launcher/runtimelauncher.jar ConferenceSchedule
Running an MDA
• Instruct the app container to configure database, initialize
database tables and start the app by communicating over the
admin interface
curlCmd="curl -X POST http://localhost:$M2EE_ADMIN_PORT 
-H 'Content-Type: application/json' 
-H 'X-M2EE-Authentication: $(echo -n "$M2EE_ADMIN_PASS" | base64)' 
-H 'Connection: close'"
$curlCmd -d '{ "action": "update_appcontainer_configuration", "params": { "runtime_port": 8080 } }'
$curlCmd -d '{ "action": "update_configuration", "params": { "DatabaseType": "HSQLDB", "DatabaseName":
"myappdb", "DTAPMode": "D" } }'
$curlCmd -d '{ "action": "execute_ddl_commands" }'
$curlCmd -d '{ "action": "start" }'
Composing a Mendix app container systemd job
for NixOS
• We can define a
systemd job
calling scripts that
initialize state,
configure the app
container and
launch the
runtime.
{pkgs, ...}:
{
systemd.services.mendixappcontainer =
let
mendixPkgs = import ../nixpkgs-mendix/top-level/all-packages.nix { inherit pkgs; };
appContainerConfigJSON = pkgs.writeTextFile { ... };
configJSON = pkgs.writeTextFile {
name = "config.json";
text = builtins.toJSON {
DatabaseType = "HSQLDB";
DatabaseName = "myappdb";
DTAPMode = "D";
};
};
runScripts = mendixPkgs.runMendixApp {
app = import ../conferenceschedule.nix { inherit (mendixPkgs) packageMendixApp; };
};
in {
enable = true;
description = "My Mendix App";
wantedBy = [ "multi-user.target" ];
environment = {
M2EE_ADMIN_PASS = "secret";
M2EE_ADMIN_PORT = "9000";
MENDIX_STATE_DIR = "/home/mendix";
};
serviceConfig = {
ExecStartPre = "${runScripts}/bin/undeploy-app";
ExecStart = "${runScripts}/bin/start-appcontainer";
ExecStartPost = "${runScripts}/bin/configure-appcontainer ${appContainerConfigJSON} ${configJSON}";
};
};
}
Composing a NixOS module
• We can create a
module abstraction
over the properties
that we need to
configure to run a
Mendix app
container
{ config, lib, pkgs, ... }:
let
cfg = config.services.mendixAppContainer;
in
{
options = {
services.mendixAppContainer = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable the Mendix app container.";
};
adminPort = mkOption {
type = types.int;
default = 9000;
description = "TCP port where the admin interface listens to.";
};
runtimePort = mkOption {
type = types.int;
default = 8080;
description = "TCP port where the embedded Jetty HTTP server listens to.";
};
databaseType = mkOption {
type = types.string;
default = "HSQLDB";
description = "Type of database to use for storage. Possible options are 'HSQLDB' (the default) or 'PostgreSQL’”;
};
app = mkOption {
type = types.package;
description = "Mendix MDA to deploy";
};
...
};
};
config = mkIf cfg.enable {
systemd.services.mendixappcontainer = { ... };
};
}
A simple configuration running a Mendix app
• With our custom
NixOS module,
we can concisely
express our
desired app
container
properties
{pkgs, ...}:
{
require = [ ../nixpkgs-mendix/nixos/modules/mendixappcontainer.nix ];
services = {
openssh.enable = true;
mendixAppContainer = {
enable = true;
adminPassword = "secret";
databaseType = "HSQLDB";
databaseName = "myappdb";
DTAPMode = "D";
app = import ../../conferenceschedule.nix {
inherit pkgs;
inherit (pkgs.stdenv) system;
};
};
};
networking.firewall.allowedTCPPorts = [ 8080 ];
}
A more complete deployment scenario
• We can add a
PostgreSQL database
and nginx reverse proxy
to our NixOS
configuration.
• We can use the NixOS
module system to
integrate our Mendix app.
{pkgs, config, ...}:
{
services = {
postgresql = {
enable = true;
enableTCPIP = true;
package = pkgs.postgresql94;
};
nginx = {
enable = true;
config = ''
http {
upstream mendixappcontainer {
server 127.0.0.1:${toString config.services.mendixAppContainer.runtimePort};
}
server {
listen 0.0.0.0:80;
server_name localhost;
root ${config.services.mendixAppContainer.stateDir}/web
location @runtime {
proxy_pass http://mendixappcontainer;
}
location / {
try_files $uri $uri/ @runtime;
proxy_pass http://mendixappcontainer;
}
}
}
'';
};
mendixAppContainer = {
databaseType = "PostgreSQL"; ...
};
};
networking.firewall.allowedTCPPorts = [ 80 ];
}
Conclusion
• I gave an introduction to Nix and NixOS
• I have implemented the following features:
• A Nix function that builds an MDA file from a project directory
• A set of scripts launching and configuring the runtime for a Mendix app
• A NixOS module that automatically spawns an app container instance
Conclusion
• You can declaratively deploy a system with a Mendix app
container by running a single command-line instruction
{pkgs, ...}:
{
require = [ ../nixpkgs-mendix/nixos/modules/mendixappcontainer.nix ];
services = {
openssh.enable = true;
mendixAppContainer = {
enable = true;
adminPassword = "secret";
databaseType = "HSQLDB";
databaseName = "myappdb";
DTAPMode = "D";
app = import ../../conferenceschedule.nix {
inherit pkgs;
inherit (pkgs.stdenv) system;
};
};
};
networking.firewall.allowedTCPPorts = [ 8080 ];
}
Future work
• Try Disnix. Deploy multiple apps to multiple machines. Manage
databases and connections between apps and database.
Optionally: manage state/snapshots
• Try NixOS test driver. Instantly spawn NixOS virtual machines
to run integration tests
References
• The NixOS project web site (http://nixos.org)
• Nix package manager (http://nixos.org/nix)
• The package manager can also be used on conventional Linux
distributions and other Unix-like systems, such as macOS and Cygwin
• nixpkgs-mendix (http://github.com/mendix/nixpkgs-mendix)

More Related Content

What's hot

Lessons from running potentially malicious code inside containers
Lessons from running potentially malicious code inside containersLessons from running potentially malicious code inside containers
Lessons from running potentially malicious code inside containersBen Hall
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOpsОмские ИТ-субботники
 
QNAP COSCUP Container Station
QNAP COSCUP Container StationQNAP COSCUP Container Station
QNAP COSCUP Container StationWu Fan-Cheng
 
Docker and friends at Linux Days 2014 in Prague
Docker and friends at Linux Days 2014 in PragueDocker and friends at Linux Days 2014 in Prague
Docker and friends at Linux Days 2014 in Praguetomasbart
 
Small, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeSmall, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeDocker, Inc.
 
Docker & FieldAware
Docker & FieldAwareDocker & FieldAware
Docker & FieldAwareJakub Jarosz
 
Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Ben Hall
 
CoreOS in a Nutshell
CoreOS in a NutshellCoreOS in a Nutshell
CoreOS in a NutshellCoreOS
 
How to create your own hack environment
How to create your own hack environmentHow to create your own hack environment
How to create your own hack environmentSumedt Jitpukdebodin
 
Enjoying k8s cluster with Minikube and Helm
Enjoying k8s cluster with Minikube and HelmEnjoying k8s cluster with Minikube and Helm
Enjoying k8s cluster with Minikube and Helmロフト くん
 
Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計Koichi Nagaoka
 
Docker 初探,實驗室中的運貨鯨
Docker 初探,實驗室中的運貨鯨Docker 初探,實驗室中的運貨鯨
Docker 初探,實驗室中的運貨鯨Ruoshi Ling
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for DummiesŁukasz Proszek
 
Building Docker images with Puppet
Building Docker images with PuppetBuilding Docker images with Puppet
Building Docker images with PuppetNick Jones
 
Testing Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsTesting Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsAll Things Open
 
Building a Docker v1.12 Swarm cluster on ARM
Building a Docker v1.12 Swarm cluster on ARMBuilding a Docker v1.12 Swarm cluster on ARM
Building a Docker v1.12 Swarm cluster on ARMTeam Hypriot
 
CoreOS: Control Your Fleet
CoreOS: Control Your FleetCoreOS: Control Your Fleet
CoreOS: Control Your FleetMatthew Jones
 
Docker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよDocker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよYusuke Kon
 
Lessons from running potentially malicious code inside Docker containers
Lessons from running potentially malicious code inside Docker containersLessons from running potentially malicious code inside Docker containers
Lessons from running potentially malicious code inside Docker containersBen Hall
 

What's hot (20)

Lessons from running potentially malicious code inside containers
Lessons from running potentially malicious code inside containersLessons from running potentially malicious code inside containers
Lessons from running potentially malicious code inside containers
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
 
QNAP COSCUP Container Station
QNAP COSCUP Container StationQNAP COSCUP Container Station
QNAP COSCUP Container Station
 
Docker and friends at Linux Days 2014 in Prague
Docker and friends at Linux Days 2014 in PragueDocker and friends at Linux Days 2014 in Prague
Docker and friends at Linux Days 2014 in Prague
 
Small, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeSmall, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the Microscope
 
Docker & FieldAware
Docker & FieldAwareDocker & FieldAware
Docker & FieldAware
 
Docker up and running
Docker up and runningDocker up and running
Docker up and running
 
Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)
 
CoreOS in a Nutshell
CoreOS in a NutshellCoreOS in a Nutshell
CoreOS in a Nutshell
 
How to create your own hack environment
How to create your own hack environmentHow to create your own hack environment
How to create your own hack environment
 
Enjoying k8s cluster with Minikube and Helm
Enjoying k8s cluster with Minikube and HelmEnjoying k8s cluster with Minikube and Helm
Enjoying k8s cluster with Minikube and Helm
 
Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計Dockerを利用したローカル環境から本番環境までの構築設計
Dockerを利用したローカル環境から本番環境までの構築設計
 
Docker 初探,實驗室中的運貨鯨
Docker 初探,實驗室中的運貨鯨Docker 初探,實驗室中的運貨鯨
Docker 初探,實驗室中的運貨鯨
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
 
Building Docker images with Puppet
Building Docker images with PuppetBuilding Docker images with Puppet
Building Docker images with Puppet
 
Testing Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsTesting Wi-Fi with OSS Tools
Testing Wi-Fi with OSS Tools
 
Building a Docker v1.12 Swarm cluster on ARM
Building a Docker v1.12 Swarm cluster on ARMBuilding a Docker v1.12 Swarm cluster on ARM
Building a Docker v1.12 Swarm cluster on ARM
 
CoreOS: Control Your Fleet
CoreOS: Control Your FleetCoreOS: Control Your Fleet
CoreOS: Control Your Fleet
 
Docker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよDocker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよ
 
Lessons from running potentially malicious code inside Docker containers
Lessons from running potentially malicious code inside Docker containersLessons from running potentially malicious code inside Docker containers
Lessons from running potentially malicious code inside Docker containers
 

Similar to Automating Mendix application deployments with Nix

Deploying .NET applications with the Nix package manager
Deploying .NET applications with the Nix package managerDeploying .NET applications with the Nix package manager
Deploying .NET applications with the Nix package managerSander van der Burg
 
Techniques and lessons for improvement of deployment processes
Techniques and lessons for improvement of deployment processesTechniques and lessons for improvement of deployment processes
Techniques and lessons for improvement of deployment processesSander van der Burg
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with PuppetKris Buytaert
 
Docker DANS workshop
Docker DANS workshopDocker DANS workshop
Docker DANS workshopvty
 
Introduction to Docker and Monitoring with InfluxData
Introduction to Docker and Monitoring with InfluxDataIntroduction to Docker and Monitoring with InfluxData
Introduction to Docker and Monitoring with InfluxDataInfluxData
 
Deploying NPM packages with the Nix package manager
Deploying NPM packages with the Nix package managerDeploying NPM packages with the Nix package manager
Deploying NPM packages with the Nix package managerSander van der Burg
 
A Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentA Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentSander van der Burg
 
Best Practices for Running Kafka on Docker Containers
Best Practices for Running Kafka on Docker ContainersBest Practices for Running Kafka on Docker Containers
Best Practices for Running Kafka on Docker ContainersBlueData, Inc.
 
SPACK: A Package Manager for Supercomputers, Linux, and MacOS
SPACK: A Package Manager for Supercomputers, Linux, and MacOSSPACK: A Package Manager for Supercomputers, Linux, and MacOS
SPACK: A Package Manager for Supercomputers, Linux, and MacOSinside-BigData.com
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsMichael Lange
 
The NixOS project and deploying systems declaratively
The NixOS project and deploying systems declarativelyThe NixOS project and deploying systems declaratively
The NixOS project and deploying systems declarativelySander van der Burg
 
Настройка окружения для кросскомпиляции проектов на основе docker'a
Настройка окружения для кросскомпиляции проектов на основе docker'aНастройка окружения для кросскомпиляции проектов на основе docker'a
Настройка окружения для кросскомпиляции проектов на основе docker'acorehard_by
 
Docker and Puppet for Continuous Integration
Docker and Puppet for Continuous IntegrationDocker and Puppet for Continuous Integration
Docker and Puppet for Continuous IntegrationGiacomo Vacca
 
CD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas KolenkinCD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas KolenkinDataArt
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with PuppetKris Buytaert
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Patrick Chanezon
 

Similar to Automating Mendix application deployments with Nix (20)

The Nix project
The Nix projectThe Nix project
The Nix project
 
Deploying .NET applications with the Nix package manager
Deploying .NET applications with the Nix package managerDeploying .NET applications with the Nix package manager
Deploying .NET applications with the Nix package manager
 
The Nix project
The Nix projectThe Nix project
The Nix project
 
Dockerized maven
Dockerized mavenDockerized maven
Dockerized maven
 
Techniques and lessons for improvement of deployment processes
Techniques and lessons for improvement of deployment processesTechniques and lessons for improvement of deployment processes
Techniques and lessons for improvement of deployment processes
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with Puppet
 
Docker DANS workshop
Docker DANS workshopDocker DANS workshop
Docker DANS workshop
 
Introduction to Docker and Monitoring with InfluxData
Introduction to Docker and Monitoring with InfluxDataIntroduction to Docker and Monitoring with InfluxData
Introduction to Docker and Monitoring with InfluxData
 
Deploying NPM packages with the Nix package manager
Deploying NPM packages with the Nix package managerDeploying NPM packages with the Nix package manager
Deploying NPM packages with the Nix package manager
 
A Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentA Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software Deployment
 
Best Practices for Running Kafka on Docker Containers
Best Practices for Running Kafka on Docker ContainersBest Practices for Running Kafka on Docker Containers
Best Practices for Running Kafka on Docker Containers
 
SPACK: A Package Manager for Supercomputers, Linux, and MacOS
SPACK: A Package Manager for Supercomputers, Linux, and MacOSSPACK: A Package Manager for Supercomputers, Linux, and MacOS
SPACK: A Package Manager for Supercomputers, Linux, and MacOS
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
 
The NixOS project and deploying systems declaratively
The NixOS project and deploying systems declarativelyThe NixOS project and deploying systems declaratively
The NixOS project and deploying systems declaratively
 
Настройка окружения для кросскомпиляции проектов на основе docker'a
Настройка окружения для кросскомпиляции проектов на основе docker'aНастройка окружения для кросскомпиляции проектов на основе docker'a
Настройка окружения для кросскомпиляции проектов на основе docker'a
 
Docker and Puppet for Continuous Integration
Docker and Puppet for Continuous IntegrationDocker and Puppet for Continuous Integration
Docker and Puppet for Continuous Integration
 
CD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas KolenkinCD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas Kolenkin
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with Puppet
 
nuxt-en.pdf
nuxt-en.pdfnuxt-en.pdf
nuxt-en.pdf
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
 

More from Sander van der Burg

Dysnomia: complementing Nix deployments with state deployment
Dysnomia: complementing Nix deployments with state deploymentDysnomia: complementing Nix deployments with state deployment
Dysnomia: complementing Nix deployments with state deploymentSander van der Burg
 
Deploying (micro)services with Disnix
Deploying (micro)services with DisnixDeploying (micro)services with Disnix
Deploying (micro)services with DisnixSander van der Burg
 
Hydra: Continuous Integration and Testing for Demanding People: The Details
Hydra: Continuous Integration and Testing for Demanding People: The DetailsHydra: Continuous Integration and Testing for Demanding People: The Details
Hydra: Continuous Integration and Testing for Demanding People: The DetailsSander van der Burg
 
Hydra: Continuous Integration and Testing for Demanding People: The Basics
Hydra: Continuous Integration and Testing for Demanding People: The BasicsHydra: Continuous Integration and Testing for Demanding People: The Basics
Hydra: Continuous Integration and Testing for Demanding People: The BasicsSander van der Burg
 
A Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentA Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentSander van der Burg
 
A Generic Approach for Deploying and Upgrading Mutable Software Components
A Generic Approach for Deploying and Upgrading Mutable Software ComponentsA Generic Approach for Deploying and Upgrading Mutable Software Components
A Generic Approach for Deploying and Upgrading Mutable Software ComponentsSander van der Burg
 
Deploying .NET services with Disnix
Deploying .NET services with DisnixDeploying .NET services with Disnix
Deploying .NET services with DisnixSander van der Burg
 
A Self-Adaptive Deployment Framework for Service-Oriented Systems
A Self-Adaptive Deployment Framework for Service-Oriented SystemsA Self-Adaptive Deployment Framework for Service-Oriented Systems
A Self-Adaptive Deployment Framework for Service-Oriented SystemsSander van der Burg
 
Using NixOS for declarative deployment and testing
Using NixOS for declarative deployment and testingUsing NixOS for declarative deployment and testing
Using NixOS for declarative deployment and testingSander van der Burg
 
Disnix: A toolset for distributed deployment
Disnix: A toolset for distributed deploymentDisnix: A toolset for distributed deployment
Disnix: A toolset for distributed deploymentSander van der Burg
 
Automated Deployment of Hetergeneous Service-Oriented System
Automated Deployment of Hetergeneous Service-Oriented SystemAutomated Deployment of Hetergeneous Service-Oriented System
Automated Deployment of Hetergeneous Service-Oriented SystemSander van der Burg
 
Pull Deployment of Services: Introduction, Progress and Challenges
Pull Deployment of Services: Introduction, Progress and ChallengesPull Deployment of Services: Introduction, Progress and Challenges
Pull Deployment of Services: Introduction, Progress and ChallengesSander van der Burg
 
Software Deployment in a Dynamic Cloud
Software Deployment in a Dynamic CloudSoftware Deployment in a Dynamic Cloud
Software Deployment in a Dynamic CloudSander van der Burg
 
Atomic Upgrading of Distributed Systems
Atomic Upgrading of Distributed SystemsAtomic Upgrading of Distributed Systems
Atomic Upgrading of Distributed SystemsSander van der Burg
 
Model-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentModel-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentSander van der Burg
 
Model-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentModel-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentSander van der Burg
 
Model-driven Distributed Software Deployment laymen's talk
Model-driven Distributed Software Deployment laymen's talkModel-driven Distributed Software Deployment laymen's talk
Model-driven Distributed Software Deployment laymen's talkSander van der Burg
 

More from Sander van der Burg (19)

The Monitoring Playground
The Monitoring PlaygroundThe Monitoring Playground
The Monitoring Playground
 
Dysnomia: complementing Nix deployments with state deployment
Dysnomia: complementing Nix deployments with state deploymentDysnomia: complementing Nix deployments with state deployment
Dysnomia: complementing Nix deployments with state deployment
 
Deploying (micro)services with Disnix
Deploying (micro)services with DisnixDeploying (micro)services with Disnix
Deploying (micro)services with Disnix
 
Hydra: Continuous Integration and Testing for Demanding People: The Details
Hydra: Continuous Integration and Testing for Demanding People: The DetailsHydra: Continuous Integration and Testing for Demanding People: The Details
Hydra: Continuous Integration and Testing for Demanding People: The Details
 
Hydra: Continuous Integration and Testing for Demanding People: The Basics
Hydra: Continuous Integration and Testing for Demanding People: The BasicsHydra: Continuous Integration and Testing for Demanding People: The Basics
Hydra: Continuous Integration and Testing for Demanding People: The Basics
 
A Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software DeploymentA Reference Architecture for Distributed Software Deployment
A Reference Architecture for Distributed Software Deployment
 
A Generic Approach for Deploying and Upgrading Mutable Software Components
A Generic Approach for Deploying and Upgrading Mutable Software ComponentsA Generic Approach for Deploying and Upgrading Mutable Software Components
A Generic Approach for Deploying and Upgrading Mutable Software Components
 
Deploying .NET services with Disnix
Deploying .NET services with DisnixDeploying .NET services with Disnix
Deploying .NET services with Disnix
 
A Self-Adaptive Deployment Framework for Service-Oriented Systems
A Self-Adaptive Deployment Framework for Service-Oriented SystemsA Self-Adaptive Deployment Framework for Service-Oriented Systems
A Self-Adaptive Deployment Framework for Service-Oriented Systems
 
Using NixOS for declarative deployment and testing
Using NixOS for declarative deployment and testingUsing NixOS for declarative deployment and testing
Using NixOS for declarative deployment and testing
 
Pull Deployment of Services
Pull Deployment of ServicesPull Deployment of Services
Pull Deployment of Services
 
Disnix: A toolset for distributed deployment
Disnix: A toolset for distributed deploymentDisnix: A toolset for distributed deployment
Disnix: A toolset for distributed deployment
 
Automated Deployment of Hetergeneous Service-Oriented System
Automated Deployment of Hetergeneous Service-Oriented SystemAutomated Deployment of Hetergeneous Service-Oriented System
Automated Deployment of Hetergeneous Service-Oriented System
 
Pull Deployment of Services: Introduction, Progress and Challenges
Pull Deployment of Services: Introduction, Progress and ChallengesPull Deployment of Services: Introduction, Progress and Challenges
Pull Deployment of Services: Introduction, Progress and Challenges
 
Software Deployment in a Dynamic Cloud
Software Deployment in a Dynamic CloudSoftware Deployment in a Dynamic Cloud
Software Deployment in a Dynamic Cloud
 
Atomic Upgrading of Distributed Systems
Atomic Upgrading of Distributed SystemsAtomic Upgrading of Distributed Systems
Atomic Upgrading of Distributed Systems
 
Model-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentModel-driven Distributed Software Deployment
Model-driven Distributed Software Deployment
 
Model-driven Distributed Software Deployment
Model-driven Distributed Software DeploymentModel-driven Distributed Software Deployment
Model-driven Distributed Software Deployment
 
Model-driven Distributed Software Deployment laymen's talk
Model-driven Distributed Software Deployment laymen's talkModel-driven Distributed Software Deployment laymen's talk
Model-driven Distributed Software Deployment laymen's talk
 

Recently uploaded

Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Automating Mendix application deployments with Nix

  • 2. Modeling applications bring value to a broader audience than just developers
  • 3. Deployment is an important activity in an application’s development process Without deployment, an application can not be used by end users
  • 4. Deployment looks quite convenient for Mendix cloud portal users
  • 5. Actually managing app deployments is not
  • 6. Fortunately, there are automated deployment solutions
  • 7. No deployment solution is perfect So we must keep an open mind when integrating solutions
  • 8. The Nix project • Family of declarative deployment tools: • Nix. A purely functional package manager • NixOS. Nix-based GNU/Linux distribution • Hydra. Nix-based continuous integration service • NixOps. NixOS-based multi-cloud deployment tool • Disnix. Nix-based distributed service deployment tool
  • 9. The Nix package manager • The basis of all tools in the Nix project • Nix is a package manager borrowing concepts from purely functional programming languages • 𝑥 = 𝑦 → 𝑓 𝑥 = 𝑓(𝑦) • Reliably deploying a package = Invoking a pure function • Nix provides its own purely functional DSL
  • 10. Example Nix expression • A package is a function definition • Function parameters correspond to build dependencies • The mkDerivation {} function invocation composes a “pure” build environment • In a build environment, we can invoke almost any build/test tool we want { stdenv, fetchurl, acl }: stdenv.mkDerivation { name = "gnutar-1.30"; src = fetchurl { url = http://ftp.gnu.org/tar/tar-1.30.tar.xz; sha256 = "1lyjyk8z8hdddsxw0ikchrsfg3i0…"; }; buildCommand = '' tar xfv $src cd tar-1.30 ./configure --prefix=$out --with-acl=${acl} make make install ''; }
  • 11. Composing packages • We must compose packages by providing the desired versions of the dependencies as function parameters • Dependencies are composed in a similar way • Top level expression is an attribute set of function invocations rec { stdenv = import ... fetchurl = import ... acl = import ../pkgs/os-specific/linux/acl { inherit stdenv fetchurl …; }; gnutar = import ../pkgs/tools/archivers/gnutar { inherit stdenv fetchurl acl; }; ... }
  • 12. Enforcing purity • Nix imposes restrictions on builds: • Every package is stored in an isolated directory, not in global directories, such as /lib, /bin or C:WindowsSystem32 • Files are made read-only after build completion • Timestamps are reset to 1 second after the epoch • Search environment variables are cleared and configured explicitly, e.g. PATH • Private temp folders and designated output directories • Network access is restricted (except when an output hash is given) • Running builds as unprivileged users • Chroot environments, namespaces, bind-mounting dependency packages
  • 13. The Nix store • Every package is stored in isolation in the Nix store • Every package is prefixed by a 160-bit cryptographic hash of all inputs, such as: • Sources • Libraries • Compilers • Build scripts
  • 14. Invoke nix-build to build a package rec { stdenv = import ... fetchurl = import ... acl = import ../pkgs/os-specific/linux/acl { inherit stdenv fetchurl; }; gnutar = import ../pkgs/tools/archivers/gnutar { inherit stdenv fetchurl acl; }; ... }
  • 15. Some benefits of the purely functional model • Strong dependency completeness guarantees • Strong reproducibility guarantees • Build only the packages and dependencies that you need • Packages that don’t depend on each other can be built in parallel • Because of purity, we can also download a substitute from a remote machine (e.g. build server) if the hash prefix is identical • Because of purity, we can delegate a build to a remote machine
  • 16. Nix user environments • Users have convenient access to packages through a symlink tree (and generation symlinks)
  • 17. Packaging the Mendix runtime and mxbuild • Simply extract tarball and move content into the Nix store • I created a wrapper script that launches the runtime for convenience • I used a similar approach for mxbuild {stdenv, fetchurl, jre}: stdenv.mkDerivation { name = "mendix-7.13.1"; src = fetchurl { url = https://download.mendix.com/runtimes/mendix-7.13.1.tar.gz; sha256 = "1v620zmxm1s50p5jhpl74xvr0jv4j334cg1yfvy0mvgz4x0jrr7y"; }; installPhase = '' cd .. mkdir -p $out/libexec/mendix mv 7.13.1 $out/libexec/mendix mkdir -p $out/bin # Create wrapper script for the runtime launcher cat > $out/bin/runtimelauncher <<EOF #! ${stdenv.shell} -e export MX_INSTALL_PATH=$out/libexec/mendix/7.13.1 ${jre}/bin/java –jar $out/libexec/mendix/7.13.1/runtime/launcher/runtimelauncher.jar "$@" EOF chmod +x $out/bin/runtimelauncher ''; }
  • 18. Creating a function abstraction for building MDAs • We can create a Nix function abstraction that builds MDA (Mendix Deployment Archive) bundles from Mendix projects {stdenv, mxbuild, jdk, nodejs}: {name, mendixVersion, looseVersionCheck ? false, ...}@args: let mxbuildPkg = mxbuild."${mendixVersion}"; in stdenv.mkDerivation ({ buildInputs = [ mxbuildPkg nodejs ]; installPhase = '' mkdir -p $out mxbuild --target=package --output=$out/${name}.mda --java-home ${jdk} --java-exe-path ${jdk}/bin/java ${stdenv.lib.optionalString looseVersionCheck "--loose- version-check"} "$(echo *.mpr)" ''; } // args)
  • 19. Building an MDA from a Mendix project with Nix • We can invoke our function abstraction to build MDAs for any Mendix project we want. {packageMendixApp}: packageMendixApp { name = "conferenceschedule"; src = /home/sbu/ConferenceSchedule-main; mendixVersion = "7.13.1"; }
  • 20. Declarative deployment • Nix package deployment can be considered declarative deployment • You specify how packages are built from source and what their dependencies are • You don’t specify the deployment activities or the order in which builds need to be carried out • Being declarative means expressing what you want, not how to do something • Declarativity is a spectrum – hard to draw a line between what and how • Producing an MDA is not entirely what we want – we want a running system
  • 21. NixOS: deploying a Linux distribution declaratively {pkgs, ...}: { boot.loader.grub.device = "/dev/sda"; fileSystems."/".device = "/dev/sda1"; services = { openssh.enable = true; xserver = { enable = true; displayManager.sddm.enable = true; desktopManager.plasma5.enable = true; }; }; environment.systemPackages = [ pkgs.firefox ]; }
  • 22. NixOS: deploying a Linux distribution declaratively • Nix deploys all packages, configuration files and other static system parts in the Nix store. Generates a Nix user environment that contains all static parts of a system. • A bundled activation script takes care of setting up the dynamic parts of a system, e.g. starting systemd jobs, setting up /var etc. • Changing configuration.nix and running nixos-rebuild again -> upgrade
  • 24. Running an MDA • Unzip MDA file to a directory • Add writable state sub directories, e.g. data/files, data/tmp • Configure admin interface settings • Start runtime with the unpacked directory as parameter (Mendix 7.x) export M2EE_ADMIN_PORT=9000 export M2EE_ADMIN_PASS=secret java -jar $out/libexec/mendix/7.13.1/runtime/launcher/runtimelauncher.jar ConferenceSchedule
  • 25. Running an MDA • Instruct the app container to configure database, initialize database tables and start the app by communicating over the admin interface curlCmd="curl -X POST http://localhost:$M2EE_ADMIN_PORT -H 'Content-Type: application/json' -H 'X-M2EE-Authentication: $(echo -n "$M2EE_ADMIN_PASS" | base64)' -H 'Connection: close'" $curlCmd -d '{ "action": "update_appcontainer_configuration", "params": { "runtime_port": 8080 } }' $curlCmd -d '{ "action": "update_configuration", "params": { "DatabaseType": "HSQLDB", "DatabaseName": "myappdb", "DTAPMode": "D" } }' $curlCmd -d '{ "action": "execute_ddl_commands" }' $curlCmd -d '{ "action": "start" }'
  • 26. Composing a Mendix app container systemd job for NixOS • We can define a systemd job calling scripts that initialize state, configure the app container and launch the runtime. {pkgs, ...}: { systemd.services.mendixappcontainer = let mendixPkgs = import ../nixpkgs-mendix/top-level/all-packages.nix { inherit pkgs; }; appContainerConfigJSON = pkgs.writeTextFile { ... }; configJSON = pkgs.writeTextFile { name = "config.json"; text = builtins.toJSON { DatabaseType = "HSQLDB"; DatabaseName = "myappdb"; DTAPMode = "D"; }; }; runScripts = mendixPkgs.runMendixApp { app = import ../conferenceschedule.nix { inherit (mendixPkgs) packageMendixApp; }; }; in { enable = true; description = "My Mendix App"; wantedBy = [ "multi-user.target" ]; environment = { M2EE_ADMIN_PASS = "secret"; M2EE_ADMIN_PORT = "9000"; MENDIX_STATE_DIR = "/home/mendix"; }; serviceConfig = { ExecStartPre = "${runScripts}/bin/undeploy-app"; ExecStart = "${runScripts}/bin/start-appcontainer"; ExecStartPost = "${runScripts}/bin/configure-appcontainer ${appContainerConfigJSON} ${configJSON}"; }; }; }
  • 27. Composing a NixOS module • We can create a module abstraction over the properties that we need to configure to run a Mendix app container { config, lib, pkgs, ... }: let cfg = config.services.mendixAppContainer; in { options = { services.mendixAppContainer = { enable = mkOption { type = types.bool; default = false; description = "Whether to enable the Mendix app container."; }; adminPort = mkOption { type = types.int; default = 9000; description = "TCP port where the admin interface listens to."; }; runtimePort = mkOption { type = types.int; default = 8080; description = "TCP port where the embedded Jetty HTTP server listens to."; }; databaseType = mkOption { type = types.string; default = "HSQLDB"; description = "Type of database to use for storage. Possible options are 'HSQLDB' (the default) or 'PostgreSQL’”; }; app = mkOption { type = types.package; description = "Mendix MDA to deploy"; }; ... }; }; config = mkIf cfg.enable { systemd.services.mendixappcontainer = { ... }; }; }
  • 28. A simple configuration running a Mendix app • With our custom NixOS module, we can concisely express our desired app container properties {pkgs, ...}: { require = [ ../nixpkgs-mendix/nixos/modules/mendixappcontainer.nix ]; services = { openssh.enable = true; mendixAppContainer = { enable = true; adminPassword = "secret"; databaseType = "HSQLDB"; databaseName = "myappdb"; DTAPMode = "D"; app = import ../../conferenceschedule.nix { inherit pkgs; inherit (pkgs.stdenv) system; }; }; }; networking.firewall.allowedTCPPorts = [ 8080 ]; }
  • 29. A more complete deployment scenario • We can add a PostgreSQL database and nginx reverse proxy to our NixOS configuration. • We can use the NixOS module system to integrate our Mendix app. {pkgs, config, ...}: { services = { postgresql = { enable = true; enableTCPIP = true; package = pkgs.postgresql94; }; nginx = { enable = true; config = '' http { upstream mendixappcontainer { server 127.0.0.1:${toString config.services.mendixAppContainer.runtimePort}; } server { listen 0.0.0.0:80; server_name localhost; root ${config.services.mendixAppContainer.stateDir}/web location @runtime { proxy_pass http://mendixappcontainer; } location / { try_files $uri $uri/ @runtime; proxy_pass http://mendixappcontainer; } } } ''; }; mendixAppContainer = { databaseType = "PostgreSQL"; ... }; }; networking.firewall.allowedTCPPorts = [ 80 ]; }
  • 30. Conclusion • I gave an introduction to Nix and NixOS • I have implemented the following features: • A Nix function that builds an MDA file from a project directory • A set of scripts launching and configuring the runtime for a Mendix app • A NixOS module that automatically spawns an app container instance
  • 31. Conclusion • You can declaratively deploy a system with a Mendix app container by running a single command-line instruction {pkgs, ...}: { require = [ ../nixpkgs-mendix/nixos/modules/mendixappcontainer.nix ]; services = { openssh.enable = true; mendixAppContainer = { enable = true; adminPassword = "secret"; databaseType = "HSQLDB"; databaseName = "myappdb"; DTAPMode = "D"; app = import ../../conferenceschedule.nix { inherit pkgs; inherit (pkgs.stdenv) system; }; }; }; networking.firewall.allowedTCPPorts = [ 8080 ]; }
  • 32. Future work • Try Disnix. Deploy multiple apps to multiple machines. Manage databases and connections between apps and database. Optionally: manage state/snapshots • Try NixOS test driver. Instantly spawn NixOS virtual machines to run integration tests
  • 33. References • The NixOS project web site (http://nixos.org) • Nix package manager (http://nixos.org/nix) • The package manager can also be used on conventional Linux distributions and other Unix-like systems, such as macOS and Cygwin • nixpkgs-mendix (http://github.com/mendix/nixpkgs-mendix)