{"id":3342,"date":"2018-03-28T13:00:01","date_gmt":"2018-03-28T11:00:01","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=3342"},"modified":"2023-08-06T21:49:57","modified_gmt":"2023-08-06T19:49:57","slug":"ci-cd-infrastructure-choosing-and-setting-up-a-server-with-jenkins-as-docker-image","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/ci-cd-infrastructure-choosing-and-setting-up-a-server-with-jenkins-as-docker-image\/","title":{"rendered":"CI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image"},"content":{"rendered":"<p style=\"text-align: left; margin-bottom: 10px;\"><em>Related articles:&nbsp;\u25ba<a href=\"https:\/\/wp.me\/p71Rzi-Tb\">Take Me Home &#8211; Project Overview<\/a>&nbsp; \u25ba<a href=\"https:\/\/wp.me\/p71Rzi-RH\">Android SDK and emulator in Docker for testing<\/a>&nbsp; \u25ba<a href=\"https:\/\/wp.me\/p71Rzi-SN\">Automated Unit- and GUI-Testing for Android in Jenkins<\/a>&nbsp; \u25ba<a href=\"https:\/\/wp.me\/p71Rzi-SQ\">Testing a MongoDB with NodeJS, Mocha and Mongoose<\/a><\/em><\/p>\n<hr style=\"padding-top: 1px;\">\n<p>This article will run you through the <a href=\"#intro\">motivation<\/a> for a continuous integration and delivery, <a href=\"#choosetool\">choosing a corresponding tool<\/a> and a server to run it on. It will give you a brief overview over<a href=\"#bluemix\"> IBM Bluemix and kubernetes <\/a>as server solution and then discuss the <a href=\"#virtualmachine\">application for a virtual machine inside a company<\/a>. There are some useful instructions (for beginners) on <a href=\"#putty\">generating key-pairs for the server on Windows<\/a>. Next there is a motivation <a href=\"#jenkinsdocker\">why to run Jenkins (the CI tool of choice) as docker container<\/a> and gives some <a href=\"#dockergetstarted\">instructions to get started<\/a>. Finally, <a href=\"#problems\">frequent problems are discussed <\/a>which hopefully save some of your time.<br \/>\n<!--more--><\/p>\n<h1 id=\"intro\">Intro<\/h1>\n<p>In the last years, agile methods like Scrum have become very popular. The main principles, (aka as <a href=\"http:\/\/agilemanifesto.org\/\">\u2018The Agile Manifest\u2019<\/a>) are individuals and interaction over processes an tools, collaboration with the customer over contracts, responding to changes over a strict plan and \u2013 most important in context of this blog entry \u2013 working software over comprehensive documentation. Well, let\u2019s not go into details with the importance of documentation but focus on the \u201cworking software\u201d. One might have heard of the iterative incremental model in agile methods, especially in Scrum. Iterative as development in iterations, e.g. in sprints. After each iteration an increment, a \u201cworkings software\u201d, a compileable, runnable and shippable artefact is produced. This is important in different points of view: the customer can look at the product as it is right now and so can be part of the process. Also, there is less documentation needed during development as one can look at working features and the danger of developing something the customer doesn\u2019t want is minimized. And finally, there will not be a long and tedious integration and deployment\/delivery phase at the end of the project.<\/p>\n<p>To be able to ship an artefact after each iteration (e.g. each two weeks) we somehow need to automate this process. This is the birth of DevOps. DevOps is the merge of development and operations with the goal to test, build and release software fast, frequently and reliable. This leads to an automated toolchain, in which a single change in code by a programmer can result in a new production release.A programmer now has impact on a productive system and needs to think about configuring and running the software securely. We will setup a server for this purpose and install a CI tool.<\/p>\n<h1 id=\"choosetool\">Choosing a continuous integration\/delivery (CI\/CD) tool<\/h1>\n<p>A popular (most popular?) continuous integration tool is Jenkins, former known as Hutson. Before looking into the problem of hosting and setting up your Jenkins, you should be sure Jenkins is the right choice. Most recently the big git repository suppliers (gitlab, bitbucket ect.) ship with continuous integration and deployment out of the box. The big advantage: you do not have to care about maintaining the CI\/CD server and software. Jenkins is (today) still the more mature tool, simply because it\u2019s wide spread, open source and has a lot of plugins.<\/p>\n<p>There is another article on choosing the right tool <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/03\/01\/game-project-build-system\/\">here<\/a>.<\/p>\n<p>While looking for a suitable server to setup Jenkins we were looking into Bluemix (with a free education license), a KVM based VM (Ubuntu) hosted by our university and into scaleway, one of the many server suppliers you will find by googling something like \u201conline server\u201d.<\/p>\n<h1 id=\"bluemix\">Looking for a server: Experience with Bluemix and Kubernetes<\/h1>\n<p><strong>tl:dr<\/strong> Bluemix is overkill for a student\u2019s project, and overkill for a small application, in which load balancing, scaling and worldwide distribution is not important. Same counts for Kubernetes.<\/p>\n<p>First you will have to register with IBM. There is an education program amongst others \u2013 but you will get only restricted access to the features.<\/p>\n<div class=\"mceTemp\">\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3405\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/ci-cd-infrastructure-choosing-and-setting-up-a-server-with-jenkins-as-docker-image\/bluemix-2\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2.png\" data-orig-size=\"1499,781\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"bluemix (2)\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2-1024x534.png\" class=\"wp-image-3405 size-large\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2-1024x534.png\" alt=\"\" width=\"656\" height=\"342\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2-1024x534.png 1024w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2-300x156.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2-768x400.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/bluemix-2.png 1499w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/a><\/p>\n<p>Figure 1 &#8211; Layers setting up Jenkins on bluemix IBM. DMZ = Demilitarized ZoneOnce registered, you can create a free <em>lite-cluster<\/em>. In a cluster you have worker (nodes) \u2013 well, with the<em> lite-cluster<\/em> its only on node. Inside this node you can deploy several containers. &nbsp;To deploy a container, you must upload an image to you own IBM image registry (you might know Docker Hub \u2013 it\u2019s something like that). Once the image is uploaded, you can use Kubernetes to deploy a container of your image, see Figure 1.<\/p>\n<p>For the interaction with Bluemix install the Bluemix CLI and Kubernetes CLI. <a href=\"https:\/\/console.bluemix.net\/docs\/services\/Registry\/index.html#index\">Here<\/a> is a detailed description for the image upload, and <a href=\"https:\/\/console.bluemix.net\/docs\/containers\/cs_cli_install.html#cs_cli_install\">here<\/a> one for the Kubernetes installation.<\/p>\n<p>There are two things you have to deploy with Kubernetes: your server container (<a href=\"https:\/\/console.bluemix.net\/docs\/containers\/cs_app.html#app_cli\">Tutorial<\/a>) and a service, which maps the internal ports (inside the node) to external reachable ports (<a href=\"https:\/\/console.bluemix.net\/docs\/containers\/cs_nodeport.html#nodeport\">Tutorial<\/a>).<\/p>\n<p>See here for some simple example <em>yaml<\/em> files <a href=\"https:\/\/github.com\/cpflaume\/bluemix-scripts\">https:\/\/github.com\/cpflaume\/bluemix-scripts<\/a>.<\/p>\n<p>So far so good. The only thing that tipped us off with the free Bluemix account is, that you cannot persist any data \u2013 this feature is hidden behind a paywall. Buying data (50GB for $2\/Month) sounded not too bad, but don\u2019t! Even if you buy such a volume, you are not allowed to connect it to your free cluster. There exists a workaround we did not get into detail with, see <a href=\"https:\/\/github.com\/dev4cloud\/kubernetes\">here<\/a>.<\/p>\n<p>Conclusion: Quite a setup overhead, does only make sense if you plan something big.<\/p>\n<h1 id=\"virtualmachine\">Looking for a server: Virtual server hosted by you company (or your university)<\/h1>\n<p><strong>tl:dr<\/strong> The biggest drawback using resources you are not able to administrate yourself is time. Any problem will result in a call\/ticket\/email and it will take days until these problems are fixed. Besides that, it is a good solution, as you can make nearly everything possible and your server is a real virtualized server and not \u201conly\u201d a docker container (there is a difference!).<\/p>\n<h2>Request a server<\/h2>\n<p>Find out who is responsible and make sure to keep in with this person. Most properly you will have further requests and problems you need help with. You might be asked to provide a public ssh key \u2013 this key will be added to the <em>~\/.ssh\/authorized_keys<\/em> file. This allows the user (e.g. root) to log in without a password, but by proofing the possession of the private key. The good thing is, that you do not have to exchange any password with you server administrator and there is no problem with unsafe passwords.<\/p>\n<h3 id=\"putty\">Generating a key pair<\/h3>\n<p>On windows I recommend to use the PuTTY Key Generator&nbsp; (Look <a href=\"https:\/\/www.chiark.greenend.org.uk\/~sgtatham\/putty\/latest.html\">here<\/a>&nbsp;for puttygen.exe )<\/p>\n<p>Open the PuTTY Key Generator, click generate and move your mouse in the field under the progress bar (adds randomness). Add a key comment that helps you to remember, what you generated this key for.<\/p>\n<p>Your public key in OpenSSH format is displayed in the top field.<\/p>\n<p>Click \u201cSave private key\u201d and store it to a location you will find it again and you never lose it. It\u2019s a \u201c<em>PuTTY-User-Key-File<\/em>\u201d and contains private and public key.<\/p>\n<p>Note: There are different formats for public and private keys. The most common one is the OpenSSH format. If you save a key with putty, it\u2019s NOT the OpenSSH format, but in the \u201cThe Secure Shell (SSH) Public Key File Format\u201d (RFC 4716) format. If you need the OpenSSH private key, you have to export it correspondingly (Conversions \u00e0 Export OpenSSH key) and for the public key just copy the shown text.<\/p>\n<div class=\"mceTemp\">\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3401\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/ci-cd-infrastructure-choosing-and-setting-up-a-server-with-jenkins-as-docker-image\/puttygen\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen.png\" data-orig-size=\"921,908\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"PuTTY Key Generator\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;Converting and extracting keys in different formats&lt;\/p&gt;\n\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen.png\" class=\"wp-image-3401 size-full\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen.png\" alt=\"\" width=\"921\" height=\"908\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen.png 921w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen-300x296.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/puttygen-768x757.png 768w\" sizes=\"auto, (max-width: 921px) 100vw, 921px\" \/><\/a><\/p>\n<p>Figure 2 &#8211; Converting and extracting keys in different formats<\/p>\n<h3>How to tell which format<\/h3>\n<p>Public OpenSSH key example:<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">ssh-rsa AAAAB3N \u2026 bmhSw== rsa-key-2018-comment<\/pre>\n<p>Public RFC4714 key example<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">---- BEGIN SSH2 PUBLIC KEY ----\nComment: \"rsa-key-2018-comment\"\nAAAAB3N \u2026&nbsp; bmhSw==\n---- END SSH2 PUBLIC KEY ----<\/pre>\n<p>If you have a Linux machine just use the command line tool <em>\u201cssh-keygen<\/em>\u201d.<\/p>\n<h2>Log onto the server with Putty<\/h2>\n<p>I still assume you use windows. If you haven\u2019t already download Putty \u2013 it\u2019s an SSH Client. Enter the host name (or ip address) of you server. The standard port is 22, connection type SSH.<\/p>\n<p><strong>Tip<\/strong>: If you add the username of the user you want to use to login as prefix to the host name, you do not have to type it every time, e.g. <a href=\"mailto:root@myserver.de\">root@myserver.de<\/a><\/p>\n<p>Now you must provide the private key file to use for this connection.<\/p>\n<p>Click on the + left to Connection -&gt; SSH.<\/p>\n<p>Click on \u201cAuth\u201d<\/p>\n<p>Click on \u201cBrowse\u2026\u201d and add the path of the private key file stored before.<\/p>\n<p>Now go back to Session by clicking on \u201cSession\u201d (top entry in the left menu, you might have to scroll). Before you open the connection, you want to save it for the future. Type a name in the field under \u201cSaved Sessions\u201d \u2013 I always use the hostname. Then press \u201cSave\u201d.<\/p>\n<p>Finally: Click \u201cOpen\u201d \u2013 and you should be connected to you server.<\/p>\n<p><strong>Tip<\/strong>: For establishing a new connection, just double click on the saved session.<\/p>\n<h1 id=\"jenkinsdocker\">Jenkins as docker image<\/h1>\n<p>Even though we are on a real server now we decided to deploy our Jenkins as Docker container. We need to think maintainability: a new version of Jenkins? No problem, kill the old container, start a new one. Move to another server? No problem, copy the user data and start the docker container on another server.<\/p>\n<p>There are two things to do: First, you need to make sure your data will not get lost. Achieve this by mounting the directory Jenkins stores all the information about jobs etc. to a directory on your server. If you kill the docker container now, the user data will still be persisted. Second, you must not install anything manually inside the docker container \u2013 because it will be gone after you kill the container. Instead, you need to change the image (the base of the containers). This is easy: you can write a Dockerfile and build an image from it. Our Dockerfile and image can be found here <a href=\"https:\/\/hub.docker.com\/r\/connydockerid\/jenkins-image-nodejs-android\/\">https:\/\/hub.docker.com\/r\/connydockerid\/jenkins-image-nodejs-android\/<\/a>. By documenting all required changes in the Dockerfile you will never get in a situation, in which upgrading or moving you server will become a nightmare because of all the hacky changes made nobody knows of anymore.<\/p>\n<p>Note: The only thing you might have to look after when moving your server is the authorization and authentication with other servers. In our case we must authorize only with Heroku \u2013 the platform we use for continuous delivery.<\/p>\n<h3 id=\"dockergetstarted\">Docker explained in two paragraphs<\/h3>\n<p>Docker images are like prepared operating systems with some software already installed. You can assemble you own images by choosing an existing image as base and extending it. You do this by writing a Dockerfile and telling docker to build an image after these instructions.<\/p>\n<div class=\"mceTemp\">\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/docker-example.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3403\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/ci-cd-infrastructure-choosing-and-setting-up-a-server-with-jenkins-as-docker-image\/docker-example\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/docker-example.png\" data-orig-size=\"271,219\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"docker-example\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;Docker Container mounts a directory on the host and maps to port 3080 on the host. A corresponding docker command could be:  docker run -p 3080:80 -v ~\/container_mount_point:\/var\/www jenkins\/jenkins:lts&lt;\/p&gt;\n\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/docker-example.png\" class=\"wp-image-3403 size-full\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/docker-example.png\" alt=\"\" width=\"271\" height=\"219\"><\/a><\/p>\n<p>Figure 3 &#8211; Docker Container mounts a directory on the host and maps to port 3080 on the host. A corresponding docker command could be: docker run -p 3080:80 -v ~\/container_mount_point:\/var\/www jenkins\/jenkins:ltsDocker containers based on an docker image. By running a container, you start an instance of the image. A container behaves like another server\/machine. Things to configure a container with: mount a volume to persist\/access data, configure the network (e.g. map ports), run commands inside the container, e.g. via an interactive shell.<\/p>\n<h3>Install docker<\/h3>\n<p>I don\u2019t want to go into detail. There is detailed description on <a href=\"https:\/\/docs.docker.com\/install\/\">https:\/\/docs.docker.com\/install\/<\/a> for all common operating systems.<\/p>\n<p>If you are new to docker, here is a useful cheat sheet: <a href=\"https:\/\/www.docker.com\/sites\/default\/files\/Docker_CheatSheet_08.09.2016_0.pdf\">https:\/\/www.docker.com\/sites\/default\/files\/Docker_CheatSheet_08.09.2016_0.pdf<\/a><\/p>\n<h3>Start a Jenkins docker container<\/h3>\n<p>First you need to pull an image. You can use the plain Docker Jenkins image from <a href=\"https:\/\/hub.docker.com\/r\/jenkins\/jenkins\/\">https:\/\/hub.docker.com\/r\/jenkins\/jenkins\/<\/a>, our adjusted image <a href=\"https:\/\/hub.docker.com\/r\/connydockerid\/jenkins-image-nodejs-android\/\">https:\/\/hub.docker.com\/r\/connydockerid\/jenkins-image-nodejs-android\/<\/a> or build one yourself. If you build on yourself you have to build it on the server with the \u201cdocker build \u2026\u201d command, or build it anywhere and upload it to a docker registry like <a href=\"https:\/\/hub.docker.com\">https:\/\/hub.docker.com<\/a>.<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">docker pull connydockerid\/jenkins-image-nodejs-android:latest<\/pre>\n<p>Now run the container with the following command:<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">docker run -p 80:8080 -v \/data\/jenkins_mount_point:\/var\/jenkins_home connydockerid\/jenkins-image-nodejs-android:latest<\/pre>\n<p>Note: Jenkins runs by default on port 8080.<\/p>\n<p>Explained:<\/p>\n<p><strong><em>docker run [\u2026] connydockerid\/jenkins-image-nodejs-android:latest<\/em><\/strong>&nbsp;starts a container of the provided image<\/p>\n<p><em><strong>-p 80:8080<\/strong><\/em><br \/>\nMaps the port 8080 of the container to the port 80 of the host (our server). Jenkins will be running on port 8080 inside the container and will be reachable on port 80 on our server with this configuration, e.g. <a href=\"http:\/\/www.myserver.com:80\">myserver.com:80<\/a> (yes, 80 is default, but for the sake of clarity\u2026).<\/p>\n<p><strong><em>-v \/data\/jenkins_mount_point:\/var\/jenkins_home<\/em><\/strong><br \/>\nMounts the \/var\/jenkins_home directory to \/data\/jenkins_mount_point on the host. Jenkins will store all data in this directory. Persisting it will persist the state of Jenkins.<\/p>\n<p>If everything worked out, you should now be able to reach your server.<\/p>\n<h3>Useful commands<\/h3>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">#Lists all containers, running and not running\n\n<pre wp-pre-tag-4=\"\"><\/pre>\n<p>nbsp; docker ps -a<\/p>\n<p># Starts an interactive shell in the container<\/p>\n<pre wp-pre-tag-4=\"\"><\/pre>\n<p>nbsp; docker exec -it CONTAINER_ID \/bin\/bash<\/p>\n<p># Starts|stops a container<\/p>\n<pre wp-pre-tag-4=\"\"><\/pre>\n<p>nbsp; docker start|stop CONTAINER<\/p>\n<h1 id=\"problems\">Frequent Problems with our virtual server<\/h1>\n<h3>Request timeout trying to access something in the internet from the server<\/h3>\n<p>This could be a firewall issue: Most companies and universities have strict firewall rules which do not allow to communicate on nonstandard ports \/ protocols. If you have for example an external hosted MongoDB like mlab you will communicate with this database on a nonstandard port like 5342. A timeout can be a hint to a firewall issue.<\/p>\n<h3>No internet \/ no DNS<\/h3>\n<p>Maybe an issue with your DNS \u2013 any requests using a domain name will fail. Execute the following command to investigate<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\n<pre wp-pre-tag-5=\"\"><\/pre>\n<p>nbsp; nslookup google.com<br \/>\nIf the response is \u201cserver can&#8217;t find google.com: SERVFAIL\u201d contact you administrator and tell him you DNS does not work.<\/p>\n<h3>Cannot reach my server from outside<\/h3>\n<p>You might have started several containers. Only one of them can occupy the port 80 \u2013 you might have used other (nonstandard) ports for the other containers. And there it is again: nonstandard. This could be again a firewall issue. Contact you administrator and ask him to open those ports.<\/p>\n<h1>Conclusion<\/h1>\n<p>There is no perfect solution to all problems. You have to consider many aspects like project size, project requirements, technologies and your operational environment before setting up a continuous integration and delivery environment. The solution must fit the problem and you should reflect every now and then how (or if) you benefit from the system you set up.<\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Related articles:&nbsp;\u25baTake Me Home &#8211; Project Overview&nbsp; \u25baAndroid SDK and emulator in Docker for testing&nbsp; \u25baAutomated Unit- and GUI-Testing for Android in Jenkins&nbsp; \u25baTesting a MongoDB with NodeJS, Mocha and Mongoose This article will run you through the motivation for a continuous integration and delivery, choosing a corresponding tool and a server to run it [&hellip;]<\/p>\n","protected":false},"author":580,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,659,650,651,2],"tags":[46,150,78,153,154,152,151],"ppma_author":[742],"class_list":["post-3342","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-devops","category-scalable-systems","category-system-designs","category-system-engineering","tag-bluemix","tag-ci-cd","tag-jenkins","tag-key-generation","tag-kubernetes","tag-putty","tag-server"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":3421,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/take-me-home-project-overview\/","url_meta":{"origin":3342,"position":0},"title":"Take Me Home &#8211; Project Overview","author":"cp054","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0\u25baDockerizing Android SDK and Emulator for testing\u00a0 \u25baAutomated Unit- and GUI-Testing for Android in Jenkins\u00a0 \u25baTesting a MongoDB with NodeJS, Mocha and Mongoose During the winter term 2017\/2018, we created an app called Take Me Home. The\u2026","rel":"","context":"In &quot;Mobile Apps&quot;","block_context":{"text":"Mobile Apps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/mobile-apps\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":3329,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/android-sdk-and-emulator-in-docker-for-testing\/","url_meta":{"origin":3342,"position":1},"title":"Android SDK and emulator in Docker for testing","author":"Michael Laemmle","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baTake Me Home - Project Overview\u00a0 \u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0 \u25baAutomated Unit- and GUI-Testing for Android in Jenkins\u00a0 \u25baTesting a MongoDB with NodeJS, Mocha and Mongoose During our Android development project, we had to cope with several technological and organizational\u2026","rel":"","context":"In &quot;Mobile Apps&quot;","block_context":{"text":"Mobile Apps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/mobile-apps\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":3397,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/automated-unit-and-gui-testing-for-android-in-jenkins\/","url_meta":{"origin":3342,"position":2},"title":"Automated Unit- and GUI-Testing for Android in Jenkins","author":"Benedikt Schrade","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baTake Me Home - Project Overview\u00a0 \u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0\u25baAndroid SDK and emulator in Docker for testing\u00a0 \u00a0\u25baTesting a MongoDB with NodeJS, Mocha and Mongoose In this article we would like to describe, how to write unit- and gui-tests for\u2026","rel":"","context":"In &quot;Mobile Apps&quot;","block_context":{"text":"Mobile Apps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/mobile-apps\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1924,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/02\/28\/microservices-legolizing-software-development-4\/","url_meta":{"origin":3342,"position":3},"title":"Microservices \u2013 Legolizing Software Development IV","author":"Calieston Varatharajah, Christof Kost, Korbinian Kuhn, Marc Schelling, Steffen Mauser","date":"28. February 2017","format":false,"excerpt":"An automated development environment will save you. We explain how we set up Jenkins, Docker and Git to work seamlessly together.","rel":"","context":"In &quot;System Designs&quot;","block_context":{"text":"System Designs","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/draw_io_docker_small-1024x439.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/draw_io_docker_small-1024x439.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/draw_io_docker_small-1024x439.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":3822,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/08\/05\/3822\/","url_meta":{"origin":3342,"position":4},"title":"Web Performance Optimization for Continuous Deployment &#8211; Move fast and don&#8217;t lose performance","author":"Benjamin Kowatsch","date":"5. August 2018","format":false,"excerpt":"The performance of websites today is a decisive factor in how many users visit them and thus how much money can be earned from them. The impact of this fact is further enhanced by the widespread use of mobile devices and the speed of the mobile Internet. To counteract the\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3314,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/continuous-integration-deployment-for-a-cross-platform-application-part-1\/","url_meta":{"origin":3342,"position":5},"title":"Continuous Integration &#038; Deployment for a Cross-Platform Application &#8211; Part 1","author":"Tobias Eberle, Marco Maisel, Tobias Staib, Mario Walz","date":"28. March 2018","format":false,"excerpt":"When we started the project \"Flora CI\" for the lecture \"System Engineering\", we planned to deal with Continuous Integration. As an important aspect of software engineering all of us have previously been involved in projects where code of developers had to be merged and builds had to be automated somehow.\u2026","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/devops\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/flora-app.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":742,"user_id":580,"is_guest":0,"slug":"cp054","display_name":"cp054","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/c8295f08a6e6de8d2431589b3c9e937e1a0c979b220df372a3d38d33bc918e72?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3342","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/580"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=3342"}],"version-history":[{"count":26,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3342\/revisions"}],"predecessor-version":[{"id":25488,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3342\/revisions\/25488"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=3342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=3342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=3342"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=3342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}