 
 (defn resource
   [{:keys [cpu memory]}]
-  {:cpus   (some-> cpu (str))
-   :memory (some-> memory (str "M"))})
+  {:cpus   (when (< 0 cpu) (str cpu))
+   :memory (when (< 0 memory) (str memory "M"))})
 
 (defn service
-  [stackName service]
-  {(keyword (alias :serviceName stackName service))
+  [stack-name service]
+  {(keyword (alias :serviceName stack-name service))
    {:image       (-> service :repository :image)
     :environment (->> service :variables
                       (map #(str (:name %) "=" (:value %))))
     :ports       (->> service :ports
                       (map #(str (:hostPort %) ":" (:containerPort %) (when (= "udp" (:protocol %)) "/udp"))))
     :volumes     (->> service :mounts
-                      (map #(str (alias :host stackName %) "=" (:containerPath %) (when (:readOnly %) ":ro"))))
-    :networks    (->> service :networks (map #(alias :networkName stackName %)))
+                      (map #(str (alias :host stack-name %) "=" (:containerPath %) (when (:readOnly %) ":ro"))))
+    :networks    (->> service :networks (map #(alias :networkName stack-name %)))
     :deploy      {:mode      (when-not (= "replicated" (:mode service)) (:mode service))
                   :placement {:constraints (->> service :deployment :placement (map :rule))}
                   :resources {:reservations (-> service :resources :reservation resource)
                               :limits       (-> service :resources :limit resource)}}}})
 
 (defn network
-  [stackName net]
-  {(keyword (alias :networkName stackName net)) (select-keys net [:driver])})
+  [stack-name net]
+  {(keyword (alias :networkName stack-name net))
+   (if (in-stack? stack-name net)
+     {:driver      (:driver net)
+      :internal    (when (:internal net) true)
+      :driver_opts (:options net)}
+     {:external true})})
 
 (defn volume
-  [stackName volume]
-  {(keyword (alias :volumeName stackName volume)) (select-keys volume [:driver])})
+  [stack-name volume]
+  {(keyword (alias :volumeName stack-name volume))
+   (if (in-stack? stack-name volume)
+     {:driver      (:driver volume)
+      :driver_opts (:options volume)}
+     {:external true})})
+
+(defn secret
+  [_ secret]
+  {(keyword (:secretName secret))
+   {:external true}})
+
+(defn config
+  [_ config]
+  {(keyword (:configName config))
+   {:external true}})
 
 (defn ->compose
   [stack]

  (:require [clojure.string :as str]
            [clojure.set :refer [rename-keys]]
            [swarmpit.utils :refer [clean select-keys*]]
            [swarmpit.yaml :refer [->yaml]])
  (:refer-clojure :exclude [alias]))

(defn alias
  [key stackName map]
  (let [name (get map key)]
    (if (= stackName (:stack map))
      (str/replace name (str stackName "_") "")
      name)))

(defn group
  [stackName fn coll]
  (->> coll
       (map #(fn stackName %))
       (into {})))

(defn environment

    (-> {:version  "3"
         :services (group name service (:services stack))
         :networks (group name network (:networks stack))
         :volumes  (group name volume (:volumes stack))
         :configs  (group name config (:configs stack))
         :secrets  (group name secret (:secrets stack))}
        (clean))))