There's a bit of "it depends" here. The big question is, how much do you expect the person running the container to need to modify the configuration?
If the configuration is totally fixed then just build it into the container. A good example of this is an nginx configuration file for proxying a set of other containers in a Docker Compose setup: if you think the host names for the other containers you will use will never change, it's easier to build it into the image.
If the configuration has a limited number of things that can change, but the configuration language allows variable substitutions, then compile a config file referencing environment variables into the image, and use environment variables to adjust the configuration. The prototypical example of this in my mind is a Rails database.yml.erb file where you can substitute
host: <%= ENV['MYSQL_HOST'] %>
docker run --net some_network -e MYSQL_HOST=mysql myimage
If the configuration has a limited number of things that can change, you can also apply variable substitutions at startup time. sed can do this fine; if you otherwise have the GNU tools available (perhaps your image is Debian or Ubuntu-based) envsubst can do this straightforwardly. An entrypoint script can do this before you start the main program.
#!/bin/sh
# Fill in runtime values for configuration
sed -e "s/MYSQL_HOST/$MYSQL_HOST/" < database.conf.tpl > database.conf
# Run the CMD from the Dockerfile
exec "$@"
...
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["myapp"]
docker run --net some_network -e MYSQL_HOST=mysql myimage
If there are many complex configuration choices or you expect the user to just wholesale replace the configuration, bind-mount it in.
docker run -v $PWD/application.conf:/app/application.conf myimage
If you're actually deploying into Kubernetes you can put the configuration file in a ConfigMap object, which essentially behaves the same way as the bind-mount option. If you're also using a tool like Helm to manage the deployment then you can use its templating layer to set the ConfigMap content. The Helm templating language is fairly involved and has loops and conditionals, so you can build up a complex configuration file based on deploy-time settings.
You also mention databases. The standard SQL database containers support placing content in a /docker-entrypoint-initdb.d directory, and this will get run the very first time the database starts up. I'd minimize the use of this, and prefer creating tables via a database-migration system. Mostly this is because those scripts only get run when the database is created the very first time, and you'll need a migration system anyways; you don't want to need to delete all of your data every time you change your schema.