There's two basic good approaches to this, depending on how much customization you need to do.
If you're just replacing config files and injecting alternate images, you can use Docker bind mounts to do this. A typical Docker Compose file to do this might look like (I'm making up paths a little bit):
version: '3'
services:
kibana:
image: 'kibana:6.6.2'
volumes:
- ./kibana.yml:/etc/kibana/kibana.yml
- ./kibana.png:/usr/share/kibana/assets/kibana.png
You can then check this docker-compose.yml
, the config file, and anything else you're injecting this way into source control. These files replace the corresponding files from the image in the specified paths. (And if the container process happens to write to these files, the host files will change too.)
If you need to make somewhat more involved changes, building a custom image makes sense. (The official Docker tutorial on building and running custom images is helpful, if more application-oriented.) You can start an image FROM
any other image. The equivalent Dockerfile
to the above might look like
FROM kibana:6.6.2
COPY kibana.yml /etc/kibana
COPY kibana.png /usr/share/kibana/assets
# Keep base image's ENTRYPOINT/CMD
and the matching docker-compose.yml
file could just be
version: '3'
services:
kibana:
build: .
Both of these approaches put you in a position where you can check everything that went into the image/container into source control, and on the off chance that your system dies (or a new colleague is trying the project, or /var/lib/docker
gets corrupted, or Amazon shuts off your EC2 instances, or ...) you can just check the artifacts out of source control and run them again. If you need a newer version of Kibana, you can just change the image tag and re-run things as well.