diff --git a/changelogs/unreleased/gh-8605-add-gethostname.md b/changelogs/unreleased/gh-8605-add-gethostname.md
new file mode 100644
index 0000000000000000000000000000000000000000..af92672f37be781db9528e3c99cb66ac51a8a728
--- /dev/null
+++ b/changelogs/unreleased/gh-8605-add-gethostname.md
@@ -0,0 +1,3 @@
+## feature/box
+
+* Added a new `box.info` parameter `hostname` (gh-8605).
diff --git a/src/box/lua/info.c b/src/box/lua/info.c
index 8664965c91b07014242fb7d7db3f42ea48ec3b95..05bf09389fff919082098053e4dd4e29f2347112 100644
--- a/src/box/lua/info.c
+++ b/src/box/lua/info.c
@@ -31,6 +31,7 @@
 #include "lua/info.h"
 
 #include <ctype.h> /* tolower() */
+#include <unistd.h>
 
 #include <lua.h>
 #include <lauxlib.h>
@@ -69,6 +70,18 @@
 static bool box_info_cluster_new_meaning = true;
 TWEAK_BOOL(box_info_cluster_new_meaning);
 
+/**
+ * Known upper limits for a hostname (without a zero-terminating
+ * byte):
+ *
+ * sysconf(_SC_HOST_NAME_MAX) == 64 on Linux.
+ * sysconf(_SC_HOST_NAME_MAX) == 255 on macOS.
+ * sysconf(_SC_HOST_NAME_MAX) == 255 on BSD.
+ *
+ * The constant value is used to simplify the code.
+ */
+enum { TT_HOST_NAME_MAX = 255 };
+
 static inline void
 lbox_push_replication_error_message(struct lua_State *L, struct error *e,
 				    int idx)
@@ -701,6 +714,22 @@ lbox_schema_version(struct lua_State *L)
 	return 1;
 }
 
+/** gethostname() Lua interface inside box.info. */
+static int
+lbox_info_hostname(struct lua_State *L)
+{
+	char buffer[TT_HOST_NAME_MAX + 1];
+	int rc = gethostname(buffer, sizeof(buffer));
+	if (rc != 0) {
+		say_warn_ratelimited("failed to get hostname: %s",
+				     tt_strerror(errno));
+		lua_pushnil(L);
+		return 1;
+	}
+	lua_pushstring(L, buffer);
+	return 1;
+}
+
 static const struct luaL_Reg lbox_info_dynamic_meta[] = {
 	{"id", lbox_info_id},
 	{"uuid", lbox_info_uuid},
@@ -725,6 +754,7 @@ static const struct luaL_Reg lbox_info_dynamic_meta[] = {
 	{"election", lbox_info_election},
 	{"synchro", lbox_info_synchro},
 	{"schema_version", lbox_schema_version},
+	{"hostname", lbox_info_hostname},
 	{NULL, NULL}
 };
 
diff --git a/test/box-luatest/gh_8605_add_box_info_hostname_test.lua b/test/box-luatest/gh_8605_add_box_info_hostname_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..5bad6a32f46afab912a077d5cd421eee02843c75
--- /dev/null
+++ b/test/box-luatest/gh_8605_add_box_info_hostname_test.lua
@@ -0,0 +1,21 @@
+local popen = require('popen')
+local t = require('luatest')
+
+local g = t.group()
+
+g.test_hostname_result = function()
+    local ph = popen.shell("hostname", 'r')
+
+    local exp_status = {
+        state = popen.state.EXITED,
+        exit_code = 0,
+    }
+    local status = ph:wait()
+    t.skip_if(status.exit_code == 127, "no hostname on host")
+    t.assert_equals(status, exp_status, 'verify process status')
+
+    local hostname = ph:read():rstrip()
+    t.assert_equals(hostname, box.info.hostname, 'verify hostname')
+
+    ph:close()
+end
diff --git a/test/box/info.result b/test/box/info.result
index 6db9b6d5afd90c54ded474b588c294fb4ee9cad8..19bb50a328a2a29daec995f54ddd1c4c3d249311 100644
--- a/test/box/info.result
+++ b/test/box/info.result
@@ -63,6 +63,10 @@ box.info.replicaset.uuid == box.space._schema:get{'replicaset_uuid'}[2]
 ---
 - true
 ...
+type(box.info.hostname) == 'string'
+---
+- true
+...
 t = {}
 ---
 ...
@@ -77,6 +81,7 @@ t
 - - cluster
   - election
   - gc
+  - hostname
   - id
   - listen
   - lsn
diff --git a/test/box/info.test.lua b/test/box/info.test.lua
index 19056301bd207d97e9741b2938fe0b700eebec12..51a9c509dfeace7459dbb3ca00e5c7d118b6009e 100644
--- a/test/box/info.test.lua
+++ b/test/box/info.test.lua
@@ -17,6 +17,7 @@ box.info.status
 string.len(box.info.uptime) > 0
 string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil
 box.info.replicaset.uuid == box.space._schema:get{'replicaset_uuid'}[2]
+type(box.info.hostname) == 'string'
 t = {}
 for k, _ in pairs(box.info()) do table.insert(t, k) end
 table.sort(t)