diff --git a/picodata/cli.yml b/picodata/cli.yml
index 96e0913197e14222df4f418db6814d124f51ea28..ab8f69fd5d41d2a2a31098c02971f730997c1ca7 100644
--- a/picodata/cli.yml
+++ b/picodata/cli.yml
@@ -5,19 +5,23 @@ subcommands:
   - run:
       about: run the picodata instance
       args:
+        # Don't use `default_value` here,
+        # it breaks env vars precedence
+
         - data-dir:
             long: data-dir
-            help: Here instance persists all its data
+            help: >
+                Here instance persists all its data
+                (default: .)
             takes_value: true
-            default_value: "."
             value_name: path
 
         - listen:
             # short: l
             long: listen
-            help: Socket bind address
+            help: >
+                Socket bind address (default: 3301)
             takes_value: true
-            default_value: "0.0.0.0:3301"
             value_name: "[host:]port"
 
         - peer:
diff --git a/picodata/main.rs b/picodata/main.rs
index 497d4d852d30e1ef3797f1dbf4db17602268405e..86dd89984c6ef87b2d8c0e3484e953c8bb4a4af9 100644
--- a/picodata/main.rs
+++ b/picodata/main.rs
@@ -65,6 +65,10 @@ fn main_run(matches: &clap::ArgMatches) {
     }
 
     envp.insert("PICODATA_COMMAND".to_owned(), "run".to_owned());
+    envp.entry("PICODATA_LISTEN".to_owned())
+        .or_insert("3301".to_owned());
+    envp.entry("PICODATA_DATA_DIR".to_owned())
+        .or_insert(".".to_owned());
 
     let bypass_vars = [
         "cluster-id",
diff --git a/tests/cli.rs b/tests/cli.rs
index 536da9e3b740866ec132552f5666cb4a16c9079d..91e9862d6676f7f15e3f2031b6bb5a4eaee14e6f 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -11,7 +11,18 @@ fn positive() {
     let mut cmd = Command::cargo_bin("picodata").unwrap();
     cmd.current_dir(temp_path);
     cmd.arg("run");
-    cmd.args(["-e", "os.exit()"]);
+    cmd.arg("-e").arg(
+        r#"
+        function assert_eq(l, r)
+            if l ~= r then
+                error(('Assertion failed: %q ~= %q'):format(l, r), 2)
+            end
+        end
+        assert_eq(os.environ()['PICODATA_LISTEN'], "3301")
+        assert_eq(os.environ()['PICODATA_DATA_DIR'], ".")
+        os.exit()
+        "#,
+    );
     cmd.timeout(Duration::from_secs(1)).assert().success();
 }
 
@@ -104,3 +115,28 @@ fn pass_environment() {
         "tarantool didn't make a snapshot"
     );
 }
+
+#[test]
+fn precedence() {
+    let temp = tempdir().unwrap();
+    let temp_path = temp.path();
+
+    let mut cmd = Command::cargo_bin("picodata").unwrap();
+    cmd.current_dir(temp_path);
+    cmd.arg("run");
+    cmd.env("PICODATA_DATA_DIR", "./somewhere");
+    cmd.env("PICODATA_LISTEN", "0.0.0.0:0");
+    cmd.arg("-e").arg(
+        r#"
+        function assert_eq(l, r)
+            if l ~= r then
+                error(('Assertion failed: %q ~= %q'):format(l, r), 2)
+            end
+        end
+        assert_eq(os.environ()['PICODATA_DATA_DIR'], './somewhere')
+        assert_eq(os.environ()['PICODATA_LISTEN'], "0.0.0.0:0")
+        os.exit(0)
+    "#,
+    );
+    cmd.timeout(Duration::from_secs(1)).assert().success();
+}