4 Tips for Designing Server-Side Software Configurations

When designing and developing server-side (back-end) software, configuration files are an inescapable topic.

A configuration file is a special file used to store various configurable items. Every software presets some default configurations, but these defaults may not work in all situations. Therefore, in different environments, we often need to extend and modify them with configuration files.

Take the version control software git as an example. Most users’ home directory (~) stores a .gitconfig configuration file with their username and email address:

 [user] name = piglei email = [email protected]

Like any main function of the software, the configuration file will greatly affect the experience of using the software. Good design can make software easier to use, but bad design can bring many unexpected problems and keep users away.

In this article, I have compiled 4 design suggestions for “software profiles” that I hope will help you.

1. It is best to use it without configuration

In the online world, with each passing day, people seem to be less patient than the day before. A well-made short video, if it can’t catch you within 3 seconds, your right thumb will reflexively swipe it away.

Now, suppose you develop a very useful tool software and publish it on the Internet. The software is so comprehensive that everyone needs to edit a configuration file containing 20 configurations before using it. Guess what percentage of potential users will simply turn around and walk away?

When we want something, we don’t want to wait for a moment. Therefore, whether the initial configuration process is troublesome or not can strongly influence people’s determination to try the software. In this regard, I think the best experience is that more than 80% of the functions of the software can be used directly without any configuration.

If this is not possible, we should also try to start from the following aspects, try to reduce the user’s configuration cost, and compress the waiting time between “starting installation” and “available”.

1.1 Preset reasonable default values

In order to compress the configuration items that must be provided by the user to a minimum. You have to preset a reasonable enough default value for all configuration items of the software. These defaults should satisfy as many users as possible.

For example, suppose your software depends on an available Redis service. Then please set the default value of this configuration to the default address by convention: redis_url: redis://localhost:6379/0 . In this way, when a Redis service happens to be running on the user’s machine, the trouble of adjusting this configuration item can be avoided.

1.2 Delay some configuration items

After the software is complicated to a certain extent, the configurable items are often staggering. Many configurations are often very critical in the eyes of developers and cannot be simplified by presetting default values. At this point, it seems like an impossible task for users to fill in less configuration.

Faced with this situation, we can try to split configuration items into two types: minimal configuration items and other configuration items . When users use the software, they only need to provide a file containing the minimum configuration items. The rest of the configuration can be delayed until the software is used, and the user is required to fill in through a friendly interactive interface.

For example, the software you provide includes a Web site. To use it, users only need to provide 1 configuration item: MySQL database address. After that, he can access the site through a browser and gradually complete the remaining configuration items required for other functions.

2. Never default “admin password”

When it comes to presetting default values ​​for configuration items, it is easy to overdo it – setting key security class configurations to fixed default values. For example, when your project is first started, a built-in administrator role with the highest privileges is created. To reduce configuration costs for users, the role’s password is hardcoded with a default value:

 # 重要:请在你的配置文件里修改该默认密码,否则将会带来严重# 的安全风险。 SUPER_USER_PASSWORD = "proje2p#admin@321"

Once the system sets a default password, more than 90% of users will never change it – no matter how dangerous the reminder text says. When the software spread, this fixed password would facilitate many hackers, with disastrous consequences.

With the exception of passwords, no key class configuration should provide fixed defaults. You should always ask users to configure them manually. Alternatively, a random value can be generated when the software is first started. The practice is as follows:

 # 成功安装软件后,弹出提示文字:恭喜,你已经成功安装了nice_software。因为你没有在配置里提供管理员密码,该值已经被设置为随机值:fuiwe2shdvwi23

Later in the process, you can ask the user to enter the random password again for verification and provide a new password. This can also effectively reduce security risks.

In addition to passwords and secret keys, the network card device bound by default when the Web service starts can easily create security holes. If a software binds all network card interfaces by default when it is started, then when a user installs the software on a machine with a public IP, the service may be exposed to the external network without preparation, and the risk is extremely high. For details, please refer to the example in the Redis configuration file .

3. Descriptive text formatting is preferred

In some projects using dynamic programming languages ​​(such as Python, Ruby, Lua, etc.), there is often a unique configuration file format: source code files .

For example, if you have a project developed with the Django framework, then you can fully support the user to provide a Python script as a configuration file when distributing the project.

 # 配置文件my_settings.py 内容CONTACT_USERNAME = 'contact_us' CREATE_DEFAULT_ADMIN = True ATTACHMENTS_DIR = '~/.attachments' # 启动项目$ start_project -s ./my_settings.py

At first glance, this approach looks very good. If you look around, you can even find quite a few open source projects doing this – like Emacs using LISP , GitLab using Ruby . In terms of flexibility , there is a world of difference between source code and common descriptive text files (YAML, JSON, etc.). The use of source code format means that users can toss out dizzyingly complex configurations by writing code.

The problem is that flexibility (or “programmability”) is not the most important evaluation metric for profiles. To evaluate the quality of a configuration file design, whether it is “easy to understand”, “easy to modify”, and whether each configuration item has a detailed description is the most important. When comparing source code and ordinary descriptive text files, you will find that the former is not dominant in these dimensions.

For example, it doesn’t matter which programming language you choose as the configuration file format. When users want to use your software, they have to understand some basic syntax and data structures. This is likely to turn some people who aren’t keen on it out.

Using source code for configuration, in some ways, also encourages users to cram complex logic into configuration files. Sometimes this is not a problem, but sometimes – especially when users need to manage many configuration files at the same time, the complex code logic hidden in the configuration can make maintenance especially difficult.

As mentioned above, under the premise of meeting the needs of the project, you should try to choose a simple descriptive text format as the configuration file – YAML, TOML, JSON are all fine. They’re not as flexible as code, but they’re easier to get started with.

In addition, even in the same text format, flexibility varies. When you need to choose one of several formats, just choose the simpler and less flexible one. That is, if both TOML and YAML are OK, use TOML.

Configuration file structure

After using the text format as the configuration file, the configuration of the general project will form a three-layer structure similar to the following figure:

using_toml.png

illustrate:

  1. The main configuration module on the far left: maintained by the project developer, responsible for providing the default configuration, and also contains most of the “smart” configuration generation and simplification logic
  2. The middle part is the personalized configuration file that the user needs to provide when using the software
  3. If the environment is extremely complex, users can also develop tools for specific scenarios to assist in managing and operating configuration files, reducing maintenance costs

4. Partial or full support for environment variables

The 12-factor App is a very popular application architecture advice. It recommends using environment variables as a source of application configuration, and believes that this is the best configuration management model – better than any file format.

Compared with configuration files, environment variables do have some inherent advantages: such as low threshold, easy modification, operating system independence, and so on. Using environment variables to configure services is especially convenient on cloud-native platforms like Kubernetes.

Because of this, in addition to supporting reading configuration items from files, your software should also allow users to modify configuration items through environment variables.

A sample configuration file sample.TOML :

 contact_username = 'piglei'

The same configuration items can also be set through environment variables:

 export CONTACT_USERNAME="piglei"

To achieve this, you can read the value of environment variables directly in the project:

 # config.py import os # 优先读取环境变量,而后是配置文件contact_username = os.environ.get('CONTACT_USERNAME', toml_config['contact_username'])

If you find it too cumbersome to manually read environment variables, each programming language generally has its own popular configuration management library, some of which support the management of configuration in files and environment variables at the same time. For example, Python’s dynaconf and Go’s viper module are very easy to use.

Summarize

Designing configuration files is an important part of developing server-side software. This article shares some experiences in designing server-side software configuration. I think the most important point is to realize that users always want to use the software immediately, rather than tossing the configuration for a long time.

Hopefully we can think more actively about how to optimize the configuration design and add more color to the software.

This article is reprinted from: https://www.zlovezl.cn/articles/how-to-design-config-file-for-software/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment