This file contains details about the configuration files.
Configuration is stored in the file config.yaml, exception made for custom HTML which is stored in custom.html.
These files are kept in the same folder of hfs.exe if you are using this kind of distribution on Windows,
or $HOME/.hfs on other systems, where $HOME varies with the system and is the user's home folder.
Anyway, the current working directory (CWD) is printed by HFS in the first lines of the console.
Many things are stored in the CWD, like the plugins you install.
You can decide a different CWD passing --cwd SOME_FOLDER parameter at command line.
If you are not sure what your cwd is, look in the console, and you'll see that in first lines of your console.
Here is an example, look at the 6th line:
HFS ~ HTTP File Server
© Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
started 2026-01-03 10:10:00
version 3.0.0
build 2025-12-20T13:20:50.027Z
working directory (cwd) /Users/rejetto/.hfs
node v20.19.6
platform darwin arm64 binary
Configuration can be done in several ways
- accessing the Admin-panel with your browser
- it will automatically open when you start HFS. Bookmark it. If your port is 8000 the address will be http://localhost:8000/~/admin
- directly editing the
config.yamlfile. As soon as you save, it is reloaded and changes are applied- if you don't want to use an editor, consider typing this (example) command inside the folder where the config file is:
echo "port: 1080" >> config.yaml
- if you don't want to use an editor, consider typing this (example) command inside the folder where the config file is:
- passing via command line at start in the form
--NAME VALUE. Values can use JSON syntax. - using envs in the form
HFS_<uppercase property name>, likeHFS_PORT=80if you want to change the configport, but the same applies to any other config available. Values can use JSON syntax. - after HFS has started you can enter console command in the form
config NAME VALUE - setting special env
HFS_ENV_BOOTSTRAP=truewill disable other envs when file config.yaml already exists. - env
DISABLE_UPDATE(designed for containers) will disable updating, but check-for-update will still be possible.
NAME stands for the property name that you want to change. See the complete list below.
portwhere to accept http connections. Default is 80.vfsthe files and folders you want to expose. For details see the dedicated following section.logpath of the log file. Default isaccess.log.log_rotationfrequency of log rotation. Accepted values aredaily,weekly,monthly, or empty string to disable. Default isweekly.log_apishould api calls be logged? Default istrue.log_guishould GUI files be logged? Default isfalse.log_spamlog failed requests that are considered spam. Default is false.log_uainclude user-agent in the logs. Default is false.track_ipskeep track of all IP addresses seen. Default is true.error_logpath of the log file for errors. Default iserror.log.dont_log_netdon't include in log entries if IP matches this network mask. Default is127.0.0.1|::1.accountslist of accounts. For details see the dedicated following section.mimecommand what mime-type to be returned with some files. E.g.:"*.jpg": image/jpegYou can specify multiple entries, or separate multiple file masks with a p|pe. You can use the special valueautoto attempt automatic detection.max_kbpsthrottle output speed. Default is Infinity.max_kbps_per_ipthrottle output speed on a per-ip basis. Default is Infinity.zip_calculate_size_for_secondshow long should we wait before the zip archive starts streaming, trying to understand its finale size. Default is 1.open_browser_at_startshould HFS open browser on localhost on start? Default is true.https_portlisten on a specific port. Default is -1 (disabled).certuse this file for https certificate. Minimum to start https is to give a cert and a private_key. Default is none.private_keyuse this file for https private key. Default is none.allowed_refereryou can decide what domains can link to your files. Wildcards supported. Default is any.blocka list of rules that will block connections. E.g.:Syntax supports wildcards and more.block: - ip: 192.168.0.90plugins_configthis is a generic place where you can find/put configuration for each plugin, at least those that need configuration.enable_pluginsif a plugin is not present in this list, it won't run. Defaults is[ antibrute ].localhost_adminshould Admin be accessed without credentials when on localhost. Default is true.proxiesnumber of proxies between server and clients to be trusted about providing clients' IP addresses. Default is 0.delete_unfinished_uploads_aftershould unfinished uploads be deleted after a number of seconds. 0 for immediate, empty for never. Default is 1 day.faviconpath to file to be used as favicon. Default is none.force_httpsredirect http traffic to https. Requires https to be working. Default is true.force_langforce translation for frontend. Default is none, meaning let browser decide.admin_netnet-mask specifying what addresses are allowed to access Admin-panel. Default is any.titletext displayed in the tab of your browser. Default is "File server".file_menu_on_linkif to display file-menu when clicking on link, or have a dedicated button instead. Default is true.min_available_mbrefuse to accept uploads if available disk space is below this threshold. Default is 100.dont_overwrite_uploadinguploading a file with name already present in the folder will have a number appended in the name if this is enabled. Default is true. Affects the frontend only, but you can get the same effect using the?existing=renamein the url.keep_session_alivekeeps you logged in while the page is left open and the computer is on. Default is true.session_durationafter how many seconds should the login session expire. Default is a day.force_webdav_loginforce WebDAV clients to authenticate. Accepts:false(disabled),true(all user-agents), or a case-insensitive regex string (only matching user-agents). Default is true.webdav_initial_authone-time login prompt for matching WebDAV user-agents (used only whenforce_webdav_logindoes not match). Accepts:false(disabled),true(all user-agents), or a case-insensitive regex string. Default isWebDAVFS.acme_domaindomain used for ACME certificate generation. Default is none.acme_renewautomatically renew acme certificate close to expiration. Default is false.listen_interfacenetwork interface to listen on, by specifying IP address. Default is any.base_urlURL to be used for links generation. Default is automatic.force_addressdisconnect any request not made with one of the hosts specified inrootsorbase_url. Default is false.ignore_proxiesstop warning about detected proxies. Default is false.comments_storagechoose where to read/write comments. Default is in filedescript.ion.- You can set
attrto use only file's attributes, orattr+ionto store in file's attributes but fall-back todescript.ionas read-only.`
- You can set
descript_ion_encodingtext encoding to be used for filedescript.ion. List of supported values. Default isutf8.server_codejavascript code that works similarly to a plugin.tiles_sizestarting value for frontend's tiles size. Default is 0.auto_play_secondsstarting value for frontend's auto_play_seconds (used in Show). Default is 5.themestarting value for theme. Default is "auto".sort_bystarting value for sort-by. Values can be: name, extension, size, time. Default is "name".sort_numericsstarting value for sort-numeric-names. Default is false.folders_firststarting value for sort-folders-first. Default is true.invert_orderstarting value for invert-order. Default is false.update_to_betaincludes beta versions searching for updates. Default is false.rootsmaps hosts (or mask of hosts) to a root different from the home folder. Default is none. E.g.roots: music.domain.com: /music image.domain.com: /imagemax_downloadslimit the number of concurrent downloads on the whole server. Default is unlimited.max_downloads_per_iplimit the number of concurrent downloads for the same IP address. Default is unlimited.max_downloads_per_accountlimit the number of concurrent downloads for each account. This is enforced only for connections that are logged in, and will override other similar settings. Default is unlimited.geo_enablewhen enabled, country is determined for each request/connection. Necessary database will be downloaded every month (2MB).geo_allowset true ifgeo_listshould be treated as white-list, set false for black-list. Default will ignore the list.geo_listlist of country codes to be used as white-list or black-list. Default is none.geo_allow_unknownset false to disconnect connections for which country cannot be determined. Works only ifgeo_allowis set. Default is true.dynamic_dns_urlURL to be requested to keep a domain updated with your latest IP address. Optionally, you can append “>” followed by a regular expression to determine a successful answer, otherwise status code will be used. Multiple URLs are supported, and you can specify one for each line.outbound_proxyif you need outgoing http(s) requests to pass through an HTTP proxy. E.g.:http://user:password@localhost:8888. Default is none. Setting one will trigger a test request to google.com. You can skip this with env HFS_SKIP_PROXY_TEST=1 .auto_basicautomatically detect (based on user-agent) when the basic web interface should be served, to support legacy browsers. Default is true. No UI. You can disable it setting it tofalse, or recognize additional user-agents by setting a regular expression.file_timeoutnumber of seconds to wait before giving up when accessing a file. Default is 3. No UI.smart_unc_folder_detectionWindows-only optimization for UNC paths in VFS. When enabled, if the name of the element has no dot, it is assumed to be a folder without doing a stat call. This is faster with unreachable SMB shares, but heuristic and not fully reliable. Disable to always use regular detection. Default is true. No UI.authorization_headerenable support for the HTTPAuthorizationheader. Default is true. No UI.cache_control_disk_filesnumber of seconds after which the browser should bypass the cache and check the server for an updated version of the file. Default is 5. No UI.disable_custom_htmldisable the content ofcustom_html. Default is false.split_uploadsThe size in megabytes of the chunks the upload will be split into. Default is none.create-adminspecial entry to quickly create an admin account. The value will be set as the password. As soon as the account is created, this entry is removed.
The virtual file system is a tree of files and folders, collectively called nodes.
By default, a node is a folder, unless you provide for it a source that's a file.
The vfs config is a single root node. You can either bind a disk path directly to the root, like so
vfs:
source: /data
or expose paths as children of the root:
vfs:
children:
- source: /data
In the first example, the root of HFS shows the contents of /data.
In the second example, HFS shows a folder named "data" at the root (name inferred from the path).
Valid keys in a node are:
name: this is the name we'll use to display this file/folder. If not provided, HFS will infer it from the source. At leastnameorsourcemust be provided.source: absolute or relative path of where to get the contentchildren: just for folders, specify its virtual children. Value is a list and its entries are nodes.rename: whensourceis a folder, you can rename entries virtually as they are read from disk. Value is a map "original name" → "new name". No UI.mime: specify what mime to use for this resource. Use "auto" for automatic detection.url: when this value is present, the element is a link to the URL you specify.order: a number that you can set if you want to force the position of this element to the top or the bottom of the list. A positive number for the top, negative for the bottom. If you set "1" for an entry and "2" for another, the "2" will be the topmost.target: optional, for links only, used to open the link in a new browser. E.g._blankaccept: valid only on upload folders; not enforced, just hinting the browser. E.g..zip,.rardefault: use this with a folder where you want to serve a file, instead of the standard page with the list of files. The value must be the name of the file to serve. E.g.:index.html. The value must be an absolute or relative path in the VFS, not a path on disk. It works also with other type of files. Using this will makemimedefault to "auto".can_read: specify who can download this entry. Value is aWhoCandescriptor, which is one of these valuestrue: anyone can, even people who didn't log in. This is normally the default value.false: no one can."*": any account can, i.e. anyone who logged in.[ frank, peter ]: the list of accounts who can.can_SOMETHING: copy the permission from another permission. This is convenient to have same value for different permissions. E.g.can_see{ this?: WhoCan, children?: WhoCan }: this form is useful only for folders. By using it, you can have different permission for the folder itself and its children. For example, having only thethisproperty will make the permission limited to the folder and not be inherited by children. Otherwise, having only thechildrenwill make the permission have no effect on the folder, but only on its content.thisspecifies permission for this folderchildrenspecifies permission for the content.
can_see: specify who can see this element. Even if a user can download you can still make the file not appear in the list. Value is aWhoCandescriptor, refer above. Default iscan_read.can_upload: specify who can upload. Applies to folders with a source. Default is none.can_list: specify who can see the content of a folder. Default iscan_read.can_archive: specify who can get the zip a folder or a set of files. Default iscan_read.can_delete: specify who can delete. Applies to folders with a source. Default is none.masks: maps a file mask to a set of properties as the one documented in this section. E.g.Rules on top have priority over bottom rules. Inner rules have priority over parent's rules. A mask can carry any node property (even property "masks" itself). If the mask ends withmyfile.txt: can_see: false can_read: false "**/*.mp3": can_read: false "*.jpg|*.png": mime: auto|files|, then it will match only files and not folders. You can get the opposite effect with suffix|folders|.
Permissions set on an inner element will override inherited permissions. This means that you can restrict access to folder1, and yet decide to give free access to folder1/subfolder2.
All accounts go under accounts: property, as a dictionary where the key is the username.
E.g.
accounts:
admin:
password: hello123
admin: true
frank:
password: another
belongs: group1
guest:
password: guest
group1:
As soon as the config is read HFS will encrypt passwords (if necessary) in a non-reversible way. It means that password property is replaced with an encrypted property: srp.
As you can see in the example, group1 has no password. This implies that you cannot log in as group1, but still group1 exists and its purpose is to
gather multiple accounts and refer to them collectively as group1, so you can quickly share powers among several accounts.
For each account entries, this is the list of properties you can have:
ignore_limitsto ignore speed limits. Default isfalse.redirectprovide a URL if you want the user to be redirected upon login. Default is none.adminsettrueif you want to let this account log in to the Admin-panel. Default isfalse.belongsan array of usernames of other accounts from which to inherit their permissions. Default is none.passworda temporary unencrypted password, transformed intosrpASAP (and removed).srpencrypted password. Don't modify this, HFS will create it frompasswordfield.disabledprevents using this account. Default is false. If a user is disabled, it cannot log in. A user won't inherit permissions from a group if the group is disabled. If all of its groups are disabled, then it cannot log in, even if the user itself is not disabled.expireaccount won't work once the time has passed this timestamp. Use JSON timestamp syntax. Default is none.days_to_liveused to setexpireon first login. Default is none.disable_password_changesettrueif you want to forbid password change for this user. Default isfalse.require_password_changesettrueif you want to require password change for this user. Default isfalse.allow_neta mask of addresses to restrict the access of the account
Do you need to load a different config file that's not config.yaml?
Use this parameter at command line --config PATH or similarly with an env HFS_CONFIG.
The path you specify can be either a folder or full-path to the file.