How do I move App from Server 1 to Server 2? ModuleNotFoundError

I was wondering if in 2024 it is still only possible to move an app by using bench get-app and then bench install-app .

I was hoping I could just copy the directory /frappe-bench/apps/erpnext_xxxxx_app from one machine to the other and then use bench –site [site name] install-app [app name] but when I do that I get the following error:

frappe@c302c01b809d:~/frappe-bench/apps$ bench --site frontend install-app erpnext_xxxxx_app
Could not find app "erpnext_xxxxx_app":
No module named 'erpnext_xxxxx_app'
An error occurred while installing erpnext_xxxxx_app: No module named 'erpnext_xxxxx_app'
Traceback with variables (most recent call last):
  File "apps/frappe/frappe/commands/site.py", line 446, in install_app
    _install_app(app, verbose=context.verbose, force=force)
      context = {'sites': ['frontend'], 'force': False, 'verbose': False, 'profile': False}
      apps = ('erpnext_xxxxx_app',)
      force = False
      _install_app = <function install_app at 0x7fe50cf8ae80>
      filelock = <function filelock at 0x7fe50cf89080>
      exit_code = 0
      site = 'frontend'
      app = 'erpnext_xxxxx_app'
      err = ModuleNotFoundError("No module named 'erpnext_xxxxx_app'")
  File "apps/frappe/frappe/installer.py", line 264, in install_app
    app_hooks = frappe.get_hooks(app_name=name)
      name = 'erpnext_xxxxx_app'
      verbose = False
      set_as_patched = True
      force = False
      sync_jobs = <function sync_jobs at 0x7fe50bf41440>
      sync_for = <function sync_for at 0x7fe50bf422a0>
      sync_customizations = <function sync_customizations at 0x7fe50d0856c0>
      sync_fixtures = <function sync_fixtures at 0x7fe50bf425c0>
  File "apps/frappe/frappe/__init__.py", line 1589, in get_hooks
    hooks = _dict(_load_app_hooks(app_name))
      hook = None
      default = '_KEEP_DEFAULT_LIST'
      app_name = 'erpnext_xxxxx_app'
  File "apps/frappe/frappe/utils/caching.py", line 57, in wrapper
    return_val = func(*args, **kwargs)
      args = ('erpnext_xxxxx_app',)
      kwargs = {}
      args_key = ********
      func = <function _load_app_hooks at 0x7fe50d1c20c0>
  File "apps/frappe/frappe/__init__.py", line 1561, in _load_app_hooks
    app_hooks = get_module(f"{app}.hooks")
      app_name = 'erpnext_xxxxx_app'
      hooks = {}
      apps = ['erpnext_xxxxx_app']
      app = 'erpnext_xxxxx_app'
      types = <module 'types' from '/usr/local/lib/python3.11/types.py'>
  File "apps/frappe/frappe/__init__.py", line 1427, in get_module
    return importlib.import_module(modulename)
      modulename = 'erpnext_xxxxx_app.hooks'
  File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
      name = 'erpnext_xxxxx_app.hooks'
      package = None
      level = 0
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
      name = 'erpnext_xxxxx_app.hooks'
      package = None
      level = 0
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
      name = 'erpnext_xxxxx_app.hooks'
      import_ = <function _gcd_import at 0x7fe50ebc3d80>
      module = <exception while printing> Traceback (most recent call last):
          File "env/lib/python3.11/site-packages/traceback_with_variables/core.py", line 222, in _to_cropped_str
            raw = print_(obj)
                  ^^^^^^^^^^^
          File "apps/frappe/frappe/utils/__init__.py", line 327, in dict_printer
            if key in v:
               ^^^^^^^^
        TypeError: argument of type 'object' is not iterable

  File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
      name = 'erpnext_xxxxx_app.hooks'
      import_ = <function _gcd_import at 0x7fe50ebc3d80>
      path = None
      parent = 'erpnext_xxxxx_app'
      parent_spec = None
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
      f = <function _gcd_import at 0x7fe50ebc3d80>
      args = ('erpnext_xxxxx_app',)
      kwds = {}
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
      name = 'erpnext_xxxxx_app'
      package = None
      level = 0
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
      name = 'erpnext_xxxxx_app'
      import_ = <function _gcd_import at 0x7fe50ebc3d80>
      module = <exception while printing> Traceback (most recent call last):
          File "env/lib/python3.11/site-packages/traceback_with_variables/core.py", line 222, in _to_cropped_str
            raw = print_(obj)
                  ^^^^^^^^^^^
          File "apps/frappe/frappe/utils/__init__.py", line 327, in dict_printer
            if key in v:
               ^^^^^^^^
        TypeError: argument of type 'object' is not iterable

  File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
      name = 'erpnext_xxxxx_app'
      import_ = <function _gcd_import at 0x7fe50ebc3d80>
      path = None
      parent = ''
      parent_spec = None
      spec = None
builtins.ModuleNotFoundError: No module named 'erpnext_xxxxx_app'

Anybody know if my approach is somehow possible? Or must I use bench get-app?

Hi @julez,

I recommend utilizing the “bench get-app” command to retrieve the application, followed by installation, as it offers the most efficient solution to resolve the issue.

Assuming it’s feasible to transfer the application from one server to another, you may encounter numerous challenges such as path discrepancies and uncertainty regarding whether the application is configured correctly. Additionally, time consumption becomes a significant concern.

If your custom application is up to date and is on GitHub, obtaining and installing it becomes a straightforward process.