# Question
Title: How do I autostart Jenkins agent machines?
To save money, I would like a large number of agent machines to be stopped and started up only when needed. Better yet, a single VM should be copied and launched on demand.

I am using Google Cloud Platform.

I see the Kubernetes plugin, used in Jenkins X, as well as the VirtualBox Plugin, but I get the sense that Jenkins might not be designed for this.

What is the standard way, if any, to do this?

# Answer
We use AWS's EC2 Plugin to spin up spot instances in AWS for our Jenkins master based on a single AMI, exactly as you describe, so Jenkins does support this behavior.

From a quick bit of searching Google Cloud seems to offer a similar solution;

> Spotinst’s Jenkins Plugin helps you to do more with your Jenkins setup by allowing you to automatically configure and scale a designated Google Compute Engine Preemptible VM as Slaves up and down depending on the number jobs to be completed.
> 1 votes

# Answer
Google just announced this Jenkins plugin for GCE , which does support autoscaling.
> 0 votes

---
Tags: jenkins, kubernetes, google-cloud-platform, virtualization, google-compute-engine
---


# Question
Title: Is it possible to set up Microsoft Sql Server in a scalable way?
I am working on some architecture where we need to have a Microsoft Sql Server database that is scalable, with one writable master and many read-only slaves. Ideally I should be able to hit a load balancer of some kind, and if it is a write, it goes to the master, and if it is a read it is load balanced through the slaves. Some kind of eventual consistency would update the slaves over time to match the data on the master.

I'm fairly sure that AWS and MySQL are capable of doing this out of the box pretty simply. However, I've got little knowledge of the Microsoft Sql Server side of things. One of my fellow architects insists it is impossible, but was not able to back up that statement with anything. We are hosting our microservices in Azure currently, but our databases are supposed to be on prem in our datacenter. This is a flagship project, so suffice it to say if there's a cool thing out there that we can use for scaling, we can probably convince our DBAs and Ops to use it for this project.

That said, things in the cloud for our DBs are out of the question at the moment.

# Answer
Not impossible, very easy in fact with read-only routing. Clients intending to be read-only specify it in their connect string, so this is per-session rather than per-statement. You can have up to 9 replicas in an availability group. With modern hardware and storage, that goes a long way to being “scalable” - 10’s of thousands of concurrent connections easily.
> 1 votes

---
Tags: load-balance, sql
---


# Question
Title: docker-compose local variable declare and use
In the programming language we can define and declare a **variable** and use it later in the program, can we do same in **docker-compose** file?

### For example in Java:

int **x** = 100; System.out.println("Number is: "+ **x**);
Similarly, in docker-compose file, can we declare a local variables and use it later.

### docker-compose file

In the docker-compose file we want to declare **tomcat\_home** as a variable and use it later as shown in example.

`values:
 - **tomcat_home**: "/usr/local/tomcat"`

`# Creating Tomcat Server 1`

`Server1:
 image: tomcat
 hostname: TomcatServer1
 container_name: TomcatServer1
 volumes:
 - ${PWD}/tomcat-users.xml:**${tomcat_home}**/conf/tomcat-users.xml
 - ${PWD}/server.xml:**${tomcat_home}**/conf/server.xml`

# Answer
> 2 votes
https://docs.docker.com/compose/environment-variables/#the-env-file

One could set a variable in an .env file:

```
TAG=1.2.3

```

and call it in a docker-compose file

docker-compose.yml

```
version: "3"
services:
  web:
    image: nginx:${TAG}
    ports:
    - 80:80

```

docker-compose up

returns:

```
Pulling web (nginx:1.2.3)...
ERROR: manifest for nginx:1.2.3 not found

```

No need to run docker-compose to check the config

According to the documentation one could run:

```
docker-compose config

```

to verify the docker-compose config

```
networks: {}
services:
  web:
    image: nginx:1.2.3
    ports:
    - 80:80/tcp
version: '3.0'
volumes: {}

```

# Answer
> 1 votes
For `docker-compose`, you can use either the environment or a `.env` file. For swarm mode, you can only use the environment. So for portability, I like to export variables into the shell or environment of the command being run.

From a bash shell, this would look like:

```
$ export tomcat_home=/usr/local/tomcat
$ docker-compose up

```

Depending on what you use to deploy your containers (shell script, custom code, some other CI/CD tool), exporting your environment variable will vary.

---
Tags: docker-compose
---


# Question
Title: Kubectl: the server doesn't have a resource type "cronjobs"
I ran minikube with:

```
minikube start --vm-driver=kvm2 --kubernetes-version=v1.8.0

```

status:

```
minikube: Running
cluster: Running
kubectl: Correctly Configured: pointing to minikube-vm at 192.168.39.93

```

However, running `kubectl get all` returns this error:

```
error: the server doesn't have a resource type "cronjobs"

```

Anyone have any idea what could be the reason for this?

# Answer
> 0 votes
The answer is appearently that there's a bug in Minikube 0.26. Downgrading the Minikube installation is solving it.

---
Tags: kubernetes, minikube
---


# Question
Title: How to bind ports for docker container in bitbucket pipelines?
I'd like to test an application using bitbucket pipelines with a custom docker image running some services. I have a dev docker image which runs all the services I need in order for tests to pass.

```
docker run -it -p 3000:3000 -p 6379:6379 -p 8983:8983 my_dockerhub/image
./start_services.sh
bundle exec rspec
# everything passes

```

I can't seem to find a way to start the container with the right ports bound so the tests to pass.

1. I tried using the container directly using this in my bitbucket-pipelines.yml:

```
image:
  name: my_dockerhub/image
  username: $DOCKER_HUB_USERNAME
  password: $DOCKER_HUB_PASSWORD
  email: $DOCKER_HUB_EMAIL
  # bind ports here somehow?

pipelines:
  branches:
    '{master, develop, bitbucket_pipelines}':
      - step:
          name: Test
          script:
            - ./start_services.sh
            - sleep 30
            - bundle exec rspec

```

But I get the following error at the `bundle exec rspec` step

```
# Errno::ECONNREFUSED:
#   Connection refused - connect(2) for "127.0.0.1" port 8983

```
2. I tried running the docker container directly within the bitbucket pipeline

```
pipelines:
  branches:
    '{master, develop, bitbucket_pipelines}':
      - step:
          name: Start Docker
          script:
            - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD
            - docker run -t -p 3000:3000 -p 6379:6379 -p 8983:8983  my_dockerhub/image
            - ./script/start_services.sh
            - sleep 20
            - bundle exec rspec

```

But the step froze at the `docker run` step. I assume this is because I used the -t flag so the command doesn't exit. I was thinking I could possibly use `docker exec` to send commands to the container without running it but then how would I check the tests have passed?

# Answer
> 4 votes
Try running with `-d detached` flag

`docker run -td -p 3000:3000 -p 6379:6379 -p 8983:8983 my_dockerhub/image
 # here ^` Containers started in detached mode exit when the root process used to run the container exits. This will prevent the step to freeze at `docker run` stage.

Docker docs -d flag

---
Tags: docker, bitbucket, bitbucket-pipelines
---


# Question
Title: Error while trying to run docker redis image on Alpine Linux 3.7.0
### Specifications

---

```
Microsoft Windows [Version 10.0.14393]
VirtualBox 5.2.8
Alpine Linux Extended 3.7.0

```

### Docker Info

---

```
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 17.10.0-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
runc version: 0351df1c5a66838d0c392b4ac4cf9450de844e2d
init version: 949e6facb77383876aeff8a6944dde66b3089574
Kernel Version: 4.9.65-1-hardened
Operating System: Alpine Linux v3.7
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.953GiB
Name: node-4
ID: 3AVF:5SGV:6Y3P:HQW4:PTSU:BRA7:R3PL:AW4F:CIFW:BYDY:FY5P:O6GX
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support

```

### Issue Description

---

I'm trying to run the `bitname-redis-docker` image on my `Alpine Linux` setup on VirtualBox.

```
docker run --name redis -e ALLOW_EMPTY_PASSWORD=yes bitnami/redis:latest

```

The container never starts. Inspecting the log it says

```
Welcome to the Bitnami redis container
Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-redis
Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-redis/issues
Send us your feedback at containers@bitnami.com

PROT_EXEC|PROT_WRITE failed.
INFO  ==> Starting redis...
sed: can't read /opt/bitnami/redis/conf/redis.conf: No such file or directory
14:C 26 Apr 19:38:43.389 # Fatal error, can't open config file '/opt/bitnami/redis/conf/redis.conf'

```

To further investigate I ran an `strace` and here is the log output link.

Can someone tell me what's going on here? Am I doing something wrong?

# Answer
> 1 votes
One could also use a docker image from an official docker repository like https://hub.docker.com/r/library/redis/

```
docker run --name some-redis -d redis:alpine

```

---
Tags: docker, docker-compose, docker-swarm, alpine
---


title: Teamcity web-interface does not work

text:
# Question
Title: Teamcity web-interface does not work
I have Teamcity on Windows machine.
When installed it, I selected the 8080 port.
I have another application on the 80 and 443 ports.
It worked fine, but now I see an error:

But if I open `localhost:8080` on a virtual machine - all works well.

1. What happened? Maybe you know :(
2. How I can change port or change working to "without SSL"?
3. How I can move all my projects to another Teamcity?

Thanks!

# Answer
Thaks for all answers. Teamcity began to work correctly when I installed all windows updates to my Windows Server 2012 R2. Maybe it depended with last Microsoft security update.
> 1 votes

---
Tags: windows, teamcity
---


# Question
Title: Cannot connect to server running on host from Dockerfile / image build
I have a server running on localhost:3440 on the host machine. In a Dockerfile I have:

```
RUN apt-get install -y netcat
RUN nc localhost 3440 | tar -x -O > ores-$(date +%s.%N).tgz

```

I've read that using `--net="host"` with `docker run` will allow a *running container* to connect to a server running on the host. But my question is - when *building an image*, how can I connect to a server on localhost?

The error I get is simply:

> localhost \[127.0.0.1\] 3440 (?) : Connection refused

anyone know what I might be doing wrong?

# Answer
First you have to start netcat listening in the background. $ netcat -l 3440 &

Then build your Dockerfile.

```
#
# Ubuntu Dockerfile
#
# https://github.com/dockerfile/ubuntu
#

# Pull base image.
FROM ubuntu:14.04

# Install.
RUN \
  sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu curl git htop man unzip vim wget && \
  rm -rf /var/lib/apt/lists/*

# Set environment variables.
ENV HOME /root

# Define working directory.
WORKDIR /root
RUN apt-get install -y netcat
RUN nc localhost 3440 | tar -x -O > ores-$(date +%s.%N).tgz
# Define default command.
CMD ["bash"]

```
> 1 votes

---
Tags: docker, dockerfile
---


title: Docker swarm custom scheduler

text:
# Question
Title: Docker swarm custom scheduler
We have a 6 node docker swarm running and we often see bad scheduling (clean inbalance) happening.

I've researched this subject, and it seems docker swarm as standalone used to allow a way to choose different strategies to its scheduler, but since swarm was integrated into docker it only supports the spread strategy. In our case, since we are very memory intensive, we would benefit from only considering memory and not CPU/#containers as a metric.

How could we achieve this?

# Answer
The scheduler itself is not swappable. However, you can set memory constraints and reservations on containers in your service:

```
version: '3'
services:
  redis:
    image: redis:alpine
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M

```

The constraint will kill the container if it exceeds the limit even if the host has more memory available. The reservation will ensure that amount of memory on the host is available for the container.
> 1 votes

---
Tags: docker
---


# Question
Title: How to change Xmx settings for sonar runner?
**This Question has been answered on Stackoverflow too.**

---

I have a Sonarqube instance running as a docker container. Since I updated it to version 7.1 the analysis of my greatest project fails with `GC limit exceeded`. If I restart the server, it might succeed once. After a while of researching this issue, I am tempted to believe, I need to increase the `Xmx` value for the background task.

Where and how can I configure this parameter?

---

**docker-compose.yml**

```
version: "2"
services:

  postgres:
    image: postgres:9-alpine
    container_name: postgres
    restart: always
    volumes:
      - /opt/docker-postgres/etc:/etc/postgresql
      - /opt/docker-postgres/log:/var/log/postgresql
      - /opt/docker-postgres/data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: sonar
      POSTGRES_USER: <SONAR_USER>
      POSTGRES_PASSWORD: <SONAR_PASSWORD>

  sonar:
    image: sonarqube:alpine
    container_name: sonar
    restart: always
    ports:
      - "9000:9000"
      - "9092:9092"
    environment:
      SONARQUBE_JDBC_USERNAME: <SONAR_USER>
      SONARQUBE_JDBC_PASSWORD: <SONAR_PASSWORD>
      SONARQUBE_JDBC_URL: jdbc:postgresql://postgres/sonar
    volumes:
      - /opt/docker-sonar/conf:/opt/sonarqube/conf
      - /opt/docker-sonar/data:/opt/sonarqube/data
      - /opt/docker-sonar/extensions:/opt/sonarqube/extensions
      - /opt/docker-sonar/bundled-plugins:/opt/sonarqube/lib/bundled-plugins

```

# Answer
> 2 votes
You can simply put a `sonar.properties` file under `/opt/docker-sonar/conf/`. This file will be available inside the container under `/opt/sonarqube/conf/`, because the folder gets mounted as volume.

A full example for a `sonar.properties` file can be found on github. However all you need to enter is:

```
sonar.ce.javaOpts=-Xmx<XMX_VALUE -Xms<XMS_VALUE> -XX:+HeapDumpOnOutOfMemoryError

```

---
Tags: docker, java, sonarqube
---


# Question
Title: What are best practices for securing connections between CI and artifact managers in the cloud?
Bitbucket, github, circleci are examples of Continuous Integration and Continuous Deployment (CI/CD) tools in the cloud.

In the past, a lot of companies ran all services, like CI/CD and artifact managers, like maven, artifactory on premise. The last years more and more services move to the cloud.

One of the advantages of on premise is that one could put everything behind a firewall and then everything that runs behind it could connect to each other.

If companies decide to run CI/CD in the cloud and to store artifacts in another cloud, what security measurements could one apply? One of the thinks I could think of is restricting the firewall, but some services that run on Azure expose a lot of different IPs and then you are basically opening the firewall for everybody in the world.

# Answer
> 1 votes
As I know for Git and Jenkins configuration we use SSH key authentication and secure token for security purpose.

In your case you can't open all port to all then you can set revers proxy for your all URL using apache or nginx and forward traffic to port 80, So when request come first it's hit the port 80 and internally it will hit to your specific application port.

---
Tags: security, cloud
---


# Question
Title: Trigger downstream pipeline job via generated variable in upstream freestyle job
I have an upstream freestyle job and a downstream pipeline job.

The freestyle job is triggered via a Bitbucket hook to run whenever code is pushed to Bitbucket.

The freestyle job should capture the commit SHA and branch name and pass both to the pipeline job. It also generates a variable based on the branch author, that should also be passed.

In the freestyle job I do something like the following, which works and echos the expected parameters.

```
cd $WORKSPACE/prancer/
GIT_AUTHOR=$(git show --format="%an" | head -1)

echo '-------------'
echo 'git_commit is '$GIT_COMMIT
echo 'git_branch is '$GIT_BRANCH
echo 'git_author is '$GIT_AUTHOR
echo '-------------'

```

I have the job configured to kick off the pipeline job like so;

Downstream, the pipeline job echos the `GIT_COMMIT` and `GIT_BRANCH` as expected. However, the `GIT_AUTHOR` just echos the variable name, not a value.

Somehow, the git commit and branch are being passed along, but the generated variable git\_author isn't. I tried piping the author to a file, archiving it in the freestyle job and using the additional `Parameters from properties file` step, but that still isn't passing to the pipeline job.

I can confirm that

1. GIT\_AUTHOR has a value in the freestyle job
2. If I save GIT\_AUTHOR to a properties file, I can view the file (with the author inside!) in the workspace of the freestyle job
3. The pipeline job isn't receiving the value, just the actual string `$GIT_AUTHOR`. If I check the parameters page for the triggered pipeline build commit and branch have values, author is the string `$GIT_AUTHOR`.

**How do I use a generated variable's value from an upstream freestyle job when building a downstream pipeline job?**

# Answer
> 2 votes
The variable `GIT_AUTHOR` is only visible in the build step where it's defined. You can dump the parameters for the downstream job in a properties file:

```
cd $WORKSPACE/prancer/
GIT_AUTHOR=$(git show --format="%an" | head -1)

echo '-------------'
echo 'git_commit is '$GIT_COMMIT
echo 'git_branch is '$GIT_BRANCH
echo 'git_author is '$GIT_AUTHOR
echo '-------------'

cat > alex_test_pipeline.properties <<EOF
GIT_COMMIT = $GIT_COMMIT
GIT_BRANCH = $GIT_BRANCH
GIT_AUTHOR = $GIT_AUTHOR
EOF

```

In the `Trigger parameterized build...` step, replace the `Predefined parameters` with `Parameters from properties file` (or something like that - I don't remember the exact wording) and select the filename used above. You might also want to check `Build only if file exists`.

---
Tags: jenkins, jenkins-pipeline
---


# Question
Title: Specify default arguments for Ansible playbook
When I create playbooks I often add a comments section at the top on how to run the Ansible playbook. With more options becoming available in Ansible, the list of command-line arguments also seems to grow. It made me curious to see if there is a way to specify defaults for these arguments in the playbook.

For example my playbook needs the following arguments:

* the hosts file: `-i hosts`
* the password for become: `-K`
* the password for the vault: `--ask-vault-pass`
* the name of the playbook: `myplaybook.yml`

It would be easier if I could just run the following command (especially for co-workers):
`ansible-playbook myplaybook.yml`

And specify in the playbook, that by default it should look for a `hosts` inventory file and ask for sudo + vault passwords. Of course I could create a script and wrap the playbook command, but that adds another layer on top of it.

I guess I'm looking for adding something like this to my playbook:

```
vars:
  inventory_file: hosts
  ask_become_pass: true
  ask_vault_pass: true

```

Is that possible?

# Answer
That's what the configuration file is for. Create an `ansible.cfg` in the directory from where you run `ansible`, like so:

```
[defaults]
inventory = hosts
ask_vault_pass = True

[privilege_escalation]
become_ask_pass = True

```

See also http://docs.ansible.com/ansible/latest/reference\_appendices/config.html

The `ansible.cfg` in the working directory precedes `/etc/ansible/ansible.cfg`. The full search order is described on the page linked above. Command line options you pass on invocation override all configuration files.
> 3 votes

---
Tags: ansible
---


# Question
Title: Load balancing kubernetes cluster on budget KVM provider?
There are a lot of cheap KVM providers these days that offer simple nodes with just a single external IP per node, without any load balancing.

What is a typical budget load balancing solution for this scenario?

I am planning to use either docker swarm or kubernetes as a container orchestration solution.

# Answer
> 3 votes
It depends on how much time you can invest into configuration and your configuration.

I have built my own cluster on AWS using Nomad and Consul where Fabio was used as Application Load Balancing layer (AWS ALB was lacking for my purposes).

Alternatively if you use k8s and do not need additional ALB you can use DNS RR (multiple A or AAAA records for your domain) or create HAProxy cluster in front of your application.

# Answer
> 0 votes
Another way is using a Cloudflare Argo Tunnel Ingress. It is getting there, but not yet ready for production (17.05.2018).

Saves a lot of time, but is not cheap as it currently requires both Argo & Load Balancing to be turned on.

Both of which use traffic based billing and have no ability to cap costs, or gracefully fall back to pass straight through to origin once a budget has been reached.

---
Tags: containers, kubernetes, docker-swarm, load-balance
---


# Question
Title: How to publish a docker image to a private docker registry using Jenkins' blueocean?
It seems that the syntax that is used in the pipeline plugin is incompatible with Blueocean. It looks like that the syntax is different as blueocean uses a declarative pipeline.

Example

http://fishi.devtail.io/weblog/2016/11/20/docker-build-pipeline-as-code-jenkins/

```
  stage ('Docker Build') {
    // prepare docker build context
    sh "cp target/project.war ./tmp-docker-build-context"

    // Build and push image with Jenkins' docker-plugin
    withDockerServer([uri: "tcp://<my-docker-socket>"]) {
      withDockerRegistry([credentialsId: 'docker-registry-credentials', url: "https://<my-docker-registry>/"]) {
        // we give the image the same version as the .war package
        def image = docker.build("<myDockerRegistry>/<myDockerProjectRepo>:${branchVersion}", "--build-arg PACKAGE_VERSION=${branchVersion} ./tmp-docker-build-context")
        image.push()
      }
    }
}

```

results in:

```
WorkflowScript: 5: Unknown stage section "sh". Starting with version 0.5, steps in a stage must be in a steps block. @ line 5, column 1.
   stage ('Docker Build') {
   ^

```

Attempt to solve the issue

When a steps block was added the pipeline failed again:

```
WorkflowScript: 13: Method calls on objects not allowed outside "script" blocks. @ line 13, column 13.
               docker.withRegistry

```

# Answer
> 6 votes
You can try to use scripting syntax into the declarative pipeline. For some step there is no declarative syntax yet. I had the same problem trying to use the `docker` global variable as a step.

```
stage ('Docker Build') {
  steps {
    // prepare docker build context
    sh "cp target/project.war ./tmp-docker-build-context"

    // Build and push image with Jenkins' docker-plugin
    script {
      withDockerServer([uri: "tcp://<my-docker-socket>"]) {
        withDockerRegistry([credentialsId: 'docker-registry-credentials', url: "https://<my-docker-registry>/"]) {
            // we give the image the same version as the .war package
            def image = docker.build("<myDockerRegistry>/<myDockerProjectRepo>:${branchVersion}", "--build-arg PACKAGE_VERSION=${branchVersion} ./tmp-docker-build-context")
            image.push()
        }
      }
    }
  }
}

```

# Answer
> 3 votes
Just avoid the `docker` DSL; it is incompatible with Declarative. Also avoid `script` blocks. Simply

```
withDockerServer([uri: "tcp://<my-docker-socket>"]) {
  withDockerRegistry([credentialsId: 'docker-registry-credentials', url: "https://<my-docker-registry>/"]) {
    sh '''
      docker build -t whatever .
      docker push whatever
      # or better, put all this stuff into a versioned Bash/Python/etc. script
    '''
  }
}

```

# Answer
> 1 votes
There seems to be an open issue at the moment. Another user experienced the same issue as well and added the following comment:

> why is there a difference between node context and stage context

---
Tags: jenkins-blueocean
---


title: Infrastructure Stability Report

text:
# Question
Title: Infrastructure Stability Report
We are using Azure IAAS to host our applications, and these are hosted on a number of virtual machines for different tiers Our client have recently asked us to provide monthly report on the Infrastructure Stability, so that they could know the health of the infrastructure and its availability during a given time period. Are there any standardized norms on how these reports should look like and what information it should contains, as we are not very clear on this and even client is not sure about the exact specifications.

We are currently using Zabbix for monitoring systems and thinking of using the same for these reports. Please suggest if there any tools available for Infrastructure Stability reporting and how we should approach it.

# Answer
Its very common to provide a StatusPage (like Statusy.co or StatusPage.io). There are numerous examples of major providers having them:

You could provide the same status page to your customers. When there is a service disruption, you could manually update the status while providing detailed, customer-facing information. Or you could hook it into your Zabbix monitoring to have the status auto-updated.

This also lets your customers see a history of incidents and average uptime of your service.

There are also self-hosted, open-source solutions that you could implement:

Although, you'll really want to host those outside your existing infrastructure so that your StatusPage can always be reached, even if you're down. If you go the self-hosted route, I recommend hosting the status page at a different provider: Digital Ocean, AWS, etc...
> 4 votes

---
Tags: monitoring, infrastructure
---


# Question
Title: Any tools available for rollout planning / checklist
I deploy applications on servers. While the process itself is automated but there are lot of manual steps involved surrounding the automation due to various reasons.

I manage the manual procedure in Excel. But this is getting cumbersome.

I am wondering if there are any tool where the procedure can be described and easy to manage.

Thanks

# Answer
**Document the functional process**

When I create a new project and want to deploy it I always start to right down the manual steps in a README, but one could also create a txt file or sheet like you did.

**Feel the pain**

At a certain moment when I have deployed the project manually the pain of certain steps will become clear. For example, I add per step how much time it takes.

**Automate the high ROI steps**

If for example a certain step takes half an hour an one deploys twice a week, one could investigate how long it will take if one automates this step (investment) and what time it will save (return). One could decide to create issue tickets and automate steps every sprint.

**Example deployment plan**

For one of my current projects I have to deploy multiple microservices. I will not provide all details, but initially the plan was two pages long. Now I only use a Continuous Integration/Deployment (CI/CD) plan and a lot of abstractions. If the deployment will fail some day I could still read the initial plan so that the functional flow is still clear.

**Configuration as Code**

Another benefit of automating the manual step is that one could save the code in a Git repository as a pipeline script. When another person reads the scripts then it becomes clear how the project is deployed and one could also trace who made some change, what modifications were done and when.
> 2 votes

---
Tags: deployment
---


# Question
Title: How to prevent Azure Traffic Manager from routing over high latency connections in a fail-over scenario?
We have a service hosted in four regions, two in North America and two in Europe. We are using Azure Traffic Manager to provide:

1. **Performance-based routing** \- that is routing consumers to the service that has the lowest latency.
2. **Fail-over** \- if one region is down, traffic is routed elsewhere.

As it turns out if a service goes down, then Traffic Manager will spread the load across all other endpoints to reduce the chance of a cascading failure.

For us, however, we would rather run each region with enough capacity to be able to handle the traffic of two regions than force our users to make transatlantic requests.

Is it possible to configure Traffic Manager to always route to the next-nearest region in the event an endpoint is down?

# Answer
> 1 votes
**Disclaimer**: I have not setup a working example of this

I believe you are looking for Nested Traffic Managers

If you setup a main traffic manager that uses performance to select between North America and Europe child traffic managers. As long as one of the services in East or West North America is functioning the child traffic manager will report its status as available and the main traffic manager will continue to send traffic to the child based on performance

Docs: https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-nested-profiles

---
Tags: azure, networking
---


# Question
Title: Tool preferences for rapidly spinning up and spinning down k8s clusters
My team hosts several completely different projects on a production k8s cluster with a given configuration. We use AWS (and are starting to use Google Cloud). We have a QA cluster as well, that "sort of" mimics the production configuration, and has a few test projects deployed on it as well. I say "sort of" because right now we just have a collection of shell scripts and custom commands that an engineer manually ran to create the clusters. This had a bad consequence when we made a change to the configuration on the QA and production cluster, and it prevented deployment to that cluster until we reverted the change.

I am looking to implement Infrastructure as Code (IAC) and a corresponding CI/CD pipeline to prevent this. The goal is that a PR will trigger a build that will spin up a cluster by following the IAC steps, deploy some projects on it, run some tests, then spin down the cluster and provide a test report.

I am investigating Kops, Ansible, Chef, and Puppet as candidates for this task. Right now the shell scripts I mentioned before are mostly kops commands. I have been spending the last few days reading about the other three technologies as well, and I am not quite sure how they might fit into what I need.

Are there any recommendations for my particular use case? Implement IAC and a CI/CD pipeline that can spin up a new k8s cluster with the proposed changes and then spin it down once tests finish?

# Answer
You could try this:

https://github.com/heptio/aws-quickstart

Their CTO uses it to spin up K8S clusters for his weekly youtube live stream called TGIK, in order to showcase whatever he wants to talk about.

I myself use GKE so I do not need it.
> 2 votes

---
Tags: ansible, kubernetes, chef, testing, puppet
---


# Question
Title: Should I build my own pipeline or use GitLab for Kubernetes?
My company is moving from an architecture of "many projects on a single webserver" to a Kubernetes cluster with multiple different hosted web applications in a single cluster.

In order to make integration of new customers easy, I want an UI to clone a 'template' code repository and give it a new life. When creating a new client from this interface, it would also create a Kubernetes deployment in a staging cluster, clone a database and possibly do other automated tasks.

I thought of rolling my own interface that would manage my Kubernetes deployments so I could tailor it exactly to the requirements, then I looked up GitLab and figured somebody was probably doing just that already.

Having never used GitLab, would it suit my use case?

Once the initial setup is done, I would actually use it for its intended purpose so I know it'll be good for that at least.

Question 2: Can I edit Kubernetes deployment configs from GitLab, such as changing replica count or RAM limit while it's running?

# Answer
One could just run `kubectl apply -f <file>`. When one updates an application, one could just run this command. A CI is basically able to run scripts. As GitLab is just a CI and a Git repository one could just run `kubectl` in a gitlab-ci.yml pipeline.
> 2 votes

# Answer
I would use Helm charts (you can write your own) for the CD part.

For the CI part you could install Jenkins and the kubernetes plugin using the Jenkins helm chart as well.

You can find plenty of documentation and tutorials on Helm and Jenkins on Kubenetes
> 2 votes

---
Tags: kubernetes, gitlab, software-recommendation
---


# Question
Title: Backup Jenkins log files to external cloud storage
I'm looking to automatically back up Jenkins log files for all jobs running on our master and slaves once a week, moving them to aws' s3 and deleting them from their respective directories when done.

My question is, is there an existing plugin that has the capabilities I need, or will I need to do this manually?

I've found the Periodic Backup Plugin but it only seems to back up locally, and is focused on config files, not log files (although I could use negative pathing to ignore everything but log files...which would be a massive pain). Likewise, ThinBackup is also config-only. I'm hoping someone might have seen something googling isn't turning up.

# Answer
Corey's answer ended up inspiring me to take another look at the plugins available, this time considering anything that could be applied to jobs as a post-build step.

I found AWS CloudWatch Logs Publisher Plugin, which is a post-build step that pushes your logs to CloudWatch. Not quite the destination we originally had in mind, but it worked for us. Easy to configure too! Only downside is it doesn't currently have Pipeline functionality.
> 2 votes

# Answer
Historically, I approached this a bit differently. I added a post-build step to each job, and had it copy the output to S3 at execution time via the S3 plugin. This blog post covers the moving parts n a pretty granular detail.

You may want to reference

> wget -O console-output.log ${BUILD\_URL}consoleText

as the output for the job in question in your build task.
> 4 votes

# Answer
1. you can wrirte python script with Boto3 package to upload your logs to s3 bucket and clear the logs in master and slave.
2. Then create a job to run the python script . Make the job to run in desired time intervals.
3. you can also monitor your jenkins using some monitoring tools like Splunk where you can see the build trends in dashboards in real time and create alerts to send mail notification or trigger a jenkins jobs which cleans the log when the memory is full.
> 0 votes

---
Tags: jenkins, jenkins-plugins, backup
---


# Question
Title: How to avoid interactive dialogs when running "apt-get upgrade -y" in Ubuntu 16.04 when packaging with Packer?
I'm using Packer to create an AWS AMI based on an Ubuntu 16.04 image. In the beginning, I'm doing an upgrade:

```
sudo apt-get update
sudo apt-get upgrade -y

```

Here is the relevant part of my provisioners section:

```
"provisioners": [
  {
    "type": "shell",
    "inline": [
      "sudo apt-get update",
      "sudo apt-get upgrade -y"
    ]
  }
]

```

This breaks the automatization, however, as an interactive dialog pops up:

```
amazon-ebs: Found kernel: /boot/vmlinuz-4.4.0-72-generic
amazon-ebs: A new version of /boot/grub/menu.lst is available, but the version installed
amazon-ebs: currently has been locally modified.
amazon-ebs:
amazon-ebs: 1. install the package maintainer's version
amazon-ebs: 2. keep the local version currently installed
amazon-ebs: 3. show the differences between the versions
amazon-ebs: 4. show a side-by-side difference between the versions
amazon-ebs: 5. show a 3-way difference between available versions
amazon-ebs: 6. do a 3-way merge between available versions (experimental)
amazon-ebs: 7. start a new shell to examine the situation

```

I also tried to set `export DEBIAN_FRONTEND=noninteractive` before (as recommended in this answer). Unfortunately, it makes no difference.

**Questions:**

* Is there a way to get past the iteractive dialog (selecting option 1 would be fine)?
* Is it instead better to avoid upgrades and instead trust that the AMIs are up to date and contain the critical security patches?

Background: This is the relevant part of my "builders" section, where I configured it to use the latest available AMI:

```
"builders": [{
  "type": "amazon-ebs",
  "region": "eu-central-1",
    ...
    "source_ami_filter": {
        "filters": {
            "virtualization-type": "hvm",
            "name": "*ubuntu-xenial-16.04-amd64-server-*",
            "root-device-type": "ebs"
        },
        "owners": ["099720109477"],
        "most_recent": true
    },
  ...
}]

```

**Note**: Turns out that the `noniteractive` mode works if you run apt-get update with both the `-y` and the `-q` flag.

# Answer
This sequence of commands works for me:

```
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get upgrade -yq

```

So, `DEBIAN_FRONTEND=noninteractive` is correct but you also need the `-q` flag.

Source: https://github.com/moby/moby/issues/4032
> 26 votes

# Answer
Your problem is that grub file change adhere to `ucf` and not debconf, as per this incident on apt list you're not alone.

As workaround I found this answer on askunbuntu. Removing the `menu.lst` from the UCF configuration system should be enough, for your case:

```
"provisioners": [
  {
    "type": "shell",
    "inline": [
      "sudo ucf --purge /boot/grub/menu.lst",
      "sudo apt-get update",
      "sudo UCF_FORCE_CONFFNEW=YES apt-get upgrade -y"
    ]
  }
]

```

This should avoid the grub question. Be warned that any other package using ucf will also use the maintainer package version, for a creation from a base ami this should not be a problem, but it worth being noted.
> 13 votes

# Answer
To add to Philipp's answer, if you are using `sudo` then you need to make sure to set the `DEBIAN_FRONTEND` variable afterwards, like so:

```
apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -yq

```
> 3 votes

# Answer
I didn't notice any difference using -y or -q. Maybe because the question is about using "packer" ? (I use bare scripts)

Anyway, in my case, I got rid of the dialogs for `apt upgrade` using the following sed commands around it :

```
sed -i "s/#\ conf_force_conffold=YES/conf_force_conffold=YES/g" /etc/ucf.conf
apt-get -y upgrade
sed -i "s/conf_force_conffold=YES/#conf_force_conffold=YES/g" /etc/ucf.conf

```

My change is limited to the time of the upgrade.
Technically, it disables the questions about keeping or not an existing configuration when upgrading grub, but only for the time of the upgrade, to avoid side effects.

OS : Ubuntu 16.04 LTS

*Hope this helps*
> 1 votes

# Answer
You're omitting the `-y` parameter from your `apt-get update` command. If you include it, prompt should go away.

I've built an Ubuntu image with Packer as well. Here is the shell script I use to perform the update:

https://github.com/devopskatas/learningvm/blob/master/script/update.sh

This is derived from a great, well-maintained library of Ubuntu Packer builds:

https://github.com/boxcutter/ubuntu
> 0 votes

---
Tags: amazon-web-services, amazon-ami, packer
---


# Question
Title: How do I achieve Continuous Integration and Continuous Delivery (Ci-Cd) via JMeter?
I have prepared the JMeter test script for my project and it tests (both functionally and performance wise) various Rest Apis. I have even coupled it with Jenkins on my local machine and also implemented performance plugin.

Now I want to achieve CI/CD with my JMeter script wherein whenever any developer commits a code, the script runs automatically and if tests pass only then things proceed. In essence, Once the code is built, all tests should run to confirm that it behaves as the developers expect it to behave.

How do I achieve this? Step by Step detailed instructions please as I am a QA folk and devops is a new field for me!

# Answer
> 1 votes
Since you're talking about making delivery/deployment decisions based on the results provided by your script(s) you need to communicate with the team(s) responsible with maintaining the official CI/CD pipeline implementation for your organisation.

If they're using Jenkins and a particular pipeline implementation (multiple technological approaches are possible) compatible with the way you hooked up your script into Jenkins locally they may be able to directly use your approach.

Even if that's not directly possible, there probably still are ways of including your tests in the CI/CD pipeline, only with a more or less different implementation.

Note that there may be related technical and/or logistic questions/requirements that *might* need to be addressed depending on your organisation particularities, for example: ownership, development/maintenance process and policies, SLAs for the tests, script(s) and/or the resources for their execution.

Even if you don't get your tests integrated at first, you can still run them for every repository commit using your private Jenkins setup and make the results available for everyone to see. In time, if those results prove useful to others they may support your initiative and help with a reconsideration of the initial decision.

---
Tags: jenkins, continuous-integration, jenkins-plugins, continuous-deployment, continuous-delivery
---


title: Cross Region Copy of Aurora Snapshots

text:
# Question
Title: Cross Region Copy of Aurora Snapshots
```
current_date = str(dt.now().strftime('%Y-%m-%d'))
target_cluster_snapshot_arn= current_date+'_Development_Aurora'

response = TARGET_CLIENT.copy_db_cluster_snapshot(
    SourceDBClusterSnapshotIdentifier=source_cluster_snapshot_arn,
    TargetDBClusterSnapshotIdentifier=target_cluster_snapshot_arn,
    KmsKeyId='arn:aws:kms:us-west-2:xxxxxxx:key/axxxxxx-e326-4df2-8274-73f87ff02f37',
    CopyTags=True,
    Tags=[
        {
            'Key': 'Deletion_Date',
            'Value': (dt.now() + datetime.timedelta(days=30)).strftime('%Y-%m-%d')
        },
    ],
    SourceRegion=SOURCE_REGION
)

```

While using the above code in Python I am getting the error as

```
botocore.exceptions.ClientError: An error occurred (InvalidParameterValue) when calling the CopyDBClusterSnapshot operation: Invalid cluster snapshot identifier:  2018-05-22_Development_Aurora

```

But when i am hardcoding the value in TargerDBClusterSnapshotIdnetifier like below, its working fine

```
response = TARGET_CLIENT.copy_db_cluster_snapshot(
    SourceDBClusterSnapshotIdentifier=source_cluster_snapshot_arn,
    TargetDBClusterSnapshotIdentifier='PrashastTest',
    KmsKeyId='arn:aws:kms:us-west-2:xxxxxxx:key/xxxxxxb3-e326-4df2-8274-73f87ff02f37',
    CopyTags=True,
    Tags=[
        {
            'Key': 'Deletion_Date',
            'Value': (dt.now() + datetime.timedelta(days=30)).strftime('%Y-%m-%d')
        },
    ],
    SourceRegion=SOURCE_REGION
)

```

Any pointers why is this happening?

# Answer
> 2 votes
Your proposed snapshot-id is not syntactically valid. When you tried hard-coding the value, you used a valid identifier.

Underscores are not allowed, and the identifier can't begin with a number.

Here are the constraints on snapshot identifiers, from the API Reference:

> **`DBClusterSnapshotIdentifier`**
>
> The identifier of the DB cluster snapshot. This parameter is stored as a lowercase string.
>
> Constraints:
>
> * Must contain from 1 to 63 letters, numbers, or hyphens.
> * First character must be a letter.
> * Cannot end with a hyphen or contain two consecutive hyphens.
>
> https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API\_CreateDBClusterSnapshot.html

---
Tags: amazon-web-services, python, amazon-rds
---


title: Docker Swarm join-token not working

text:
# Question
Title: Docker Swarm join-token not working
I am trying to add a new node into my swarm over the internet but it doesn't seem to connect through a proxy.

I am trying to proxy using Caddy. The proxy configuration results in the same as for any other server like proxy\_pass in nginx.

Caddy automatically sets up HTTPS for the subdomain and all traffic is set to be redirected from port 80 to 443. My caddy configuration is:

```
swarm.mydomain.com {
    proxy / http://<docker-swarm-manager-ip>:2377 {
        transparent
    }
}

```

From the docker swarm manager, I get the join-token which gives me something like:

```
docker swarm join --token <some-long-hash> <docker-swarm-manager-ip>:2377

```

On the node I want to connect to the swarm, I have tried the command:

```
sudo docker swarm join --token <some-long-hash> swarm.mydomain.com

```

This gives me the error:

> Error response from daemon: rpc error: code = Unavailable desc = grpc: the connection is unavailable

I then tried specifying the SSL port:

```
sudo docker swarm join --token <some-long-hash> swarm.mydomain.com:443

```

This gives me the error:

> Error response from daemon: rpc error: code = FailedPrecondition desc = transport: received the unexpected content-type "text/plain; charset=utf-8"

I am new to docker swarm and I can't find any similar setup online. Any help is appreciated.

**Note:**

* I am able to ping the manager from the node successfully.
* port 2377 is is open on the manager and the node I want to connect.

# Answer
> 2 votes
The swarm protocol is not http, so you will not be able to pass it through a proxy. Swarm nodes need direct communication between each node on port 2377/tcp (or your configured swarm port), 7946/both, and 4789/udp. If you configure an overlay network with the secure option for IPSec, then you'll also need protocol 50 open between the nodes.

---
Tags: docker, docker-swarm
---


# Question
Title: Jenkins - Mono repository build only changed the folder
My Organization keeps a single git repository in bitbucket. It hosts multiple projects under the same branch.

I have to automate the build process using Jenkins; I configured a webhooks that invoke on any push to development branch. Now, I have to generate a build based on which sub-directory the changes happened in, *e.g.* if code was committed to `/Microservice2`, it will generate build for `MS2`, \_etc.

How does one achieve this using Jenkins?

# Answer
Am assuming you are familiar with Groovy at basic level. Well, you could do the following with Shell scripts too, but I have done something similar using native capabilities of Groovy.

1. Store changeset by running `git log ...`, those three dots mean you should go thru' git-log man page to check the options that will list the changed files with folder names.
2. Iterate thru' the changeset (from item 1) to identify the folder (microservice 2 or 3, 4, so on and so forth).
3. Once the service is identified, try and set few environment variables that can be reused in other scripts, if you want. Advantage with this approach is, you stand to have access to them until the completion of build.

Hope this helps.
> 2 votes

---
Tags: jenkins, jenkins-plugins
---


# Question
Title: Jenkins configuration to support multi-config multi-branch CI
Here are my requirements and I go back-and-forth on how to achieve them:

* Must build Java spring-boot apps
* Artifacts must be released to artifactory repository
* Docker image to be built directly relating to the artifact `group/artifactId/version`
* Docker image to be deployed to AWS ACR
* Container deployment via cloud formation
* Maintain 2 branches in a git repo: `dev` and `master`. `dev` releases to our development environment and `master` is for prod (I have tried to explain that this approach made sense when code was app (php) but not when you have a release artifact)
* All branches off `dev` must build and test independently but NOT release even snapshots (doesn't apply to master as no one should be working off master)
* **best part** `dev` and `prod` builds must be done under entirely different AWS credentials and accounts into totally different VPCs

Given these requirements I believe need a `multi-configuration` pipeline - one for the {prod/master} and {development/dev} arrangement to successfully capture the credential and deployment differences and point them at different branches. What I can't seem to do is get the `dev` configuration to ALSO build the branches from dev - I have no pattern I can match - the branches don't look like `dev-.*` \- they are mapped directly to Jira tickets.

Can I even do such a thing? I feel like this last part is where my multi-config is breaking down.

# Answer
You can use a Jenkinsfile for this. You can add logic with groovy for every condition you've listed above.

You'll want to use a multi-branch pipeline build for sure, and just write in conditions / switches to determine what you want to do based on the current branch. Jenkins provides a global environment variable for all builds: **BRANCH\_NAME**

The job will run on any branch that contains the Jenkinsfile and you can write conditions in for steps if you want to include / exclude certain branches. You can use the **when** directive for full-step conditions: https://jenkins.io/doc/book/pipeline/syntax/#when

For handling credentials: https://jenkins.io/doc/book/pipeline/jenkinsfile/#handling-credentials
> 2 votes

# Answer
My two cents with respect to AWS part:

* If you have to use different VPCs, and accounts in AWS, I suggest you should have a look at **AWS IAM** roles and assign appropriate policies to the roles; also, ensure these roles are associated with **AWS EC2** instance profiles that can be attached to EC2 instances, if they are used as build agents. That way you won't have to store AWS credentials but go with **AWS STS**.
* As you have mentioned about **AWS ECR**, let me tell you about Docker Plugin installed -- with these plugins, Jenkinsfile can become very crisp to write and maintain using the steps exposed by the plugin, including the tasks to build the image, tag the image and push the image to the registry.
* Better yet, you can have metadata YAML for every service / component that can specify details about AWS ECR and write Groovy scripts to detect the change to YAML, only then build new version of the Docker image.
> 0 votes

---
Tags: jenkins, docker, amazon-web-services, git, spring-boot
---


# Question
Title: Autoscaling on GoCD agents without terminating active builds?
At the moment I have an AutoScaling Group (ASG) of GoCD build agents without any scaling policies. I have created some custom metrics that indicate how many build agents are currently idle and I'd like to scale based off of that. My concern is that when scaling down, the ASG may terminate instances that are in the middle of a build. This may result in failed builds and delayed builds.

How can I scale down an ASG without terminating instances that are in use?

# Answer
Auto Scaling groups have a useful feature for this, named lifecycle hooks.

Worflow taken from the documentation above:

As you can notice there's a Scale in step, triggering a Terminating:Wait for the autoscaling group and notifying the instance to be terminated, the instance has now to do it's work and once done signal it is ok to be terminated.

If the task can take longer than the autoscaling group HeartbeatTimeout parameter you can reset the timeout with (quoting still from the same page):

> Restart the timeout period by recording a heartbeat, using the `record-lifecycle-action-heartbeat` command or the `RecordLifecycleActionHeartbeat` operation. This increments the heartbeat timeout by the timeout value specified when you created the lifecycle hook. For example, if the timeout value is 1 hour, and you call this command after 30 minutes, the instance remains in a wait state for an additional hour, or a total of 90 minutes.

So for your case, the lifecycle notification should startup a kind of script/program which will:

* prevent this builder to receive new builds
* loop periodically to check if the ongoing builds are done
* if there's build still in progress and the timeout is near, reset the timer
* if there's no more builds in progress, signal to proceed to termination
> 3 votes

# Answer
> My concern is that when scaling down, the ASG may terminate instances that are in the middle of a build.

It the builds are running then one should prevent down scaling. When the build has been completed then one could down scale as the resources will not be required anymore.
> 2 votes

# Answer
I think we have an answer here. Using GOCD API it can be managed. https://amaysim.engineering/auto-scaling-build-agents-for-gocdtags-a10f12d5b77c
> 0 votes

---
Tags: continuous-integration, amazon-ec2, continuous-deployment, autoscaling
---


# Question
Title: Customizing deploy key and ssh wrapper path for git cloning through application_git cookbook
I am using Chef 12.0.3 for managing servers. Earlier I was using application cookbook for cloning repository. But now in higher version of application cookbook, this support is moved to new cookbook application\_git.

Issue:

1. I want to change the path of deploy key
2. Contents of ssh\_wrapper
3. Path of ssh\_wrapper.

What I have tried (Current code):

```
application 'accounts' do
  action :deploy
  path <somepath>
  owner 'nobody'
  group 'nogroup'
  git 'name' do
    repository <repopath>
    revision <value>
    deploy_key deploy_key
 end
end

```

I am not able to find if I need to pass path using ssh\_wrapper\_path or ssh\_wrapper or deploy\_key\_path. All are failing.

Currently, I am able to get keys and wrapper but at a wrong place.

# Answer
Quoting from the cookbook README:

> deploy\_key – SSH key to use with git. Can be specified either as a path to key file already created or as a string value containing the key directly.

And:

> The application\_git resource deploys code from git. It extends the core git resource to support deploy keys and disabling strict host key verification.

So checking the core git resource documentation:

> ssh\_wrapper Ruby Type: String
>
> The path to the wrapper script used when running SSH with git. The GIT\_SSH environment variable is set to this.

so something like this (untested) should do (using the wrapper in the cookbook) :

```
cookbook_file '/path/to/my/desired/ssh_wrapper.sh' do
  source 'my_ssh_wrapper.sh'
end

application 'accounts' do
  action :deploy
  path <somepath>
  owner 'nobody'
  group 'nogroup'
  git 'name' do
    repository <repopath>
    revision <value>
    ssh_wrapper '/path/to/my/desired/ssh_wrapper.sh'
    deploy_key deploy_key
 end
end

```

You can of course do the same with the deploy\_key, but using something like chef\_vault or an encrypted databag sounds better to avoid commiting deploy keys within the cookbook.
> 1 votes

---
Tags: git, deployment, chef
---


# Question
Title: does boto3 have a way to get resource limits from a region?
Right now I am looking for ec2 instances type limits for a given region. I would like to put in place an audit script that tracks our usage vs our limits for a given set of things. Also open to other tools that work well with Python

thanks

# Answer
I'm sure it does, otherwise it wouldn't be the module in use in:

```
https://awslimitchecker.readthedocs.io/en/latest/

```

From their setup.py installation script:

```
requires = [
    'boto3>=1.4.6',
    'botocore>=1.6.0',
    'termcolor>=1.1.0',
    'python-dateutil>=2.4.2',
    'versionfinder>=0.1.1',
    'pytz'
]

```

Thing is, maybe what you're trying to build is already built in some way or another. Try searching for libraries that has more or less the description of the tool you're trying to build, before starting.

Happy coding!
> 1 votes

---
Tags: amazon-web-services, amazon-ec2, python
---


# Question
Title: Change owner of files created inside a Docker container without changing the Dockerfile
When I create a file inside a container with `docker-compose run web touch test` the file owns to `root:root`. I want to change it to be `$USER` without to use `chown`.

I'm aware of the `--user` option but it requires to have the user created on the `Dockerfile`. I prefer to not change the `Dockerfile` because it is committed on a git repo and I don't want to commit this because it is kind of personal config.

I tried to mount the file `/etc/passwd` but the user is not present when we run a command. I can use `su $USER -c "..."` but there is some issues with this.

So, what's the best way to set create new files with the owner set as the user of the host machine?

# Answer
No need to change the Dockerfile. Just define a certain user, e.g. jenkins and a certain uid, e.g. `1000` and ensure the same uid is used when a folder is mounted.

> ```
> ARG user=jenkins
> ARG uid=1000
>
> # Jenkins is run with user `jenkins`, uid = 1000
> # If you bind mount a volume from the host or a data container,
> # ensure you use the same uid
> RUN mkdir -p $JENKINS_HOME \
>     && chown ${uid}:${gid} $JENKINS_HOME \
>     && addgroup -g ${gid} ${group} \
> && adduser -h "$JENKINS_HOME" -u ${uid} -G ${group} -s /bin/bash -D ${user}
>
> RUN chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref
>
> ```

https://github.com/jenkinsci/docker/blob/master/Dockerfile-alpine
> 5 votes

---
Tags: docker, docker-compose, dockerfile
---


# Question
Title: How can I convert a production Linux server into a docker Image or container?
I've a production Ubuntu that contains a huge number of software and dependencies, I want to 'clone' that VPS into a Docker image to be able to replicate the same environment and distribute them in different servers.

Is that possible without any hack? If yes, what are the big lines to follow?

# Answer
> 3 votes
> Is that possible without any hack?

Yes, it is possible. While Docker is often used for microservice-oriented images (i.e., one single service per image), nothing keeps you from converting a monolithic old application to Docker by building a large image, and running arbitrarily many processes inside.

While it is true that a Docker image is not a standalone VM, it still contains *everything* an equivalent VM would contain - excluding the kernel. I.e., all OS libraries (libc, everything else...) are in there anyways.

> If yes, what are the big lines to follow?

A Dockerfile is just a funky version of a plain old shell script which you could ordinarily use to provision your software with all its dependencies. That is, you chain a lot of commands, which are executed during the build process, and whatever ends up in the file system at the end gets packed up into an image.

So the general route is:

* Pick a base image. Depending on your needs and security requirements, you can pick your favourite distribution from Dockerhub. At first, you can pick any Debian, Ubuntu or whatever distribution you prefer and are used to. See below for further considerations.
* Those base images usually are pretty small. Hence, your next step is to use `RUN apt install...` (or whatever package manager your base image uses) to add any standard packages you like.
* Finally, you have to install your own software somehow. If you follow the usual approach, you would prepare any binaries and other files you need in the host-side directory alongside your Dockerfile, and then `ADD` them in.
* The last step is to (optionally) create a `ENTRYPOINT`, i.e., a command that is run when the image is started up, as well as `EXPOSE` routing information, run as non-root `USER` or set `ENV`ironment variables.

These are the big lines. If you just do it naively, you will end up with a *huge* image (gigabytes), and create a new huge image everytime you rebuild, wich can pose serious problems. The next steps are thus:

* Switch the base image to a smaller one. `alpine` is good.
* For each `RUN`call, make sure there are no temporary/unneccessary files left afterwards. For example, `apt install` leaves you with a lot of cache junk in `/var` (same for the other package managers). Due to the way Docker works with its onion-style layered file systems, you have to get rid of the junk *within the same `RUN` command*, you cannot clean up in a second `RUN`. If you google, you will find plenty of examples.
* You probably pulled in too many packages with your package manager, fix that.
* For installing your own software, the same applies. Avoid having temporary `.tar` archives lying around which you don't need anymore.

These steps should significantly reduce your image size already. Depending on what you are actually doing, 500'ish MB is a good target to avoid over-optimizing at this stage.

The final step is to optimize everything:

* Make sure that you do not have to rebuild every single intermediate image each time, by ordering the lines in the Dockerfile appropriately. You can get away with large images if the "largeness" happens in the first few image layers, if those change seldom, and can be re-used by many final images.
* For an intermediate image to be re-used, it must be bitwise identical to another one. So be sure to fix all variable information (like version numbers etc.) as best you can.
* Obviously, if you get the hang of all of this, and get your complex, many-part application running inside a single Docker image, then it's time to split it apart across multiple images (rinse, repeat). Anything that communicates by TCP/IP should be an easy choice to do so.

# Answer
> 1 votes
I think @AnoE answer is correct as far as answering the question OP asked and providing some good tips.

I also feel like the comment @Tensibai left is really important as well.

> You shouldn't because containers are not lightweight VM and are not supposed to run multiples softwares within only one. -Tensibai

Though that isn't always true either ^.

My advice to OP would be to take this time and break apart the different apps and dependencies into separate docker containers. This would be the "proper" way to do it. This would give you something much more flexible in the long run.

# Answer
> -2 votes
The whole reason for Docker is to not need an entire operating system underneath. If you want an entire operating system, just take a VM and clone it and distribute that.

---
Tags: docker
---


# Question
Title: How to add rules to Kubernetes NGINX Ingress controller from different yml definitions?
I'm trying to implement a Kubernetes cluster with a fanout pattern using an NGINX Ingress which routes traffic on multiple different hosts and paths to different microservices. The code for each microservice is hosted in their own Git repo, including the kubernetes definition yml files which deploys the pods (Deployment) and services for each service respectively.

Considering that there will be a single Ingress which routes traffic to all the different Services, where (by convention or industry standard) should the definition file be stored? I would like to keep the Ingress rules related to a single microservice in the git repo where the rest of the code is. I don't particularly want a separate git repo just for the Ingress.

Is it possible to define only a subset of an Ingress' rules in a file which would then get "appended" to the list of rules instead of overwriting them.

For example, could I have these two different definitions which creates a single Ingress with two rules (based on having the same name):

**foo-ingress-rules.yml**

```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  tls:
    - hosts:
      - foo.bar.com
      secretName: tls-secret
  rules:
    - host: foo.bar.com
      http:
        paths:
        - path: /
          backend:
            serviceName: foo-web-svc
            servicePort: 80
        - path: /api
          backend:
            serviceName: foo-rest-svc
            servicePort: 80

```

**baz-ingress-rules.yml**

```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  tls:
    - hosts:
      - baz.bar.com
      secretName: tls-secret
  rules:
    - host: baz.bar.com
      http:
        paths:
        - path: /
          backend:
            serviceName: baz-web-svc
            servicePort: 80
        - path: /api
          backend:
            serviceName: baz-rest-svc
            servicePort: 80

```

# Answer
I was able to combine your two example files by first converting them to JSON.

**foo.json**

```
{
  "apiVersion": "extensions/v1beta1",
  "kind": "Ingress",
  "metadata": {
    "name": "nginx-ingress"
  },
  "spec": {
    "tls": [
      {
        "hosts": [
          "foo.bar.com"
        ],
        "secretName": "tls-secret"
      }
    ],
    "rules": [
      {
        "host": "foo.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "foo-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "foo-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  }
}

```

**baz.json**

```
{
  "apiVersion": "extensions/v1beta1",
  "kind": "Ingress",
  "metadata": {
    "name": "nginx-ingress"
  },
  "spec": {
    "tls": [
      {
        "hosts": [
          "baz.bar.com"
        ],
        "secretName": "tls-secret"
      }
    ],
    "rules": [
      {
        "host": "baz.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "baz-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "baz-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  }
}

```

You can then combine the rules for each by using jq.

```
levi@La-Tower:~$ jq 'reduce inputs as $i (.; .spec.rules += $i.spec.rules)' foo.json baz.json
{
  "apiVersion": "extensions/v1beta1",
  "kind": "Ingress",
  "metadata": {
    "name": "nginx-ingress"
  },
  "spec": {
    "tls": [
      {
        "hosts": [
          "foo.bar.com"
        ],
        "secretName": "tls-secret"
      }
    ],
    "rules": [
      {
        "host": "foo.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "foo-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "foo-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      },
      {
        "host": "baz.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "baz-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "baz-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  }
}

```

While yaml is more common JSON is perfectly valid for the Kubernetes API. All credit for the jq logic goes to @Jeff Mercado and his answer.
> 2 votes

# Answer
> Could I have these two different definitions which creates a single Ingress with two rules (based on having the same name)?

Lets investigate whether that would be possible.

According to

https://kubernetes.io/docs/concepts/services-networking/ingress/

one could update an existing ingress yaml and subsequently run `kubectl replace -f`. From a microservice perspective, one could store a snippet in every git repo, e.g.:

```
- host: microservice01.domain.com
  http:
    paths:
    - backend:
        serviceName: ms01
        servicePort: 80
      path: /microservice01

```

and deploy it manually or automatically using ssh and merge it with another ingress file that has already been deployed

```
spec:
  rules:
  <concatenate snippet1>
  <concatenate snippet2>
  and so on and so on

```

and run `kubectl replace -f` once the snippet of a microservice has been deployed.
> 1 votes

---
Tags: kubernetes, microservices, architecture, nginx, ingress
---


# Question
Title: Ansible playbook to ensure Ruby gems are installed
Can I use ansible to make sure certain Ruby gems are installed on a list of Windows 7 hosts? How do I do this?

# Answer
> 2 votes
Sure you can. Use the gem module.

---
Tags: ansible, windows
---


# Question
Title: Jenkins Artifactory Integration - Custom Maven plugin creating dynamic version/build
I am currently working on a custom Maven plugin that generates a build artifact in the form of a zip file with a dynamic version or build number. The format of the file is something like

```
target/[artifactId]_[version or build].zip

```

Where \[version or build\] parameter is dynamically generated based on a snapshot of time, (Eg. \[changeset24\]-\[changeset57\]) on a parameterized Jenkins build where the user of the build will not necessarily know the latest changeset. The plugin uses an API to determine the latest changeset, for example changset57, and then uses the starting changeset parameter to form the unique version/build of the zip artifact.

This is meant to be a solution for streamlining the chaotic and manual process we face in our enterprise around delta based SQL scripts on hugely complicated schemas. There is no clear promotion path up through environments for a single versioned database artifact. It is a long story with a very immature devops organization and many frameworks and skill sets that do not mesh well, so I will spare the rest of the details here.

Ultimately we need to specify not the JAR artifact for this build to upload to Artifactory, but the ZIP file that is being created here, however Maven does not seem to allow for us to change the hard coded `<version>` in the POM file, and even if we could, we need the ability to:

1. Run the Maven build with custom plugin execution goal
2. Parse the output file for the unique version number that is generated
3. Override the `${VERSION}` or `${BUILD_NUMBER}` environment variables in Jenkins
4. Upload the artifact to Artifactory with the new environment variable for version or build number being included in build info.

The problem I have is that I seem to have trouble figuring out how to configure these 4 steps with the existing Maven3-Artifactory Jenkins plugins, nor with the Generic Artifactory Plugin using FileSpec JSON. I don't see how I can inject a custom shell script to override environment variables here either between this process.

Does anybody have any good suggestions of how I should configure this job?

*NOTE: Please don't suggest that my general approach is fundamentally bad or flawed or whatever. That is not helpful because I am facing numerous technological and political constraints that prevent a more appropriate solution.*

# Answer
I figured out how to get this job to run which took a number of very specific steps:

1) The Maven3-Artifactory plugin will simply not do what I need it do here. I still need this in my job though to actually execute my custom maven plugin from the project POM. I configured the Build Environment for this plugin to NOT upload any build artifacts to Artifactory.

2) I added the Generic Artifactory plugin that has the responsibility of taking the zip artifact from the Maven plugin and uploading it to our Artifactory repo. I **struggled** to define an upload FileSpec that worked correctly. I ended up using the Legacy Patterns option where I could define the upload artifact and the repo location based on a number of Environment Variables that have been already defined for me previously (more info on this in future steps). The Download Details are effectively empty.

3) The first Build Step is execution of the Maven build.

4) The second build step is execution of a custom shell that will parse the maven build artifact zip file for information that is needed to derive the version number. It then injects this version number into a temporary property file in the root of the job workspace.

5) The third build step uses the Inject Environment Variables plugin to put the temporary property file into environment variables used by the Generic Artifactory Plugin Legacy Pattern.

This seems to work well as a solution for my situation.
> 1 votes

---
Tags: jenkins, maven, artifactory
---


# Question
Title: Amazon Web Service (AWS): Spot request active followed by cancelled terminating
```
5/31/2018, 5:21:51 PM   fleetRequestChange  cancelled
5/31/2018, 5:15:46 PM   fleetRequestChange  cancelled_terminating
5/31/2018, 5:15:46 PM   fleetRequestChange  active
5/31/2018, 5:15:36 PM   fleetRequestChange  submitted

```

I am trying to create a Spot instance. However, it's cancelled right after it's being activated. Tried several times.

What is the problem??

# Answer
Seems like the initial limit for instances is set to 1. Solution is to request a limit increase which is not intuitive by the provided instance cancellation.

AWS Service Limits

> You can take the following steps to request an increase for limits. These increases are not granted immediately, so it may take a couple of days for your increase to become effective.
>
> To request a limit increase
>
> Open the AWS Support Center page, sign in if necessary, and choose Create Case.
>
> For Regarding, choose Service Limit Increase.
>
> Complete Limit Type, Use Case Description, and Contact method. If this request is urgent, choose Phone as the method of contact instead of Web.
>
> Choose Submit.
> 0 votes

---
Tags: amazon-web-services, amazon-ec2
---


title: Bamboo Group Deploy Projects

text:
# Question
Title: Bamboo Group Deploy Projects
I have a numerous deploy projects in Bamboo that are used for deploying DevOps/release tools. I would like have all of these projects grouped together for easy reference. Is there a way to group or organize related projects in Bamboo? Ideally, this would be similar to how the build plans are grouped.

# Answer
There is an improvement issue open for, I *think*, exactly what you're looking for: Bamboo should be able to group projects:

> Description
>
> I'm mulling over redoing our project heirarchy and grouping things a little more logically, and realize that being able to group projects in Bamboo would be brilliant. It's already stellar that each project can contain multiple build plans. Having project groups (a la Jira) would make my OCD squeal. Any chance of this?
> 2 votes

# Answer
In case someone else finds this question, I thought I'd mention Favorites. You can mark certain jobs as favorites, and then have those jobs appear on your "My Bamboo"-page. That's obviously just *one* group, but still it might help.
> 1 votes

---
Tags: bamboo
---


# Question
Title: What are best practices for sharing Docker compose files with ops team to use in Docker stack
I'm looking for best practices to share the Docker compose files created by developers with the people that do the deployment.

We use 2 docker compose files: `docker-compose.yml` and `docker-compose.prod.yml`.

These files are included in version control (git in our case).

We have 2 options:

1. Include the compose files in the master branch, and checkout the entire master branch when the application needs to be deployed. Pro here is that it is easy to keep everything in sync, con that the entire projects needs to be cloned on the server when the application is deployed.
2. Include the compose files in a orphaned branch that can be checked out when the application needs to be deployed. The pro here is that only the compose files will be checked out, con that we have 2 branches that needs to be maintained.

Since we are fairly new to this, I'm wondering how other organizations approach this, and why one method should be preferred over the other?

# Answer
Some thoughts:

1. You do not have to clone the entire project. https://stackoverflow.com/questions/2466735/how-to-checkout-only-one-file-from-git-repository-sparse-checkout?utm\_medium=organic&utm\_source=google\_rich\_qa&utm\_campaign=google\_rich\_qa discusses how to checkout a single file. I have also had good results using curl to get single files off github.
2. You can containerize it. Like this

> ```
> FROM docker/compose:1.21.2
> RUN mkdir /src
> WORKDIR /src
> COPY docker-compose.yml /src/docker-compose.yml
> ENTRYPOINT ["docker-compose"]
> CMD []
>
> ```

You can containerize docker-compose just like any other application.
> 2 votes

---
Tags: docker, docker-compose, dtap
---


# Question
Title: ansible tower_project module, always getting "ansible-tower-cli required for this module"
I have a control host that has the following:

* ansible --version = 2.5.2
* tower-cli --version == 3.3.0

tower-cli is able to connect to a remote Ansible Tower instance (note, Ansible tower itself is not installed on this control host). Can run 'tower-cli user list' on control host and works as expected.

However, when I try to use a playbook with the tower\_\* modules, such as:

```
  tasks:
  - name: create the SCM project
    tower_project:
      name: "test project"
      state: present
      ...

```

Always getting the following:

> ansible-tower-cli required for this module

Any ideas, as I can use tower-cli just fine on this localhost that is running the playbook.

# Answer
> 2 votes
Found the origin of the issue, and unless someone else had run into it they wouldn't have known where to look --

check details of `tower-cli --version` and `ansible --version`, as well as `which tower-cli` `which ansible`; in my case were installed in *different* python environments:

> /usr/lib/python**2.6**/site-packages/ansible
>
> /usr/lib/python**3.4**/site-packages/tower\_cli

If you cannot see the python version using the above for tower-cli, you can run:

```
$ head -n1 `which tower-cli`
#!/usr/local/opt/python/bin/python3.7
$

```

The ansible modules couldn't see the tower\_cli python modules as they were in a different python environment.

After-the-fact problem origin: I had installed **`ansible` via `yum`** (package manager), and **`ansible-tower-cli` via `pip`** (python installer). Being consistent in how you install both to make sure they go to the same environment resolves the issue.

*Centos/RHEL*: `yum install ansible ansible-tower-cli`

-OR-

*Python*: `pip install ansible`

*Python*: `pip install ansible-tower-cli`

---
Tags: ansible
---


# Question
Title: Help! No development infrastructure in company! I've been tasked to implement it!
**Background:** I've recently started at a company and I've bee tasked to essentially modernize the development team/dept. Currently the problems are:

* Developers currently develop on a live site.
* Sites are backed up but they have no source control.
* No staging process (dev, QA, UAT, live).
* No automated build process.
* No SDLC.
* Minimal (if any) documentation.
* Sites use different technologies.
* Timelines are insane because of huge development delays.
* Development team aren't aware of common tools that can assist with debugging/development.

**The plan** My thoughts so far are (in no specific order):

* Bring all projects up to using the same technologies.
* Throw all active projects into source control.
* Implement staging so that we have Dev, QA, UAT and Live.
* Implement CI/CD
* Introduce tooling and setup training for development team.
* Implement coding standards.
* Introduce a methodology more suited to how the team currently operates, most likely Agile or Scrum and the tools and documentation templates that go with it.

**The Questions**

* Have you been in this scenario before? How did you address and overcome these obstacles? How long did it take to implement? (as a rough idea)
* How would you prioritize the tasks listed above?
* What would you recommend I look into/research? (I'm particularly interested in terms of CI/CD and just how to negotiate such a huge task)

I feel like I need a kind of Maslow's hierarchy of needs to get more of an idea of where/how to start and what to build up to.

**Closing notes** Any resources, links, just a pooling of materials, etc. would be greatly appreciated.

Sorry - I know this could be considered a vague question and would give an opinionated response but that would provide the most benefit to me since if I knew exactly the right questions to ask I wouldn't need help because I could use a search engine.

# Answer
> Have you been in this scenario before?

Yes. Pretty standard scenario in my experience.

> How did you address and overcome these obstacles?

In very small steps.

> How long did it take to implement? (as a rough idea)

Very long; in one rather large extreme case: over 10 years, and still ongoing.

> How would you prioritize the tasks listed above?

My priority, with additional comments:

* Throw all active projects into source control.
    + This should really be a no-brainer and low-hanging fruit.
* Implement coding standards.
    + Sensibly.
* Introduce a methodology more suited to how the team currently operates, most likely Agile or Scrum and the tools and documentation templates that go with it.
    + If there is no methodology at all right now, then I'd start with a very lenient Kanban first - which basically just means throw up a ticket system and keep track of everything relentlessly. I would hold off with full-fledged Scrum until everything is on track and you're established as a Good Guy.
* Implement staging so that we have Dev, QA, UAT and Live.
    + With this goes more separation; i.e. devs need to be weaned off of the production systems.
* Introduce tooling and setup training for development team.
    + Try to have the teams develop their own tools if at all possible.
* Implement CI/CD
* Bring all projects up to using the same technologies.
    + Might just not be feasible, if by technologies you mean languages and libraries. If you mean Docker or OpenShift or whatever, then sure.

The most important tip for you from my experience: avoid, at all cost, to do everything yourself. Give "impulses" to the teams, but they have to do it (whatever "it" is) themselves. If you do all the work (either personally, or with your separate "DevOps team"), then you will, at the end of the day, not gain that much as everybody will just depend on you constantly.
> 4 votes

# Answer
I'd prioritize things like this:

1. put all projects in version control
2. automate the builds and immediately/simultaneously bring up CI with those builds - this is important to prevent the teams not yet used with version control from falling into the branching nightmare trap - they will start appreciating the CI fast feedback, even if just for the build portion, they'll start gaining confidence into all these upcoming changes which could be quite scary for them
3. create at least one staging environment, automate deployments to it, start building/growing automated testing and hook them all up to the CI system - now they'll have fast feedback including testing

I consider the above absolutely necessary to still be able to maintain the current projects without draining all resources on it, before considering other tools/technology changes, building the rest of the CI/CD pipeline, going into re-works, bring agile into the picture, etc.
> 1 votes

---
Tags: methodology, startup
---


title: Docker Swarm loop

text:
# Question
Title: Docker Swarm loop
I have written my own simple docker image. It works fine.

Then I created my docker swarm with only two nodes a master and a slave and started a service with the following command:

`docker service create --mode global --name benchmark briomkez/ethereum-test`

It loops, because it cannot create the service (the default command is a simple `ls`).

Why does this happen? Is it expected?

If I run the same service with a different command, e.g.:

`docker service create --mode global --name benchmark briomkez/ethereum-test geth`

It works like a charm. Is this behavior expected, what is the motivation for the loop?

# Answer
> 1 votes
Docker containers are isolated applications. When the application that it launches exits, the container also exits. So when your command is `ls`, that will run and then exit almost immediately, stopping the container.

Swarm mode has the goal to maintain a target state for your containers. By default, it will keep a single replica (instance of a container) of the service running. If the current state does not match the target state, it will take action to correct the issue. So for a container that has no running instances and a target replica count of 1, it will be constantly started.

So yes, this is an expected behavior given the inputs. Instead of `ls`, you should be using a long running daemon process.

---
Tags: docker, docker-swarm
---


# Question
Title: Get changes of the parameterized pipeline on the fly in Jenkins
Is it possible to get changes of the parameterized pipeline on the fly after making changes there?

For example I have a pipeline code:

```
properties([
        parameters([
                string(name: 'TARGET_HOST', defaultValue: 'test', description: 'Host on which artifact will be deployed'),
                string(name: 'ARTIFACT_ID', defaultValue: 'test', description: 'Name of artifact which will be doployed'),
                string(name: 'ARTIFACT_VERSION', defaultValue: '1', description: 'Version of artifact which will be deployed')
        ])
])

```

And I decided to change defaultValue for TARGET\_HOST parameter from test to 1.

After such changes, I'll need to run job in order it apply changes and only running it for the second time after making changes, I'll obtain applied changes.

Is there a way to make job pick up changes during first run after making them?

So far I found a way to do it with Input structure:

```
def values = input id: 'Run-test-suites',
        message: 'Workflow Configuration',
        ok: 'Run',
        parameters: [
                [
                        $class      : 'BooleanParameterDefinition',
                        defaultValue: true,
                        name        : 'checkboxVal',
                        description : 'Testing of checkbox param'
                ],
                [
                        $class      : 'StringParameterDefinition',
                        defaultValue: "test",
                        name        : 'stringVal',
                        description : 'Testing of string param'
                ],
                [
                        $class     : 'ChoiceParameterDefinition', choices: '1\n2\n3',
                        name       : 'choiceVal',
                        description: 'Testing of choice parameter'
                ]
        ]

```

But I want to have something more flexible.

# Answer
Currently what you are asking for is not possible. This is due to the way that the Jenkinsfile is loaded into the pipeline.

I think dolphy said it best on this StackOverflow answer (I saved this link a while ago to follow it for changes, because I had the same questions):

> Jenkins does not know about the new parameters until it retrieves, parses, and runs the Jenkinsfile, and the only way to do that is to...run a build.
>
> In effect, the build history will always be "one run behind" the Jenkinsfile; when you change something in the Jenkinsfile, the next build will run with the "old" Jenkinsfile, but pick up and process the new Jenkinsfile for the build after that.

There is also a related Jenkins Ticket you can follow
> 3 votes

---
Tags: jenkins, jenkins-pipeline, groovy
---


# Question
Title: docker-compose fails to recognize when images are rebuilt sometimes ... often same code is OK
I have a devops container inside of which I execute `docker build` and `docker-compose up` commands which run OK then (on same server or different server with same code) sometimes incorrectly fail to `Recreate` sibling containers after their images are rebuilt.

My process successfully rebuilds a pair of two underlying docker images however

```
docker-compose up

```

sometimes fails to pickup that change and incorrectly says up-to-date on freshly rebuilt images when it should be saying Recreating

I am executing identical code across several servers each with varying OS ( ubuntu 16.04 or debian 8 or debian 9) and varying docker versions ( either 18.04.0-ce-rc1 or 18.03.0-ce ) ... am currently working to track down root cause however see good and bad behavior across each of above OS and docker versions

This issue does not seem related to https://github.com/docker/compose/issues/3574

Yes I am tagging the images and doing a push to local docker repository

```
docker build --tag localhost:5000/hygge/loudweb-admin .

```

docker push to my local docker repository is

```
docker push localhost:5000/hygge/loudweb-admin

```

it also does similar to above image loudweb-enduser

here my my docker-compose.yaml

```
version: '3'
services:

nodejs-admin:
  image: ${GKE_APP_REPO_PREFIX}/${PROJECT_ID}/loudweb-admin
  container_name: loud_admin
  restart: always
  depends_on:
    - loudmongo
    - loudmail
  volumes:
    - /cryptdata4/var/log/loudlog-admin:/loudlog-admin
    - /cryptdata5/var/log/blobs:/blobs
    - /cryptdata5/var:/cryptdata5/var
    - /cryptdata5/var/tools:/tools
    - /cryptdata6/var/log/loudlog-enduser:/loudlog-enduser
    - $SOURCE_REPO_DIR/tests:/tmp/tests
    - ${TMPDIR_GRAND_PARENT}/curr/loud-build/${PROJECT_ID}/webapp/admin/bundle:/tmp
  environment:
    - MONGO_SERVICE_HOST=loudmongo
    - MONGO_SERVICE_PORT=$GKE_MONGO_PORT
    - MONGO_URL=mongodb://loudmongo:$GKE_MONGO_PORT/test
    - METEOR_SETTINGS=${METEOR_SETTINGS}
    - MAIL_URL=smtp://support@${GKE_DOMAIN_NAME}:blah@loudmail:587/
    - GKE_NOTIF_TASK_OVERDUE=$GKE_NOTIF_TASK_OVERDUE
    - GKE_NOTIF_TASK_PUSH=$GKE_NOTIF_TASK_PUSH
    - GKE_NOTIF_PLANS_RECUR=$GKE_NOTIF_PLANS_RECUR
  links:
    - loudmongo
    - loudmail
  ports:
   - 127.0.0.1:3001:3001
  working_dir: /tmp
  command: /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

nodejs-enduser:
  image: ${GKE_APP_REPO_PREFIX}/${PROJECT_ID}/loudweb-enduser
  container_name: loud_enduser
  restart: always
  depends_on:
    - nodejs-admin
    - loudmongo
    - loudmail
  volumes:
    - /cryptdata6/var/log/loudlog-enduser:/loudlog-enduser
    - /cryptdata5/var/log/blobs:/blobs
    - ${TMPDIR_GRAND_PARENT}/curr/loud-build/${PROJECT_ID}/webapp/enduser/bundle:/tmp
    - ${TMPDIR_GRAND_PARENT}/curr/loud-build/${PROJECT_ID}/webapp/admin/bundle/programs/server/assets/app/config/apn-cert.pem:/private/config/apn-cert.pem
    - ${TMPDIR_GRAND_PARENT}/curr/loud-build/${PROJECT_ID}/webapp/admin/bundle/programs/server/assets/app/config/apn-key.pem:/private/config/apn-key.pem
  environment:
    - MONGO_SERVICE_HOST=loudmongo
    - MONGO_SERVICE_PORT=$GKE_MONGO_PORT
    - MONGO_URL=mongodb://loudmongo:$GKE_MONGO_PORT/test
    - METEOR_SETTINGS=${METEOR_SETTINGS}
    - MAIL_URL=smtp://support@${GKE_DOMAIN_NAME}:puMDcxNmEwMDU5MmJjZjNiNzQ3M2ZlNTJjNDYyOGI1NTggIC0Ksy@loudmail:587/
  links:
    - loudmongo
    - loudmail
  ports:
   - 127.0.0.1:3000:3000
  working_dir: /tmp
  command: /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

loudmongo:
  image: mongo
  container_name: loud_mongo
  restart: always
  ports:
   - 127.0.0.1:$GKE_MONGO_PORT:$GKE_MONGO_PORT
  volumes:
   - /cryptdata7/var/data/db:/data/db

loudmail:
  image: ${GKE_APP_REPO_PREFIX}/${PROJECT_ID}/loudmail
  hostname: mail
  domainname: ${GKE_DOMAIN_NAME}
  container_name: loud_mail
  restart: always
  environment:
    - DMS_DEBUG=1
    - ENABLE_MANAGESIEVE=1
    - ENABLE_FAIL2BAN=1
    - SA_TAG=2.0
    - SA_TAG2=6.31
    - SA_KILL=6.31
    - SSL_TYPE=letsencrypt
  ports:
    - 127.0.0.1:25:25
    - 127.0.0.1:110:110
    - 127.0.0.1:143:143
    - 127.0.0.1:587:587
    - 127.0.0.1:993:993
    - 127.0.0.1:995:995
    - 127.0.0.1:4190:4190

loud-devops:
  image: dind
  container_name: loud_devops
  restart: always
  ports:
    - 127.0.0.1:9000:9000
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - /usr/bin/docker:/usr/bin/docker
    - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7
    - /usr/lib/x86_64-linux-gnu/libgpm.so.2:/usr/lib/x86_64-linux-gnu/libgpm.so.2
    - /home/asya/src/github.com/blahblah:/inner_home/asya/src/github.com/blahblah
    - /home/asya/.docker:/inner_home/asya/.docker
    - /cryptdata5/var/tools/inner_home/asya:/inner_home/asya
    - $GKE_DIND_SUPERVISOR_LOG_DIR:/var/log/supervisor
    - /cryptdata5/var/tools/usr/local/go:/usr/local/go
    - /cryptdata6/var/log/tmp/asya01:/cryptdata6/var/log/tmp/asya01
    - /cryptdata6/var/log/tmp/shared:/cryptdata6/var/log/tmp/shared
    - /cryptdata5/var/tools/usr/local/bin:/usr/local/bin
    - /cryptdata:/cryptdata
    - /cryptdata4:/cryptdata4
    - /cryptdata5:/cryptdata5
    - /cryptdata6:/cryptdata6
    - /cryptdata7:/cryptdata7
    - /etc/letsencrypt/live:/etc/letsencrypt/live
    - /usr/local/ssl:/usr/local/ssl
    - /var/lib/docker:/var/lib/docker
  command: /usr/bin/supervisord -c /etc/supervisor/supervisord.conf

```

The bottom most container in above ( loud-devops ) contains a webhook daemon which listens for a git push to trigger a rebuild cycle. While inside that container the system issues all my docker command including docker build create fresh images for two containers ( nodejs-admin and nodejs-enduser ) then while inside the container I issue the

```
docker-compose -f /docker-compose.yaml up -d

```

which then sometimes incorrectly displays

```
loud_devops is up-to-date
loud_mongo is up-to-date
loud_mail is up-to-date
loud_admin is up-to-date
loud_enduser is up-to-date

```

other times it incorrectly displays

```
docker-compose -f /docker-compose.yml up -d
Recreating loud_devops ...
Recreating loud_mongo ...
Recreating loud_mail ...

```

which should NEVER happen since those 3 images are never rebuilt ... to me that scenario is a blatant docker logic bug ...

whereas other times works OK and correctly displays

```
loud_mongo is up-to-date
loud_mail is up-to-date
loud_devops is up-to-date
Recreating loud_admin ... done
Recreating loud_enduser ... done

```

On the host of each server I have docker installed then as you can see in above yaml for container loud-devops I mount as volumes various docker dirs to enable the execution of docker in docker from inside container loud-devops

A critical piece of evidence : on a server which has finished its rebuild cycle where it successfully rebuilt both images loudweb-enduser and loudweb-admin then incorrectly shows

```
docker-compose -f /docker-compose.yml up -d
loud_mail is up-to-date
loud_mongo is up-to-date
loud_devops is up-to-date
loud_admin is up-to-date
loud_enduser is up-to-date

```

where the `docker-compose up` command gets executed by the system while inside container loud-devops ... IF I then manually login to that same server then manually issue the same command it works correctly :

```
docker-compose -f /docker-compose.yml up -d
loud_devops is up-to-date
loud_mail is up-to-date
loud_mongo is up-to-date
Recreating loud_admin ... done
Recreating loud_enduser ... done

```

# Answer
> 0 votes
Solution was to put a docker pull into my launch script ... as in

```
docker-compose -f ${GKE_COMPOSE_YAML} pull

```

just before issuing

```
docker-compose -f ${GKE_COMPOSE_YAML} up -d

```

which seems strange since most of the time it works OK without issuing pull ... I am using a local docker registry

---
Tags: docker, docker-compose, docker-in-docker
---