You generally keep data files like this outside a container. In the case of SQLite, it's a single file, so it's fairly easy to manage.
When you start the container, bind-mount a host directory into the container's data directory. Whatever's in this directory will hide what was initially in the image. If you automatically run database migrations at startup, this will also create the SQLite database file.
docker run -v $PWD/data:/anope/data ...
Now, the database is a file on the host, and you can manage that however you'd want to.
# Stop the original container (avoids integrity issues with the database file)
docker stop first-container; docker rm first-container
# Create two extra copies of the database file
mkdir data2 data3
cp data/anope.db data2
cp data/anope.db data3
# Launch two new containers, pointing at those data directories
docker run -v $PWD/data2:/anope/data --name second-container ...
docker run -v $PWD/data3:/anope/data --name third-container ...
You do not need any special support in your Dockerfile for this to work, beyond ensuring that the application code and data are not in the same directory.
Note that this setup doesn't care at all about what's in the container filesystem. We ruthlessly discarded the first container filesystem, and launched two more containers in parallel. The actual data that needs to be persisted is always kept outside the container. (I have not used docker commit
, docker exec
, docker cp
, or docker start
at all.)
If you did want to create an image with seed data, it would be very straightforward to write a Dockerfile that did that:
FROM the-same-image-you-were-running
COPY anope.db /anope/data
However, note that any sort of mount will hide the data in the image and replace it with what was mounted, with one special case around the first use of named volumes in Docker specifically. Also note that, if the directory is declared as a VOLUME
(possibly in the base image), then you cannot make further changes to that directory and have them persisted.