diff --git a/shakers.cabal b/shakers.cabal
--- a/shakers.cabal
+++ b/shakers.cabal
@@ -1,42 +1,37 @@
-name: shakers
-version: 0.0.38
-cabal-version: >=1.22
-build-type: Simple
-license: MIT
-license-file: LICENSE
-copyright: Copyright (C) 2016 Swift Navigation, Inc.
-maintainer: Mark Fine <dev@swiftnav.com>
-homepage: https://github.com/swift-nav/shakers
-synopsis: Shake helpers.
-description:
-    Primitive helpers for Shake files.
-category: Development
-author: Swift Navigation Inc.
-
-source-repository head
-    type: git
-    location: git@github.com:swift-nav/shakers.git
+name:                  shakers
+version:               0.0.40
+synopsis:              Shake helpers.
+description:           Primitive helpers for Shake files.
+homepage:              https://github.com/swift-nav/shakers
+license:               MIT
+license-file:          LICENSE
+author:                Swift Navigation Inc.
+maintainer:            Mark Fine <dev@swiftnav.com>
+copyright:             Copyright (C) 2016 Swift Navigation, Inc.
+category:              Development
+build-type:            Simple
+cabal-version:         >= 1.22
 
 library
-    exposed-modules:
-        Development.Shakers
-    build-depends:
-        base >=4.8 && <5,
-        basic-prelude >=0.5.2,
-        deepseq >=1.4.1.1,
-        directory >=1.2.2.0,
-        lifted-base >=0.2.3.11,
-        regex-compat >=0.95.1,
-        shake >=0.15.11
-    default-language: Haskell2010
-    hs-source-dirs: src
-    ghc-options: -Wall
+  hs-source-dirs:      src
+  exposed-modules:     Development.Shakers
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+  build-depends:       base >= 4.8 && < 5
+                     , basic-prelude
+                     , deepseq
+                     , directory
+                     , lifted-base
+                     , regex-compat
+                     , shake
 
 executable shake-shakers
-    main-is: Shakefile.hs
-    build-depends:
-        base >=4.8.2.0,
-        shakers
-    default-language: Haskell2010
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  main-is:             Shakefile.hs
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:       base
+                     , shakers
+  default-language:    Haskell2010
 
+source-repository head
+  type:                git
+  location:            git@github.com:swift-nav/shakers.git
diff --git a/src/Development/Shakers.hs b/src/Development/Shakers.hs
--- a/src/Development/Shakers.hs
+++ b/src/Development/Shakers.hs
@@ -33,16 +33,13 @@
   , rsync_
   , ssh
   , ssh_
-  , sshScreen
-  , sshScreen_
-  , rmirror_
+  , sshDir
+  , sshDir_
   , rssh
   , rssh_
-  , rsshScreen
-  , rsshScreen_
   , rdocker_
-  , rdockerScreen_
   , docker_
+  , xdocker_
   , convox_
   , fake
   , meta
@@ -148,6 +145,11 @@
 remoteVar :: Action String
 remoteVar = getVar "REMOTE"
 
+-- | Remote flag.
+--
+remoteFlag :: Action Bool
+remoteFlag = getFlag "REMOTE"
+
 -- | Remove right excess on string.
 --
 rstrip :: String -> String
@@ -253,66 +255,37 @@
 ssh_ :: String -> [String] -> Action ()
 ssh_ h as = cmdArgs_ "ssh" $ h : as
 
--- | SSH command with screen.
---
-sshScreen :: String -> [String] -> Action String
-sshScreen h as = do
-  t <- timestamp
-  ssh h $ "-t" : "screen" : "-S" : t : as
-
--- | SSH command with screen no return.
+-- | SSH command in a remote directory.
 --
-sshScreen_ :: String -> [String] -> Action ()
-sshScreen_ h as = do
-  t <- timestamp
-  ssh_ h $ "-t" : "screen" : "-S" : t : as
+sshDir :: FilePath -> String -> [String] -> Action String
+sshDir d h as = cmdArgs "ssh" $ h : "cd" : d : "&&" : as
 
--- | Mirror directory remotely.
+-- | SSH command in a remote directory with no return.
 --
-rmirror_ :: Action ()
-rmirror_ = do
-  r <- remoteVar
-  p <- parentDir
-  rsync_ [ "-Laz", "--delete", buildFile p <> "/", r <:> p <> "/" ]
+sshDir_ :: FilePath -> String -> [String] -> Action ()
+sshDir_ d h as = cmdArgs_ "ssh" $ h : "cd" : d : "&&" : as
 
 -- | Remote SSH command.
 --
 rssh :: [String] -> Action String
 rssh as = do
   r <- remoteVar
-  ssh r as
-
--- | Remote SSH screen command.
---
-rsshScreen :: [String] -> Action String
-rsshScreen as = do
-  r <- remoteVar
-  sshScreen r as
+  p <- parentDir
+  sshDir p r as
 
 -- | Remote SSH command with no return.
 --
 rssh_ :: [String] -> Action ()
 rssh_ as = do
   r <- remoteVar
-  ssh_ r as
-
--- | Remote SSH command with no return.
---
-rsshScreen_ :: [String] -> Action ()
-rsshScreen_ as = do
-  r <- remoteVar
-  sshScreen_ r as
+  p <- parentDir
+  sshDir_ p r as
 
 -- | Run docker command remotely.
 --
 rdocker_ :: [String] -> Action ()
 rdocker_ = rssh_ . ("docker" :)
 
--- | Run docker command remotely.
---
-rdockerScreen_ :: [String] -> Action ()
-rdockerScreen_ = rsshScreen_ . ("docker" :)
-
 -- | Run docker command in mirro dir.
 --
 docker_ :: [String] -> Action ()
@@ -320,6 +293,13 @@
   d <- mirrorDir
   cmdArgsDir_ d "docker" as
 
+-- | Run either local or remote docker based on remote env.
+--
+xdocker_ :: [String] -> Action ()
+xdocker_ as = do
+  ok <- remoteFlag
+  bool (docker_ as) (rdocker_ as) ok
+
 -- | Run convox command in mirro dir.
 --
 convox_ :: [String] -> Action ()
@@ -447,12 +427,12 @@
   -- | ghci
   --
   phony "ghci" $
-    stack_ dir [ "ghci", "--fast" ]
+    stack_ dir [ "ghci" ]
 
   -- | ghci-tests
   --
   phony "ghci-tests" $
-    stack_ dir [ "ghci", "--fast", "--test" ]
+    stack_ dir [ "ghci", "--test" ]
 
   -- | clean
   --
@@ -508,12 +488,12 @@
   -- | ghci
   --
   phony ("ghci:" <> target) $
-    stack_ dir [ "ghci", target, "--fast" ]
+    stack_ dir [ "ghci", target ]
 
   -- | ghci-tests
   --
   phony ("ghci-tests:" <> target) $
-    stack_ dir [ "ghci", target, "--fast", "--test" ]
+    stack_ dir [ "ghci", target, "--test" ]
 
 -- | Cabal and hackage rules.
 --
@@ -579,6 +559,20 @@
         createDirectoryIfMissing True $ dropFileName (dir' </> file)
         copyFile file (dir' </> file)
 
+  -- | mirror-remote
+  --
+  phony "mirror-remote" $ do
+    need [ "mirror" ]
+    r <- remoteVar
+    p <- parentDir
+    rsync_ [ "-Laz", "--delete", buildFile p <> "/", r <:> p <> "/" ]
+
+  -- | mirrored
+  --
+  phony "mirrored" $ do
+    ok <- remoteFlag
+    need [ bool "mirror" "mirror-remote" ok ]
+
   -- | docker:login
   --
   phony "docker:login" $ do
@@ -590,6 +584,12 @@
   phony "docker:login-remote" $ do
     login <- aws [ "ecr", "get-login", "--no-include-email", "--region", "us-west-2" ]
     rssh_ [ login ]
+
+  -- | docker:logined
+  --
+  phony "docker:logined" $ do
+    ok <- remoteFlag
+    need [ bool "docker:login" "docker:login-remote" ok ]
 
 -- | Main entry point.
 --
