diff --git a/.travis.yml b/.travis.yml
index a659b0dd87e8b7179dd79f16835a0aaaafd6f60c..46ca432b3533f3ceb71f2456e3f990dedb60876c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -119,6 +119,8 @@ matrix:
       script: sh ci/run-docker.sh $TARGET
       install:
 
+cache: cargo
+
 notifications:
   email:
     on_success: never
diff --git a/ci/docker/arm-linux-androideabi/Dockerfile b/ci/docker/arm-linux-androideabi/Dockerfile
index 0e41ba6dbee66dc1301797cecb7c73a4bc4e1b56..1911fbd87970ea2e5ced4f2121373bf1e1cedea8 100644
--- a/ci/docker/arm-linux-androideabi/Dockerfile
+++ b/ci/docker/arm-linux-androideabi/Dockerfile
@@ -1,4 +1,34 @@
-FROM alexcrichton/rust-slave-android:2015-11-22
-ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
-    PATH=$PATH:/rust/bin
-ENTRYPOINT ["sh"]
+FROM ubuntu:16.04
+
+RUN dpkg --add-architecture i386 && \
+    apt-get update && \
+    apt-get install -y --no-install-recommends \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  unzip \
+  expect \
+  openjdk-9-jre \
+  libstdc++6:i386 \
+  gcc \
+  libc6-dev
+
+WORKDIR /android/
+
+COPY install-ndk.sh /android/
+RUN sh /android/install-ndk.sh
+
+ENV PATH=$PATH:/android/ndk-arm/bin:/android/sdk/tools:/android/sdk/platform-tools
+
+COPY install-sdk.sh accept-licenses.sh /android/
+RUN sh /android/install-sdk.sh
+
+ENV PATH=$PATH:/rust/bin \
+    CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
+    ANDROID_EMULATOR_FORCE_32BIT=1 \
+    HOME=/tmp
+RUN chmod 755 /android/sdk/tools/*
+
+RUN cp -r /root/.android /tmp
+RUN chmod 777 -R /tmp/.android
diff --git a/ci/docker/arm-linux-androideabi/accept-licenses.sh b/ci/docker/arm-linux-androideabi/accept-licenses.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8d8f60a5ec2604606571cdb6a7d231d5754aa38f
--- /dev/null
+++ b/ci/docker/arm-linux-androideabi/accept-licenses.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/expect -f
+# ignore-license
+
+set timeout 1800
+set cmd [lindex $argv 0]
+set licenses [lindex $argv 1]
+
+spawn {*}$cmd
+expect {
+  "Do you accept the license '*'*" {
+        exp_send "y\r"
+        exp_continue
+  }
+  eof
+}
diff --git a/ci/docker/arm-linux-androideabi/install-ndk.sh b/ci/docker/arm-linux-androideabi/install-ndk.sh
new file mode 100644
index 0000000000000000000000000000000000000000..566a3191848a3bc5736e07fe566ad6726bd1e5a7
--- /dev/null
+++ b/ci/docker/arm-linux-androideabi/install-ndk.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+curl -O https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
+unzip -q android-ndk-r13b-linux-x86_64.zip
+android-ndk-r13b/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk-arm \
+        --arch arm \
+        --api 24
+
+rm -rf ./android-ndk-r13b-linux-x86_64.zip ./android-ndk-r13b
diff --git a/ci/docker/arm-linux-androideabi/install-sdk.sh b/ci/docker/arm-linux-androideabi/install-sdk.sh
new file mode 100644
index 0000000000000000000000000000000000000000..3f20837fe061afb104c04f9a0619b9d679d03e14
--- /dev/null
+++ b/ci/docker/arm-linux-androideabi/install-sdk.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+# Prep the SDK and emulator
+#
+# Note that the update process requires that we accept a bunch of licenses, and
+# we can't just pipe `yes` into it for some reason, so we take the same strategy
+# located in https://github.com/appunite/docker by just wrapping it in a script
+# which apparently magically accepts the licenses.
+
+mkdir sdk
+curl https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz | \
+    tar xzf - -C sdk --strip-components=1
+
+filter="platform-tools,android-21"
+filter="$filter,sys-img-armeabi-v7a-android-21"
+
+./accept-licenses.sh "android - update sdk -a --no-ui --filter $filter"
+
+echo "no" | android create avd \
+                --name arm-21 \
+                --target android-21 \
+                --abi armeabi-v7a
diff --git a/ci/run-docker.sh b/ci/run-docker.sh
index e34e65ffcdc0cd5ce8cb77d356d96325a1977b9c..a7702ae1dc51282229327c2fe377df23cceba8a7 100644
--- a/ci/run-docker.sh
+++ b/ci/run-docker.sh
@@ -6,14 +6,21 @@ set -ex
 run() {
     echo $1
     docker build -t libc ci/docker/$1
+    mkdir -p target
     docker run \
+      --user `id -u`:`id -g` \
       --rm \
-      -v `rustc --print sysroot`:/rust:ro \
-      -v `pwd`:/checkout:ro \
-      -e CARGO_TARGET_DIR=/tmp/target \
-      -w /checkout \
+      --volume $HOME/.cargo:/cargo \
+      --env CARGO_HOME=/cargo \
+      --volume `rustc --print sysroot`:/rust:ro \
+      --volume `pwd`:/checkout:ro \
+      --volume `pwd`/target:/checkout/target \
+      --env CARGO_TARGET_DIR=/checkout/target \
+      --workdir /checkout \
       --privileged \
-      -it libc \
+      --interactive \
+      --tty \
+      libc \
       ci/run.sh $1
 }
 
diff --git a/libc-test/build.rs b/libc-test/build.rs
index a1bd3d98c4cb96e0167302228a9bfcea4cf60d2d..defcf5aa5f5ff4957439450c72e2f0121f9655f2 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -438,6 +438,10 @@ fn main() {
             "lio_listio" if freebsd => true,
             "lio_listio" if musl => true,
 
+            // Apparently the NDK doesn't have this defined on android, but
+            // it's in a header file?
+            "endpwent" if android => true,
+
             _ => false,
         }
     });