diff --git a/CHANGELOG b/CHANGELOG
index 8f0bbb12d7b82256e395bf9314962efe7b509ce7..18fc76e444bfa2db4046bb1ce8afef3bf4dd0d0f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -47,6 +47,7 @@ v 8.1.0 (unreleased)
   - Persist filters when sorting on admin user page (Jerry Lukins)
   - Add spellcheck=false to certain input fields
   - Invalidate stored service password if the endpoint URL is changed
+  - Only render 404 page from /public
 
 v 8.0.4
   - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 527c9da0faa50bd1863432be7b4ef35be9e7c8f0..2b2ea3dff16ecec10ece99c5eeab195dc75eb822 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -30,7 +30,7 @@ class ApplicationController < ActionController::Base
 
   rescue_from ActiveRecord::RecordNotFound do |exception|
     log_exception(exception)
-    render "errors/not_found", layout: "errors", status: 404
+    render_404
   end
 
   protected
@@ -149,10 +149,6 @@ class ApplicationController < ActionController::Base
     render "errors/access_denied", layout: "errors", status: 404
   end
 
-  def not_found!
-    render "errors/not_found", layout: "errors", status: 404
-  end
-
   def git_not_found!
     render "errors/git_not_found", layout: "errors", status: 404
   end
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index f84f85a7df842a522d7131b88cd269054cf78518..25e587248606ccde522f0b0f86fe2c4d35875107 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -62,7 +62,7 @@ class Import::BitbucketController < Import::BaseController
   end
 
   def verify_bitbucket_import_enabled
-    not_found! unless bitbucket_import_enabled?
+    render_404 unless bitbucket_import_enabled?
   end
 
   def bitbucket_auth
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index 849646cd6652403006d9a601a2909d03e70b474f..18300390851edcc3d2177ecd253951466b6e159b 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -99,6 +99,6 @@ class Import::FogbugzController < Import::BaseController
   end
 
   def verify_fogbugz_import_enabled
-    not_found! unless fogbugz_import_enabled?
+    render_404 unless fogbugz_import_enabled?
   end
 end
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index f21fbd9eccac0f02b41fbf40530d5c7364b68ff8..aae77d384c6ae745e5851cc49fb8de2bceea3e55 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -47,7 +47,7 @@ class Import::GithubController < Import::BaseController
   end
 
   def verify_github_import_enabled
-    not_found! unless github_import_enabled?
+    render_404 unless github_import_enabled?
   end
 
   def github_auth
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
index 27af19f5f616f89f19580fd03f95f6bd49faa573..23a396e8084f3dd2b32646f35b1d13f22a2bf0b3 100644
--- a/app/controllers/import/gitlab_controller.rb
+++ b/app/controllers/import/gitlab_controller.rb
@@ -44,7 +44,7 @@ class Import::GitlabController < Import::BaseController
   end
 
   def verify_gitlab_import_enabled
-    not_found! unless gitlab_import_enabled?
+    render_404 unless gitlab_import_enabled?
   end
 
   def gitlab_auth
diff --git a/app/controllers/import/gitorious_controller.rb b/app/controllers/import/gitorious_controller.rb
index f24cdb3709a0246eac25ef0c3807d6ebf9b170a2..eecbe380c9e7f7da752020f67833519bfb7c7f71 100644
--- a/app/controllers/import/gitorious_controller.rb
+++ b/app/controllers/import/gitorious_controller.rb
@@ -42,7 +42,7 @@ class Import::GitoriousController < Import::BaseController
   end
 
   def verify_gitorious_import_enabled
-    not_found! unless gitorious_import_enabled?
+    render_404 unless gitorious_import_enabled?
   end
 
 end
diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb
index 82fadeb7e832deba7f88860e3db3dd9a0e9cb9b4..41472a6fe6c16ba8dabb83751fc00ff05e521ac9 100644
--- a/app/controllers/import/google_code_controller.rb
+++ b/app/controllers/import/google_code_controller.rb
@@ -106,7 +106,7 @@ class Import::GoogleCodeController < Import::BaseController
   end
 
   def verify_google_code_import_enabled
-    not_found! unless google_code_import_enabled?
+    render_404 unless google_code_import_enabled?
   end
 
   def user_map
diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb
index 9c3763d5934e0245cc7e8133b2e136fdd7510fa1..548f1b9ebfec092ac360e8a7860a20b311cae950 100644
--- a/app/controllers/projects/avatars_controller.rb
+++ b/app/controllers/projects/avatars_controller.rb
@@ -12,7 +12,7 @@ class Projects::AvatarsController < Projects::ApplicationController
         filename: @blob.name
       )
     else
-      not_found!
+      render_404
     end
   end
 
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index ae9b138446362b62ed1a2332ece4301cd32ae769..8cc2f21d8871ca974a4e8dce3e73b6d6cd67b920 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -113,14 +113,14 @@ class Projects::BlobController < Projects::ApplicationController
         end
       end
 
-      return not_found!
+      return render_404
     end
   end
 
   def commit
     @commit = @repository.commit(@ref)
 
-    return not_found! unless @commit
+    return render_404 unless @commit
   end
 
   def assign_blob_vars
@@ -128,7 +128,7 @@ class Projects::BlobController < Projects::ApplicationController
     @ref, @path = extract_ref(@id)
 
   rescue InvalidPathError
-    not_found!
+    render_404
   end
 
   def after_edit_path
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index 5f6fbce795e950d3792d80be348e1ff724779813..d5ee6ac8663b24aadaa88818becf516764454741 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -20,7 +20,7 @@ class Projects::RawController < Projects::ApplicationController
         disposition: 'inline'
       )
     else
-      not_found!
+      render_404
     end
   end
 
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 7eaff1d61ee74c92c47abc837bedf9b1ff1e6fcf..bdcb1a3e297ee178eb58f15157f06f61db037d81 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -10,7 +10,7 @@ class Projects::TreeController < Projects::ApplicationController
   before_action :authorize_push_code!, only: [:create_dir]
 
   def show
-    return not_found! unless @repository.commit(@ref)
+    return render_404 unless @repository.commit(@ref)
 
     if tree.entries.empty?
       if @repository.blob_at(@commit.id, @path)
@@ -19,7 +19,7 @@ class Projects::TreeController < Projects::ApplicationController
                                       File.join(@ref, @path))
         ) and return
       elsif @path.present?
-        return not_found!
+        return render_404
       end
     end
 
@@ -31,7 +31,7 @@ class Projects::TreeController < Projects::ApplicationController
   end
 
   def create_dir
-    return not_found! unless @commit_params.values.all?
+    return render_404 unless @commit_params.values.all?
 
     begin
       result = Files::CreateDirService.new(@project, current_user, @commit_params).execute
diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb
index 71ecc20dd95ea7fe681e5b9ed5ef378974eeb8e6..e1fe7ea21143fcc6d3131cff79026d9f6f2ebafb 100644
--- a/app/controllers/projects/uploads_controller.rb
+++ b/app/controllers/projects/uploads_controller.rb
@@ -20,7 +20,7 @@ class Projects::UploadsController < Projects::ApplicationController
   end
 
   def show
-    return not_found! if uploader.nil? || !uploader.file.exists?
+    return render_404 if uploader.nil? || !uploader.file.exists?
 
     disposition = uploader.image? ? 'inline' : 'attachment'
     send_file uploader.file.path, disposition: disposition
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 28536e359e51c538e3bbfc8fe2bedef816eb7a73..868b05929d7404461438e8d321bb3115f3ee7400 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -10,7 +10,7 @@ class UploadsController < ApplicationController
     end
 
     unless uploader.file && uploader.file.exists?
-      return not_found!
+      return render_404
     end
 
     disposition = uploader.image? ? 'inline' : 'attachment'
@@ -21,7 +21,7 @@ class UploadsController < ApplicationController
 
   def find_model
     unless upload_model && upload_mount
-      return not_found!
+      return render_404
     end
 
     @model = upload_model.find(params[:id])
@@ -44,7 +44,7 @@ class UploadsController < ApplicationController
     return if authorized
 
     if current_user
-      not_found!
+      render_404
     else
       authenticate_user!
     end
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 322aed5e27c33e61b071ae87f6407677619673f5..51e46da82ccd24dd61ff938167bc728518d0820f 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -110,7 +110,7 @@ module ExtractsPath
                                                       @project, @ref, @path)
 
   rescue RuntimeError, NoMethodError, InvalidPathError
-    not_found!
+    render_404
   end
 
   def tree