diff --git a/build.rs b/build.rs
index 1a77b27bce95ee41e22a5de83fa1d43b5f7175ae..e8b4c9a7d4c1de09fcbe9656d28012a8fcc4fa81 100644
--- a/build.rs
+++ b/build.rs
@@ -6,6 +6,10 @@ fn main() {
 
 fn run(args: &[&str]) -> Result<String, std::io::Error> {
     let out = Command::new(args[0]).args(&args[1..]).output()?;
+    if !out.status.success() {
+        use std::io::{Error, ErrorKind};
+        return Err(Error::new(ErrorKind::Other, "Command not successful"));
+    }
     Ok(String::from_utf8(out.stdout).unwrap().trim().to_string())
 }
 
@@ -13,8 +17,10 @@ fn run(args: &[&str]) -> Result<String, std::io::Error> {
 fn read_git_info() -> Result<(), std::io::Error> {
     // The exact tag for the current commit, can be empty when
     // the current commit doesn't have an associated tag
-    let exact_tag = run(&["git", "describe", "--abbrev=0", "--tags", "--exact-match"])?;
-    println!("cargo:rustc-env=GIT_EXACT_TAG={}", exact_tag);
+    let exact_tag = run(&["git", "describe", "--abbrev=0", "--tags", "--exact-match"]).ok();
+    if let Some(ref exact) = exact_tag {
+        println!("cargo:rustc-env=GIT_EXACT_TAG={}", exact);
+    }
 
     // The last available tag, equal to exact_tag when
     // the current commit is tagged
@@ -27,13 +33,25 @@ fn read_git_info() -> Result<(), std::io::Error> {
 
     // The current git commit hash
     let rev = run(&["git", "rev-parse", "HEAD"])?;
-    let rev_short = rev.get(..12).unwrap_or_default();
+    let rev_short = rev.get(..8).unwrap_or_default();
     println!("cargo:rustc-env=GIT_REV={}", rev_short);
 
+    // Combined version
+    let version = if let Some(exact) = exact_tag {
+        exact
+    } else if &branch != "master" {
+        format!("{}-{} ({})", last_tag, rev_short, branch)
+    } else {
+        format!("{}-{}", last_tag, rev_short)
+    };
+    println!("cargo:rustc-env=GIT_VERSION={}", version);
+
     // To access these values, use:
     //    env!("GIT_EXACT_TAG")
     //    env!("GIT_LAST_TAG")
     //    env!("GIT_BRANCH")
     //    env!("GIT_REV")
+    //    env!("GIT_VERSION")
+
     Ok(())
 }
diff --git a/src/api/admin.rs b/src/api/admin.rs
index ae1f3dfa4e23990ac00fc6c73ccc6309cb11333a..1e7acdda2353db13409457f3a72475bc270ff05c 100644
--- a/src/api/admin.rs
+++ b/src/api/admin.rs
@@ -40,12 +40,13 @@ const COOKIE_NAME: &str = "BWRS_ADMIN";
 const ADMIN_PATH: &str = "/admin";
 
 const BASE_TEMPLATE: &str = "admin/base";
+const VERSION: Option<&str> = option_env!("GIT_VERSION");
 
 #[get("/", rank = 2)]
 fn admin_login(flash: Option<FlashMessage>) -> ApiResult<Html<String>> {
     // If there is an error, show it
     let msg = flash.map(|msg| format!("{}: {}", msg.name(), msg.msg()));
-    let json = json!({"page_content": "admin/login", "error": msg});
+    let json = json!({"page_content": "admin/login", "version": VERSION, "error": msg});
 
     // Return the page
     let text = CONFIG.render_template(BASE_TEMPLATE, &json)?;
@@ -94,16 +95,18 @@ fn _validate_token(token: &str) -> bool {
 
 #[derive(Serialize)]
 struct AdminTemplateData {
-    users: Vec<Value>,
     page_content: String,
+    version: Option<&'static str>,
+    users: Vec<Value>,
     config: Value,
 }
 
 impl AdminTemplateData {
     fn new(users: Vec<Value>) -> Self {
         Self {
-            users,
             page_content: String::from("admin/page"),
+            version: VERSION,
+            users,
             config: CONFIG.prepare_json(),
         }
     }
diff --git a/src/static/templates/admin/base.hbs b/src/static/templates/admin/base.hbs
index a718ed34b1f1bb344a3b6e2ba96672e5433079ec..9d0e9162503a4721edc285c1ad56457cdeb6f968 100644
--- a/src/static/templates/admin/base.hbs
+++ b/src/static/templates/admin/base.hbs
@@ -8,14 +8,14 @@
 
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css"
         integrity="sha256-azvvU9xKluwHFJ0Cpgtf0CYzK7zgtOznnzxV4924X1w=" crossorigin="anonymous" />
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
-        crossorigin="anonymous"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.js" integrity="sha256-tCQ/BldMlN2vWe5gAiNoNb5svoOgVUhlUgv7UjONKKQ="
-        crossorigin="anonymous"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/identicon.js/2.3.3/identicon.min.js" integrity="sha256-nYoL3nK/HA1e1pJvLwNPnpKuKG9q89VFX862r5aohmA="
-        crossorigin="anonymous"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/js/bootstrap.bundle.min.js" integrity="sha256-MSYVjWgrr6UL/9eQfQvOyt6/gsxb6dpwI1zqM5DbLCs="
-        crossorigin="anonymous"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
+        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.js"
+        integrity="sha256-tCQ/BldMlN2vWe5gAiNoNb5svoOgVUhlUgv7UjONKKQ=" crossorigin="anonymous"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/identicon.js/2.3.3/identicon.min.js"
+        integrity="sha256-nYoL3nK/HA1e1pJvLwNPnpKuKG9q89VFX862r5aohmA=" crossorigin="anonymous"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/js/bootstrap.bundle.min.js"
+        integrity="sha256-MSYVjWgrr6UL/9eQfQvOyt6/gsxb6dpwI1zqM5DbLCs=" crossorigin="anonymous"></script>
     <style>
         body {
             padding-top: 70px;
@@ -41,6 +41,9 @@
                 </li>
             </ul>
         </div>
+        {{#if version}}
+        <div class="navbar-text">Version: {{version}}</div>
+        {{/if}}
     </nav>
 
     {{> (page_content) }}