Installation without root user


I followed this manual step by step but using a non-root user (I did this on purpose for security reason) and installed baserow at this path: /home/user/opt/baserow .

Everything is going well, but stuck at here:
$ baserow sync_templates

It returns:
PermissionError: [Errno 13] Permission denied: '/baserow'

It looks like the reason is that I’m using a non-root user and putting baserow in a path other than /baserow, but I’m wondering if there’s another way to fix it?


Hi @joeyli, welcome to the Baserow community! We shouldn’t be using a static path pointing to the /baserow directory. Do you get the same error when you execute another management command like baserow showmigrations for example? Did you change you APPLICATION_TEMPLATES_DIR settings by any chance, or did you move the configuration file to another directory?

1. No, it looks like no problem when execute baserow showmigrations, actually, so far I’ve skipped baserow sync_templates and the installation went well, the services works fine, except for the empty template page, of course.

2. No, I didn’t modify APPLICATION_TEMPLATES_DIR settings.

3. No, I didn’t move the configuration file to another directory.

(env) joeyli@virtual:~/opt/baserow$ baserow showmigrations
 (no migrations)
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
 [X] 0001_row_comments
 [X] 0002_licenses
 [X] 0003_kanban_view
 [X] 0001_initial
 [X] 0002_remove_content_type_name
 [X] 0001_initial
 [X] 0002_userfile
 [X] 0003_auto_20201215_2047
 [X] 0004_auto_20210126_1950
 [X] 0005_settings
 [X] 0006_template_templatecategory
 [X] 0007_userlogentry
 [X] 0008_trash
 [X] 0009_user_profile
 [X] 0010_fix_trash_constraint
 [X] 0011_settings_instance_id
 [X] 0012_add_trashed_indexes
 [X] 0001_initial
 [X] 0002_booleanfield_field_numberfield_textfield
 [X] 0003_field_primary
 [X] 0004_auto_20200117_1157
 [X] 0005_auto_20200505_1242
 [X] 0006_auto_20200522_1329
 [X] 0007_datefield
 [X] 0008_auto_20200701_1608
 [X] 0009_linkrowfield
 [X] 0010_auto_20200828_1306
 [X] 0011_link_row_column_name_fix
 [X] 0012_auto_20200904_1410
 [X] 0013_urlfield
 [X] 0014_viewsort
 [X] 0015_emailfield
 [X] 0016_token_tokenpermission
 [X] 0017_view_filters_disabled
 [X] 0018_auto_20201110_1251
 [X] 0019_filefield
 [X] 0020_fix_primary_link_row
 [X] 0021_auto_20201215_2047
 [X] 0022_row_order
 [X] 0023_convert_int_to_bigint
 [X] 0024_selectoption_singleselectfield
 [X] 0025_gridviewfieldoptions_hidden
 [X] 0026_auto_20210125_1454
 [X] 0027_gridviewfieldoptions_order
 [X] 0028_fix_negative_date
 [X] 0029_phonenumberfield
 [X] 0030_auto_20210526_1939
 [X] 0031_fix_url_field_max_length
 [X] 0032_trash
 [X] 0033_unique_field_names
 [X] 0034_form_view
 [X] 0035_remove_field_old_name
 [X] 0036_createdonfield_lastmodifiedfield
 [X] 0037_alter_exportjob_export_options
 [X] 0038_multipleselectfield
 [X] 0039_formulafield
 [X] 0040_formulafield_remove_field_by_id
 [X] 0041_add_generated_table_indexes
 [X] 0042_add_other_trashed_indexes
 [X] 0043_webhooks
 [X] 0044_field_dependencies
 [X] 0045_alter_field_name
 [X] 0046_add_lookup_field
 [X] 0047_fix_date_diff
 [X] 0048_fix_trashed_field_dependencies
 [X] 0001_initial

Attach the complete ERROR prompt:

(env) joeyli@virtual:~/opt/baserow/baserow$ baserow sync_templates
Traceback (most recent call last):
  File "/home/joeyli/opt/baserow/env/bin/baserow", line 7, in <module>
    exec(compile(, __file__, 'exec'))
  File "/home/joeyli/opt/baserow/baserow/backend/baserow", line 6, in <module>
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/", line 14, in main
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/management/", line 419, in execute_from_command_line
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/management/", line 413, in execute
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/management/", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/management/", line 398, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python3.9/", line 79, in inner
    return func(*args, **kwds)
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/management/commands/", line 16, in handle
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/", line 924, in sync_templates
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/", line 820, in import_applications_to_group
    imported_application = application_type.import_serialized(
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/contrib/database/", line 188, in import_serialized
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/contrib/database/fields/", line 1536, in set_import_serialized_value
    user_file = user_file_handler.upload_user_file(
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/user_files/", line 223, in upload_user_file
    self.generate_and_save_image_thumbnails(image, user_file, storage=storage)
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/user_files/", line 140, in generate_and_save_image_thumbnails, thumbnail_stream)
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/files/", line 54, in save
    return self._save(name, content)
  File "/home/joeyli/opt/baserow/baserow/backend/src/baserow/core/", line 8, in _save
    return super()._save(name, content)
  File "/home/joeyli/opt/baserow/env/lib/python3.9/site-packages/django/core/files/", line 255, in _save
    os.makedirs(directory, exist_ok=True)
  File "/usr/lib/python3.9/", line 215, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/usr/lib/python3.9/", line 215, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/usr/lib/python3.9/", line 215, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/usr/lib/python3.9/", line 225, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/baserow'

That there might be a problem in the sync_templates management command after all. It’s not a problem if you don’t run it, you just won’t be able to install the templates.

Judging by the full output you provided, what happens if you try to upload a file? By default, Baserow tries to save uploaded files in the /baserow/media directory. Installing a template also copies over files to that folder. You can override this path by overriding the MEDIA_ROOT Django setting or by settings MEDIA_ROOT environment variable.

It looks work fine, uploaded some photos to the table, the files were uploaded to /home/joeyli/opt/baserow/media. (I have modified MEDIA_ROOT environment variable before.)

Hey @joeyli ,

I believe that you are setting this error was when you run baserow sync_templates the MEDIA_ROOT variable which controls where it is trying to save files to is defaulting to /baserow/media/. When you say you have modified MEDIA_ROOT before do you mean you’ve run in the same shell promt export MEDIA_ROOT=/home/joeyli/opt/baserow/media before then running baserow sync_templates ?

Could you check if running MEDIA_ROOT=/home/joeyli/opt/baserow/media baserow sync_templates works for you?


No, just modified MEDIA_ROOT in /etc/supervisor/conf.d/baserow.conf. Is there any other configuration file to be modified?

MEDIA_ROOT=/home/joeyli/opt/baserow/media baserow sync_templates works for me! Now I can see the content on the template page.

Thanks you!

Here’s a deeper explanation on the config files and if you need to edit another one:

  1. Baserow when it starts up looks for the environment variable MEDIA_ROOT and uses it to decide where it should store media files in the filesystem
  2. By changing /etc/supervisor/conf.d/baserow.conf you change what this environment variable is when Baserow the server is started up by supervisord
  3. However when you just run a ./baserow cmd on the command line, it the baserow program also checks the environment for the MEDIA_ROOT variable
  4. The environment of your command line program is separate and wont use the config defined in /etc/supervisor/conf.d/baserow.conf which is just config for the particular program that launches and runs Baserow
  5. So to properly run ./baserow cmd's from the command line you need to separately set the environment variables in your command line first by either doing the above command MEDIA_ROOT=/home/joeyli/opt/baserow/media baserow sync_templates which sets MEDIA_ROOT in the environment just for that particular command
  6. Or you could run export MEDIA_ROOT=/home/joeyli/opt/baserow/media in your command line which will then keep it set for the remainder of your session.
  7. There are a number of other things you could do here to not have to remember to keep on setting env variables when using the command line like creating a bash script which sets them up and then calls baserow cmd etc. You could also directly edit baserow/src/backend/baserow/config/settings/ if you are comfortable making changes to the settings python file, however future upgrades of Baserow might require you to resolve merge conflicts.
1 Like

Thank you very much for your detailed explanation!