baseDir and baseURL Parameters Explained

This website contains links to software which is either no longer maintained or will be supported only until the end of 2019 (CKFinder 2). For the latest documentation about current CKSource projects, including software like CKEditor 4/CKEditor 5, CKFinder 3, Cloud Services, Letters, Accessibility Checker, please visit the new documentation website.

If you look for an information about very old versions of CKEditor, FCKeditor and CKFinder check also the CKEditor forum, which was closed in 2015. If not, please head to StackOverflow for support.

Both baseDir and baseURL should point to the same location on the server — the userfiles directory that contains all user files uploaded with CKFinder. The difference between them is as follows:

  • baseURL gives a full URL to the userfiles directory or a path that is relative to the domain. For example:
    <baseURL>http://example.com/CKFinderJava/userfiles/</baseURL>
    <baseURL>/CKFinderJava/userfiles/</baseURL>
  • baseDir gives an absolute path to the directory on the server (a physical machine). For example:
    <baseDir>/usr/tomcat/webapps/CKFinderJava/userfiles/</baseDir>
    <baseDir>C:\tomcat\webapps\CKFinderJava\userfiles\</baseDir>

You may ask: why use two paths to point to one location?

The baseURL parameter represents the path that is used by HTTP clients. It is employed for example when CKFinder returns the URL addresses of the files.

CKFinder itself is not an HTTP client, but an application that operates on server-based files that needs absolute paths to these files to operate correctly. A specific server configuration may sometimes lead to problems with setting the absolute path based on the baseURL parameter, which leads to the malfunctioning of the application. This is where the baseDir parameter that contains the direct path to the userfiles directory may help.

Misconfiguration of baseURL and baseDir

Since setting the parameters may sometimes seem counter-intuitive, especially for the beginners, here are a couple of examples of CKFinder misconfiguration, i.e. the situation where the baseURL and baseDir settings were wrong.

Example 1: Using a Relative Path for baseDir

<!-- This configuration is wrong. -->
<baseDir>/userfiles/</baseDir>
<baseURL>/CKFinderJava/userfiles/</baseURL>

In this example the baseDir parameter contains the relative (and not absolute) path to the userfiles directory. In a Windows system with this configuration the userfiles directory will be created on the same partition that hosts the server (for example, C:\userfiles). On a Linux machine the system will try to create a /userfiles/ directory which will probably fail due to missing server permissions to create new directories in /.

Example 2: Incoherent Directory Paths

<!-- This configuration is wrong. -->
<baseDir>C:\userfiles</baseDir>
<baseURL>/CKFinderJava/userfiles/</baseURL>

In this example baseDir is set to an absolute path, but the parameter points to a different location than baseURL that is set relative to the application root.

Result: CKFinder Misconfiguration

In both examples the parameters point to different server directories. As a result, some CKFinder features may not work correctly. The View function, for example, will be one of them.

Why is that so?

As mentioned above, CKFinder works on files and for this it uses the baseDir parameter value. All uploaded files will thus be placed in the location that is set in this parameter. HTTP clients, on the other hand, will use the baseURL value, but in both examples presented above this parameter will point to a non-existent location which in some cases may lead to a lack of access to files.

BaseDir and BaseUrl best practice

important note
It is always recommended to set both baseUrl and baseDir so that they point to same location which is outside of application directory.


In previous section, we have seen what problems we may get when these two properties are misconfigured but what will happen when only baseUrl is set? CKFinder needs both, baseUrl and baseDir to work correctly and if baseDir is missing, CKFinder will try to determine its value based on baseUrl. You must know however that CKFinder has limited capabilities in this case. To be more precise, CKFinder is mainly limited to application context (application main directory). Let’s have a look at few examples:

<baseURL>/userfiles/</baseURL>
<baseDir></baseDir>
<!--or-->
<baseURL>http://example.com/userfiles/</baseURL>
<baseDir></baseDir>

In both above cases the userfiles folder points to server’s main applications directory. When multiple applications are kept on server they are accessible like http://example.com/CKFinderJava-2.5 or http://example.com/CKFinderJava-2.4. As you can probably see the userfiles folder should be created on same level as applications in order to be accessible through HTTP. The problem is that applications folder is not accessible from the web. There are however two servers which have general accessible folders and to which CKFinder can get. These servers are Apache Tomcat and Oracle GlassFish. Having configuration like presented above, starting from CKFinder 2.5.1, CKFinder will create userfiles folder in TOMCAT_HOME/webapps/ROOT directory for Apache Tomcat and GLASSFISH_HOME/glassfish/domains/domain_name/docroot directory for Oracle GlassFish. Everything will work as expected in this case. For other supported servers, CKFinder will use fallback approach and create userfiles folder inside CKFinderJavaapplication directory. As you probably know, this will unfortunately result in View option not working properly.

Let’s take a look at another example:

<baseURL>/CKFinderJava/userfiles/</baseURL>
<baseDir></baseDir>

Above setting will create userfiles inside CKFinderJava application directory. Although such configuration will work on every server there is a caveat to that approach. It isn’t recommended to put folder for uploaded files into deployed application folder because with every redeployment (e.g. when upgrading war to new version) of the application, the upload folder will be removed. So, what should be done to set baseUrl and baseDir correctly?

important note
First of all you should set both properties so that they point to same location which is accessible through HTTP and from the file system. Second, you should set these properties to point to location outside of CKFinder application folder.

One solution is using symlinks. The userfiles folder located inside application context can be a symbolic link to some other directory on the disk. With that simple approach /CKFinderJava/userfiles/ can point to folder of your choice. One downside of this technique is that you have to recreate the symbolic link with every application redeploy as the symlink gets removed on redeployment.

Another and better one solution is using server features. Most of the servers provide "virtual directory" mechanism. A "Virtual Directory" allows accessing folder which can be located even outside of the server, through HTTP. In Tomcat 7-8 this can be done through aliases, in Tomcat 6 by adding another context to server.xml, in GlassFish through alternate docroots, in Jetty by adding another context to jetty.xml and In Weblogic through virtual directories.

Let’s have a look at an example for Apache Tomcat 8. The server is installed in C:/Apache-Tomcat-8/ directory, CKFinderJava is installed in C:/Apache-Tomcat-8/CKFinderJava, we want to have our userfiles folder located directly on C drive and we want that folder to be called "myimages". Here are the settings that will allow having all CKFinder features working, and userfiles folder not being removed with every redeployment of the application:

CKFinder config.xml settings:

<baseDir>C:/myimages</baseDir>
<baseURL>/CKFinderJava/userfiles/</baseURL>

CKFinderJava/META-INF/context.xaml settings:

<Context antiJARLocking="true" path="/CKFinderJava" reloadable="true" >
    <Resources>
       <PreResources base="C://myimages" className="org.apache.catalina.webresources.DirResourceSet" webAppMount="/userfiles" />
   </Resources>
   <Valve className="org.apache.catalina.valves.RemoteAddrValve"  allow=".*" />
</Context>