diff --git a/doc/apk.8.scd b/doc/apk.8.scd
index fd279fd15def163b954899d64f3ac8fb49b3bf90..d9aa6bd6890824241e79ec795b6ddb61df7d1325 100644
--- a/doc/apk.8.scd
+++ b/doc/apk.8.scd
@@ -146,9 +146,13 @@ The following options are available for all commands.
 	Maximum AGE (in minutes) for index in cache before it's refreshed. *0*
 	means always refresh.
 
+*--cache-packages*
+	Store a copy of packages at installation time to cache. Enabled automatically
+	if */etc/apk/cache* symlink exists.
+
 *--cache-predownload*
 	Download needed packages to cache before starting to commit a transtaction.
-	Requires cache to be configured to be functional.
+	Requires cache to be configured to be functional. Implies *--cache-packages*.
 
 *--force-binary-stdout*
 	Continue even if binary data will be printed to the terminal.
diff --git a/src/apk.c b/src/apk.c
index daec0b2241e5be2da04310c3e7b63cb7401f5c2a..cf60926c84a60f0e4cc34817e6f5570062cc4a3b 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -40,7 +40,8 @@ static void version(struct apk_out *out, const char *prefix)
 	OPT(OPT_GLOBAL_arch,			APK_OPT_ARG "arch") \
 	OPT(OPT_GLOBAL_cache_dir,		APK_OPT_ARG "cache-dir") \
 	OPT(OPT_GLOBAL_cache_max_age,		APK_OPT_ARG "cache-max-age") \
-	OPT(OPT_GLOBAL_cache_predownload,	"cache-predownload") \
+	OPT(OPT_GLOBAL_cache_packages,		APK_OPT_BOOL "cache-packages") \
+	OPT(OPT_GLOBAL_cache_predownload,	APK_OPT_BOOL "cache-predownload") \
 	OPT(OPT_GLOBAL_force,			APK_OPT_SH("f") "force") \
 	OPT(OPT_GLOBAL_force_binary_stdout,	"force-binary-stdout") \
 	OPT(OPT_GLOBAL_force_broken_world,	"force-broken-world") \
@@ -181,8 +182,11 @@ static int optgroup_global_parse(struct apk_ctx *ac, int opt, const char *optarg
 	case OPT_GLOBAL_cache_max_age:
 		ac->cache_max_age = atoi(optarg) * 60;
 		break;
+	case OPT_GLOBAL_cache_packages:
+		ac->cache_packages = APK_OPT_BOOL_VAL(optarg);
+		break;
 	case OPT_GLOBAL_cache_predownload:
-		ac->cache_predownload = 1;
+		ac->cache_predownload = APK_OPT_BOOL_VAL(optarg);
 		break;
 	case OPT_GLOBAL_timeout:
 		apk_io_url_set_timeout(atoi(optarg));
diff --git a/src/apk_context.h b/src/apk_context.h
index f8561f57d5ce94492029cecb1cc156df37b3b758..5847bc0cf2a21ad4c6863ecbf8911f97f86f9fbc 100644
--- a/src/apk_context.h
+++ b/src/apk_context.h
@@ -87,6 +87,7 @@ struct apk_ctx {
 	int root_fd, dest_fd;
 	unsigned int root_set : 1;
 	unsigned int cache_dir_set : 1;
+	unsigned int cache_packages : 1;
 	unsigned int cache_predownload : 1;
 	unsigned int keys_loaded : 1;
 };
diff --git a/src/context.c b/src/context.c
index 82daaf7b1740e567cbf7506f86fbd6f9f932028d..087630c9e3178eb75765b5c0d5a252c5230244ef 100644
--- a/src/context.c
+++ b/src/context.c
@@ -56,6 +56,7 @@ int apk_ctx_prepare(struct apk_ctx *ac)
 	if (!ac->cache_dir) ac->cache_dir = "etc/apk/cache";
 	else ac->cache_dir_set = 1;
 	if (!ac->root) ac->root = "/";
+	if (ac->cache_predownload) ac->cache_packages = 1;
 
 	if (!strcmp(ac->root, "/")) {
 		// No chroot needed if using system root
diff --git a/src/database.c b/src/database.c
index 24cb0674800da46c039f978e6dab0a1d949decc4..c063d03753f823a8ef28c6f12a3f80aaa38d8c8f 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1834,7 +1834,10 @@ static int setup_cache(struct apk_database *db)
 {
 	db->cache_dir = db->ctx->cache_dir;
 	db->cache_fd = openat(db->root_fd, db->cache_dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
-	if (db->cache_fd >= 0) return remount_cache_rw(db);
+	if (db->cache_fd >= 0) {
+		db->ctx->cache_packages = 1;
+		return remount_cache_rw(db);
+	}
 	if (db->ctx->cache_dir_set || errno != ENOENT) return -errno;
 
 	// The default cache does not exists, fallback to static cache directory
@@ -2384,7 +2387,7 @@ int apk_db_run_script(struct apk_database *db, int fd, char **argv)
 
 int apk_db_cache_active(struct apk_database *db)
 {
-	return db->cache_fd > 0 && db->cache_dir != apk_static_cache_dir;
+	return db->cache_fd > 0 && db->ctx->cache_packages;
 }
 
 struct foreach_cache_item_ctx {