Don't set db_work_mem
[discourse_docker.git] / launcher
index 3dd2944e99c734ffea6e25c61dacfa9aa85f7ed7..1f3561f1a4e1de3ceef91fdbfe9125cadad56119 100755 (executable)
--- a/launcher
+++ b/launcher
@@ -4,17 +4,28 @@ command=$1
 config=$2
 opt=$3
 
+# Docker doesn't like uppercase characters, spaces or special characters, catch it now before we build everything out and then find out
+re='[A-Z/ !@#$%^&*()+~`=]'
+if [[ $config =~ $re ]];
+  then
+    echo
+    echo "ERROR: Config name must not contain upper case characters, spaces or special characters. Correct config name and rerun $0."
+    echo
+    exit 1
+fi
+
 cd "$(dirname "$0")"
 
-docker_min_version='1.2.0'
-docker_rec_version='1.2.0'
+docker_min_version='1.6.0'
+docker_rec_version='1.6.0'
 
 config_file=containers/"$config".yml
-cidfile=cids/"$config".cid
-cidbootstrap=cids/"$config"_boostrap.cid
+cidbootstrap=cids/"$config"_bootstrap.cid
 local_discourse=local_discourse
-image=samsaffron/discourse:1.0.6
+image=discourse/discourse:1.0.17
 docker_path=`which docker.io || which docker`
+template_path=samples/standalone_template.yml
+changelog=/tmp/changelog # used to test whether sed did anything
 
 if [ "${SUPERVISED}" = "true" ]; then
   restart_policy="--restart=no"
@@ -24,7 +35,9 @@ else
   attach_on_run="-d"
 fi
 
-if [ -x "$(which ip 2>/dev/null)" ]; then
+if [ -n "$DOCKER_HOST" ]; then
+  docker_ip=`sed -e 's/^tcp:\/\/\(.*\):.*$/\1/' <<< "$DOCKER_HOST"`
+elif [ -x "$(which ip 2>/dev/null)" ]; then
   docker_ip=`ip addr show docker0 | \
                   grep 'inet ' | \
                   awk '{ split($2,a,"/"); print a[1] }';`
@@ -47,12 +60,13 @@ usage () {
   echo "    enter:      Use nsenter to enter a container"
   echo "    ssh:        Start a bash shell in a running container"
   echo "    logs:       Docker logs for container"
-  echo "    mailtest:   Test the mail settings in a container"
   echo "    bootstrap:  Bootstrap a container for the config based on a template"
   echo "    rebuild:    Rebuild a container (destroy old, bootstrap, start new)"
+  echo "    memconfig:  Configure defaults based on available RAM"
+  echo "    cleanup:    Remove all containers that have stopped for > 24 hours"
   echo
   echo "Options:"
-  echo "    --skip-prereqs   Don't check prerequisites"
+  echo "    --skip-prereqs   Don't check prerequisites or resource requirements"
   echo "    --docker-args    Extra arguments to pass when running docker"
   exit 1
 }
@@ -81,7 +95,9 @@ compare_version() {
 prereqs() {
 
   # 1. docker daemon running?
-  test=`$docker_path info >/dev/null`
+  # we send stderr to /dev/null cause we don't care about warnings,
+  # it usually complains about swap which does not matter
+  test=`$docker_path info 2> /dev/null`
 
   if [[ $? -ne 0 ]] ; then
     echo "Cannot connect to the docker daemon - verify it is running and you have access"
@@ -90,10 +106,14 @@ prereqs() {
 
   # 2. running aufs or btrfs
   test=`$docker_path info 2> /dev/null | grep 'Driver: '`
-  if [[ "$test" =~ [aufs|btrfs] ]] ; then : ; else
-    echo "Your Docker installation is not using the recommended AuFS (union filesystem) and may be unstable."
-    echo "If you are unable to bootstrap / stop your image please report the issue at:"
-    echo "https://meta.discourse.org/t/discourse-docker-installation-without-aufs/15639"
+  if [[ "$test" =~ [aufs|btrfs|zfs|overlay] ]] ; then : ; else
+    echo "Your Docker installation is not using a supported filesystem if we were to proceed you may have a broken install."
+    echo "aufs is the recommended filesystem you should be using (zfs/btrfs and overlay may work as well)"
+    echo "You can tell what filesystem you are using by running \"docker info\" and looking at the driver"
+    echo ""
+    echo "If you wish to continue anyway using your existing unsupported filesystem"
+    echo "read the source code of launcher and figure out how to bypass this."
+    exit 1
   fi
 
   # 3. running recommended docker version
@@ -113,7 +133,20 @@ prereqs() {
     echo "WARNING: Docker version ${test} deprecated, recommend upgrade to ${docker_rec_version} or newer."
   fi
 
-  # 4. able to attach stderr / out / tty
+  # 4. discourse docker image is downloaded
+  test=`$docker_path images | awk '{print $1 ":" $2 }' | grep "$image"`
+
+  if [ -z "$test" ]; then
+    echo
+    echo "WARNING: We are about to start downloading the Discourse base image"
+    echo "This process may take anywhere between a few minutes to an hour, depending on your network speed"
+    echo
+    echo "Please be patient"
+    echo
+
+  fi
+
+  # 5. able to attach stderr / out / tty
   test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working`
   if [[ "$test" =~ "working" ]] ; then : ; else
     echo "Your Docker installation is not working correctly"
@@ -121,6 +154,65 @@ prereqs() {
     echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam"
     exit 1
   fi
+
+}
+
+check_resources() {
+  # Memory
+  resources="ok"
+  avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
+  if [ "$avail_mem" -lt 900 ]; then
+    resources="insufficient"
+    echo "WARNING: You do not appear to have sufficient memory to run Discourse."
+    echo
+    echo "Your system may not work properly, or future upgrades of Discourse may"
+    echo "not complete successfully."
+    echo
+    echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#create-new-cloud-server"
+  elif [ "$avail_mem" -lt 1800 ]; then
+    total_swap="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
+    if [ "$total_swap" -lt 1000 ]; then
+      resources="insufficient"
+      echo "WARNING: You must have at least 1GB of swap when running with less"
+      echo "than 2GB of RAM."
+      echo
+      echo "Your system may not work properly, or future upgrades of Discourse may"
+      echo "not complete successfully."
+      echo
+      echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#set-up-swap-if-needed"
+    fi
+  fi
+
+  # Disk space
+  free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
+  if [ "$free_disk" -lt 5000 ]; then
+    resources="insufficient"
+    echo "WARNING: You must have at least 5GB of *free* disk space to run Discourse."
+    echo
+    echo "Insufficient disk space may result in problems running your site, and may"
+    echo "not even allow Discourse installation to complete successfully."
+    echo
+    echo "Please free up some space, or expand your disk, before continuing."
+    exit 1
+  fi
+
+  if [ -t 0 ] && [ "$resources" != "ok" ]; then
+    echo
+    read -p "Press ENTER to continue, or Ctrl-C to exit and give your system more resources"
+  fi
+}
+
+check_ports() {
+  local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
+
+  if [ -n "$valid" ]; then
+    echo "Launcher has detected that port ${1} is in use."
+    echo ""
+    echo "If you are trying to run Discourse simultaneously with another web server like Apache or nginx, you will need to bind to a different port."
+    echo "See https://meta.discourse.org/t/17247 for help."
+    echo "To continue anyway, re-run Launcher with --skip-prereqs"
+    exit 1
+  fi
 }
 
 if [ "$opt" != "--skip-prereqs" ] ; then
@@ -151,41 +243,22 @@ get_ssh_pub_key() {
     fi
   done
 
-  if tty -s ; then
-    echo "This user has no SSH key, but a SSH key is required to access the Discourse Docker container."
-    read -p "Generate a SSH key? (Y/n) " -n 1 -r
-    if [[ $REPLY =~ ^[Nn]$ ]] ; then
-      echo
-      echo WARNING: You may not be able to log in to your container.
-      echo
-    else
-      echo
-      echo Generating SSH key
-      mkdir -p ~/.ssh && ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
-      echo
-      ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)"
-      return 0
-    fi
-  fi
-
-  return 1
+  return 0
 }
 
 
 install_docker() {
 
-  echo "Docker is not installed, make sure you are running on the 3.8 kernel"
-  echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following"
+  echo "Docker is not installed, you will need to install Docker in order to run Discourse"
+  echo "Please visit https://docs.docker.com/installation/ for instructions on how to do this for your system"
   echo
-  echo "sudo apt-get update"
-  echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring"
-  echo "sudo reboot"
+  echo "If you are running Ubuntu Trusty or later, you can try the following:"
   echo
 
-  echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\""
-  echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
+  echo "sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D"
+  echo "sudo sh -c \"echo deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release -sc) main > /etc/apt/sources.list.d/docker.list\""
   echo "sudo apt-get update"
-  echo "sudo apt-get install lxc-docker"
+  echo "sudo apt-get install docker-engine"
 
   exit 1
 }
@@ -288,22 +361,43 @@ RUBY
 
     if [ "$ok" -ne 1 ]; then
       echo "${env[@]}"
-      echo "YAML syntax error. Please check your /var/docker/containers/*.yml config files."
+      echo "YAML syntax error. Please check your /var/discourse/containers/*.yml config files."
       exit 1
     fi
-    echo "Calculated ENV: ${env[@]}"
 }
 
 [ -z $docker_path ] && {
   install_docker
 }
 
+[ "$command" == "cleanup" ] && {
+  echo
+  echo "The following command will"
+  echo "- Delete all docker images for old containers"
+  echo "- Delete all stopped and orphan containers"
+  echo
+  read -p "Are you sure (Y/n): " -n 1 -r && echo
+  if [[ $REPLY =~ ^[Yy]$ || ! $REPLY ]]
+    then
+      space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
+      echo "Starting Cleanup (bytes free $space)"
+
+      STATE_DIR=./.gc-state scripts/docker-gc
+
+      space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
+      echo "Finished Cleanup (bytes free $space)"
+
+    else
+      exit 1
+  fi
+  exit 0
+}
 
 [ $# -lt 2 ] && {
   usage
 }
 
-if [ ! -e $config_file ]
+if [[ ! -e $config_file &&  $command -ne "memconfig" ]]
   then
     echo "Config file was not found, ensure $config_file exists"
     echo ""
@@ -322,78 +416,195 @@ else
   restart_policy=${restart_policy:---restart=always}
 fi
 
-
-run_mailtest(){
-  if [ ! -e $config_file ]; then
-    echo "Config does not exist: $config_file" >&2
-    exit 1
-  fi
-  exec scripts/mailtest $config_file
+set_existing_container(){
+  existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
 }
 
 run_stop(){
-  if [ ! -e $cidfile ]
+
+  set_existing_container
+
+  if [ ! -z $existing ]
      then
-       echo "No cid found"
-       exit 1
+       (
+        set -x
+        $docker_path stop -t 10 $config
+       )
      else
-       $docker_path stop -t 10 `cat $cidfile`
+       echo "$config was not started !"
+       exit 1
   fi
 }
 
-run_start(){
+set_run_image() {
+  run_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
+    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['run_image']"`
 
-  host_run
+  if [ -z "$run_image" ]; then
+    run_image="$local_discourse/$config"
+  fi
+}
 
-  if [ ! -e $cidfile ]
-     then
-       echo "No cid found, creating a new container"
-       ports=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
-              "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"`
-
-       set_template_info
-       set_volumes
-       set_links
-
-       existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep "$config$" | awk '{ print $1 }'`
-       if [ ! -z $existing ]
-       then
-         echo "Found an existing container by its name, recovering cidfile, please rerun"
-         echo $existing > $cidfile
-         exit 1
-       fi
+set_boot_command() {
+  boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
+    "require 'yaml'; puts YAML.load(STDIN.readlines.join)['boot_command']"`
 
-       $docker_path run $user_args $links $attach_on_run $restart_policy "${env[@]}" -h "`hostname`-$config" -e DOCKER_HOST_IP=$docker_ip --name $config -t --cidfile $cidfile $ports \
-                  $volumes $local_discourse/$config /sbin/boot
+  if [ -z "$boot_command" ]; then
 
-       exit 0
-     else
-       cid=`cat $cidfile`
+    no_boot_command=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
+      "require 'yaml'; puts YAML.load(STDIN.readlines.join)['no_boot_command']"`
 
-       if [ -z $cid ]
-       then
-         echo "Detected empty cid file, deleting, please re-run"
-         rm $cidfile
-         exit 1
-       fi
+    if [ -z "$no_boot_command" ]; then
+      boot_command="/sbin/boot"
+    fi
+  fi
+}
 
-       found=`$docker_path ps -q -a --no-trunc | grep $cid`
-       if [ -z $found ]
-       then
-         echo "Invalid cid file, deleting, please re-run"
-         rm $cidfile
-         exit 1
-       fi
+run_memconfig(){
+  if [ "$opt" != "--skip-prereqs" ] ; then
+    check_resources
+  fi
+  if [ -f $config_file ]
+  then
+    cp $config_file $config_file.bak
+    echo "Saving $config_file as $config_file.bak"
+  else
+    echo "Creating $config_file from $template_path"
+    if [ ! -f $template_path ]
+    then
+      echo "$template_path is missing. Exiting."
+      exit 1
+    fi
+    cp $template_path $config_file
+  fi
+
+  # get free mem
+  avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
+  avail_gb=`expr $(($avail_mem / 950))`
+  avail_cores=`grep -c processor /proc/cpuinfo`
+  echo "Found $avail_mem (${avail_gb}GB), of memory and $avail_cores cores."
+
+  # set db_shared_buffers: "128MB" (1GB) or 256MB * GB
+  if [ "$avail_gb" -eq "1" ]
+  then
+    db_shared_buffers="128"
+  else
+    db_shared_buffers=`expr $avail_gb \* 256`
+  fi
+  echo -e "Setting db_shared_buffers to ${db_shared_buffers}GB\c"
+  sed -i -e "s/^  db_shared_buffers:.*/  db_shared_buffers: \"${db_shared_buffers}GB\"/w $changelog" $config_file
+  if [ -s $changelog ]
+  then
+    echo " successfully."
+    rm $changelog
+  else
+    echo -e ". . . oops!\n---> db_shared_buffers not found in $config_file. Retaining defaults."
+  fi
 
-       echo "cid found, ensuring container is started"
-       $docker_path start $attach_on_start `cat $cidfile`
-       exit 0
+  # set UNICORN_WORKERS: 2*GB or 2*cores (the same on DO)
+  if [ "$avail_gb" -le "2" ]
+  then
+    unicorn_workers=`expr $avail_gb \* 2`
+  else
+    unicorn_workers=`expr $avail_cores \* 2`
   fi
 
+  echo -e "Setting UNICORN_WORKERS to $unicorn_workers\c"
+  sed -i -e "s/^  UNICORN_WORKERS:.*/  UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
+  if [ -s $changelog ]
+  then
+      echo " successfully."
+      rm $changelog
+  else
+    echo -e ". . . oops!\n---> UNICORN_WORKERS not found in $config_file. Retaining defaults.\n"
+  fi
+}
+
+run_start(){
+
+   existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
+   echo $existing
+   if [ ! -z $existing ]
+   then
+     echo "Nothing to do, your container has already started!"
+     exit 1
+   fi
+
+   existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
+   if [ ! -z $existing ]
+   then
+     echo "starting up existing container"
+     (
+       set -x
+       $docker_path start $config
+     )
+     exit 0
+   fi
+
+   host_run
+   ports=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
+          "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| \"-p #{p}\"}.join(' ')"`
+
+   IFS='-p ' read -a array <<< "$ports"
+   for element in "${array[@]}"
+   do
+     IFS=':' read -a args <<< "$element"
+     if [ "${#args[@]}" == "2" ]; then
+       check_ports "${args[0]}"
+     elif [ "${#args[@]}" == "3" ]; then
+       check_ports "${args[1]}"
+     fi
+   done
+
+   docker_args=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
+          "require 'yaml'; puts YAML.load(STDIN.readlines.join)['docker_args']"`
+
+   set_template_info
+   set_volumes
+   set_links
+   set_run_image
+   set_boot_command
+
+   # get hostname and settings from container configuration
+   for envar in "${env[@]}"
+   do
+     if [[ $envar == DOCKER_USE_HOSTNAME* ]] || [[ $envar == DISCOURSE_HOSTNAME* ]]
+     then
+       # use as environment variable
+       eval $envar
+     fi
+   done
+
+   (
+     hostname=`hostname -s`
+     # overwrite hostname
+     if [ "$DOCKER_USE_HOSTNAME" = "true" ]
+     then
+       hostname=$DISCOURSE_HOSTNAME
+     else
+       hostname=$hostname-$config
+     fi
+
+     # we got to normalize so we only have allowed strings, this is more comprehensive but lets see how bash does first
+     # hostname=`$docker_path run $user_args --rm $image ruby -e 'print ARGV[0].gsub(/[^a-zA-Z-]/, "-")' $hostname`
+     # docker added more hostname rules
+     hostname=${hostname/_/-}
+
+     set -x
+     $docker_path run $user_args $links $attach_on_run $restart_policy "${env[@]}" -h "$hostname" \
+        -e DOCKER_HOST_IP=$docker_ip --name $config -t $ports $volumes $docker_args $run_image $boot_command
+
+   )
+   exit 0
+
 }
 
 run_bootstrap(){
 
+  if [ "$opt" != "--skip-prereqs" ] ; then
+    check_resources
+  fi
+
   host_run
 
   get_ssh_pub_key
@@ -433,7 +644,7 @@ run_bootstrap(){
      /bin/bash -c "$run_command") \
      || ($docker_path rm `cat $cidbootstrap` && rm $cidbootstrap)
 
-  [ ! -e $cidbootstrap ] && echo "FAILED TO BOOTSTRAP" && exit 1
+  [ ! -e $cidbootstrap ] && echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one" && exit 1
 
   sleep 5
 
@@ -441,6 +652,8 @@ run_bootstrap(){
   $docker_path rm `cat $cidbootstrap` && rm $cidbootstrap
 }
 
+
+
 case "$command" in
   bootstrap)
       run_bootstrap
@@ -448,51 +661,21 @@ case "$command" in
       exit 0
       ;;
 
-  mailtest)
-      run_mailtest
-      exit 0
-      ;;
-
   enter)
-
-      if [ ! -e $cidfile ]
-         then
-           echo "No cid found"
-           exit 1
-      fi
-
-      if [ ! $UID -eq 0 ] ;
-        then
-        echo "enter command must run as root, will attempt to sudo"
-        echo
-      fi
-
-      if [ ! -e bin/nsenter ]
-        then
-          echo "Downloading nsenter"
-          $docker_path pull samsaffron/nsenter
-          ($docker_path run $user_args --rm samsaffron/nsenter cat /nsenter > bin/nsenter1) || exit 1
-          cp bin/nsenter1 bin/nsenter
-          chmod +x bin/nsenter
-      fi
-
-      PID=$($docker_path inspect --format {{.State.Pid}} `cat $cidfile`)
-      SHELL=/bin/bash sudo -E bin/nsenter --target $PID --mount --uts --ipc --net --pid
-
-      exit 0;
+      exec $docker_path exec -it $config /bin/bash --login
       ;;
 
   ssh)
-      if [ ! -e $cidfile ]
-         then
-           echo "No cid found"
-           exit 1
-         else
-           cid="`cat $cidfile`"
-           address="`$docker_path port $cid 22`"
-           split=(${address//:/ })
-           exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]}
-      fi
+       existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
+
+       if [[ ! -z $existing ]]; then
+         address="`$docker_path port $config 22`"
+         split=(${address//:/ })
+         exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]}
+       else
+         echo "$config is not running!"
+         exit 1
+       fi
       ;;
 
   stop)
@@ -502,14 +685,8 @@ case "$command" in
 
   logs)
 
-      if [ ! -e $cidfile ]
-         then
-           echo "No cid found"
-           exit 1
-         else
-           $docker_path logs `cat $cidfile`
-           exit 0
-      fi
+      $docker_path logs $config
+      exit 0
       ;;
 
   restart)
@@ -523,22 +700,58 @@ case "$command" in
       exit 0
       ;;
 
+  memconfig)
+      run_memconfig
+      exit 0
+      ;;
+
   rebuild)
       if [ "$(git symbolic-ref --short HEAD)" == "master" ]; then
-        echo "Updating discourse docker"
-        git pull || (echo 'failed to update' && exit 1)
+        echo "Ensuring discourse docker is up to date"
+
+        git remote update
+
+        LOCAL=$(git rev-parse @)
+        REMOTE=$(git rev-parse @{u})
+        BASE=$(git merge-base @ @{u})
+
+        if [ $LOCAL = $REMOTE ]; then
+          echo "Discourse Docker is up-to-date"
+
+        elif [ $LOCAL = $BASE ]; then
+          echo "Updating Discourse Docker"
+          git pull || (echo 'failed to update' && exit 1)
+          exec /bin/bash $0 $@
+
+        elif [ $REMOTE = $BASE ]; then
+          echo "Your version of Discourse Docker is ahead of origin"
+
+        else
+          echo "Discourse Docker has diverged source, this is only expected in Dev mode"
+        fi
+
       fi
-      if [ -e $cidfile ]
+
+      set_existing_container
+
+      if [ ! -z $existing ]
         then
           echo "Stopping old container"
-          $docker_path stop -t 10 `cat $cidfile`
+          (
+            set -x
+            $docker_path stop -t 10 $config
+          )
       fi
 
       run_bootstrap
 
-      if [ -e $cidfile ]
+      if [ ! -z $existing ]
         then
-          $docker_path rm `cat $cidfile` && rm $cidfile
+          echo "Removing old container"
+          (
+            set -x
+            $docker_path rm $config
+          )
       fi
 
       run_start
@@ -547,16 +760,8 @@ case "$command" in
 
 
   destroy)
-      if [ -e $cidfile ]
-        then
-          echo "destroying container $cidfile"
-          $docker_path stop -t 10 `cat $cidfile`
-          $docker_path rm `cat $cidfile` && rm $cidfile
-          exit 0
-        else
-          echo "nothing to destroy cidfile does not exist"
-          exit 1
-      fi
+      (set -x; $docker_path stop -t 10 $config && $docker_path rm $config) || (echo "$config was not found" && exit 0)
+      exit 0
       ;;
 esac