Best practice(s) for initial setup needed within a docker-compose container?

I am setting up a service where most containers are pretty straightforward (e.g. nice Docker images that take either ENV variables or straightforward config files provided as volumes…) but one requires some arcane and host-specific setup before the container is really ready to launch.

Specifically, I need Samba working in “Domain Controller” (fake Active Directory) mode within the docker-compose service. I’ve worked out a proof-of-concept for this: a Dockerfile PLUS a series of several additional setup steps/scripts that are host-specific. (Basically the “normal server” process is one installs Samba, and then runs a helper wizard script thing that generates a config file but also installs more random dependencies and seeds some local binary files…)

It’s unclear to me what the best practice is here:

  1. I’m assuming I could manually set up that container outside of my docker-compose.yml file and reference from the rest of the composed ones anyway
  2. I’m scripting the overall process via Ansible, so I suppose that after the docker-compose up–equivalent step I could add some steps to that Ansible recipe that finish the “manual” setup of the troublesome Samba container
  3. Or I could just add on to my Dockerfile [or a second Dockerfile referencing the first] the steps that make it ready to server one particular Active Directory domain from one particular host, and reference that from my docker-compose. This might be the easiest but feels the most “wrong” to me for some reason since it sort of changes the Dockerfile in sort of a pets vs. cattle way
  4. Or I suppose I could track down everything the Samba “setup wizard” does and sort it out myself — e.g. the Python dependencies would go straight in the Dockerfile, the text-based configuration file would go in my docker-compose repo and get --volume-d in, same with the binary database files that it pre-seeds as volumes, etc.
  5. Finally I suppose I could engineer a whole special entrypoint script that detects if setup is needed or not, and if not leverages ENV variables and whatnot. I think this is what many Official images must do for e.g. MariaDB user/database setup or whatnot but this one feels like the most work to get right especially for an image I wasn’t planning on pushing to any registry or desire to maintain/support for the general public [I am *not* a Samba expert and would rather not play one on GitHub…!]

Are “host-specific” Dockerfiles encouraged? I.e. ones that preconfigure for a very particular purpose/configuration?

Or is it better to split out the dynamic files (basically the state that the Samba configuration wizard thing creates) into a folder in the repo with my docker-compose file itself, and mount that as a volume? I’m not excited about recreating the Samba wizard myself, and it feels weird to have binary blobs in a git repo but as I write this up that seems like a reasonable compromise.

But the real question is: am I missing another obvious-in-hindsight option that keeps this all even simpler? What do Docker experts do in this situation: where a vendor has its own script that needs to run once when the container is first created but then [at least as long as the container isn’t re-created?] is good to go as far as the overall service goes?

Are you still loooking for an answer?

Normally we don’t want our Dockerfile to depend on the host and I can’t imagine many scenarios where it is required. But of course if you have that kind of scenario, then it doesn’t matter because you want a solution and not a Dockerfile which blindly follow the rules. But the one thing I don’t understand, what is host specific part of the Dockerfile here? Do you mean you have to configure the Active Directory on the host? That would be just a requirement for the Docker container to use.

My problem is that your issue for me is too theoretical. Maybe because I don’t know samba well enough but I try to summarize some thoughts:

  1. Include everything you can in a Docker image.
  2. Avoid using Docker images that required to be rebuilt on each host.
  3. Don’t be afraid of rebuilding the Docker image on each host if you have no other choice. Docker is just a tool and not the goal.
  4. Always use a Dockerfile
  5. You are allowed to generate the Dockerfile dynamically
  6. Even if you generate the Dockerfile, always use a version controlled script to do that. This is how I create my PHP images for different versions. In addition to that I also version controll the generated files.
  7. You can have prerequisites but make sure you define them clear enough in a readme or a documentation. If you have scripts to meet those requirements that’s even better.
  8. Always have a default base configuration which can have some required paramaters but don’t rely on anything that is not under your control. Any wizard on the host can suddenly work differently and the user can’t even try the container
  9. If you don’t know how the final configuration should look like, then yes, you use those wizards to create a default configuration with some placeholders and copy it into the Dockerfile. When the container starts you can replace the placeholders based on environment variables (or secrets) from your entrypoint or default command.

I hope I could give you some useful tips or at least your topic will appear again on the home page for others to see it.

Thanks, I think this will be a good approach! I haven’t tested it but I think the setup I can do will work from a Dockerfile itself. And I can of course use things like ARG to make the Dockerfile itself re-usable, just the resulting image will be custom single-use for one particular server.

In my case the container will serve as the Active Directory controller and not just a simpler AD or SMB client. The way the Samba team have done it (you can see the instructions at Setting up Samba as an Active Directory Domain Controller - SambaWiki) is maybe fine for a pet server, but not ideal for automation. Basically I can use the system package manager to install Samba, but then to setup the controller you run another script which both installs more stuff and initializes some host and domain specific stuff. So at the point it’s a ready-to-use “image”, it’s also hardcoded to the specific domain name and an admin account/password, etc.

It’s maybe a little bit like the database images available on Docker Hub, in that they can fill themselves in with a particular new user/database, but the difference is that I am just a casual Samba user and don’t want to dive into all the intricacies of their installation wizard to integrate it with a “best examples” Docker image that sets itself up via ENV variables on first run.