michabbb
michabbb

Reputation: 931

Modifying a docker image that was created from an existing one

By following a how-to, I've created a new image based on an existing one.
I don´t have the original images' Dockerfile and there are things happening when the container starts that I can't change - that´s how it seems anyway.

Is there a way to modify the commands in the Dockerfile of the base image?

For example the container runs a bash script when it starts, I want to change this.

Upvotes: 29

Views: 70195

Answers (4)

stevec
stevec

Reputation: 52268

You can shell into a running container, modify it, and save the modified container as a new image with:

docker commit c7e6409a22bf my-new-image

Here's an example:

# Run an existing image
docker run -dt existing_image 

# See that it's running
docker ps
# CONTAINER ID   IMAGE            COMMAND   CREATED              STATUS              
# c7e6409a22bf   existing-image   "R"       6 minutes ago        Up 6 minutes

# Shell into it
docker exec -it c7e6409a22bf bash

# Make a new directory for demonstration purposes
# (note that this is inside the existing image)
mkdir NEWDIRECTORY

# Open another terminal tab/window, and save the running container you modified
docker commit c7e6409a22bf my-new-image

# Inspect to ensure it saved correctly
docker image ls
# REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
# existing-image       latest    a7dde5d84fe5   7 minutes ago   888MB
# my-new-image         latest    d57fd15d5a95   2 minutes ago   888MB

Upvotes: 2

sxc731
sxc731

Reputation: 2638

To answer your specific q: "the container runs a bash script when it starts, i want to change this". Let's assume you want to run /script.sh (part of the image) instead of the default, you can instantiate a container using:

docker run --entrypoint /script.sh repo/image

If script.sh isn't part of the image and/or you prefer not having to specify it explicitly each time with --entrypoint as above, you can prepare an image that contains and runs your own script.sh:

  1. Create an empty directory and copy or create script.sh in it
  2. Create Dockerfile with following content:

    FROM repo/image
    ADD script.sh /
    ENTRYPOINT /script.sh
    
  3. docker build -t="myimage" .

  4. docker run myimage

Notes:

  • When running the container (step 4), it's no longer necessary to specify --entrypoint since we have it defaulted in the Dockerfile.
  • It's really that simple; no need to sign up to docker hub or any such thing (although it's of course recommended in time ;-)

Upvotes: 33

Harald Albers
Harald Albers

Reputation: 1992

If launching the container with the command from the tutorial fails, your base image most likely introduced an ENTRYPOINT. Any commands you specify for docker run will be appended as options to the ENTRYPOINT command. Thus, given an ENTRYPOINT of e.g. /usr/bin/somescript,

docker run -d --name newguest -p 8080:80 mymod/httpd:v1 /usr/sbin/httpd -D FOREGROUND

will cause the container to execute

/usr/bin/somescript /usr/sbin/httpd -D FOREGROUND

instead of

/usr/sbin/httpd -D FOREGROUND

To get rid of the ENTRYPOINT, use the --entrypoint option:

docker run --entrypoint "" -d --name newguest -p 8080:80 mymod/httpd:v1 /usr/sbin/httpd -D FOREGROUND

Upvotes: 3

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657248

Just create a new Dockerfile in an empty Directory. Start the Dockerfile with

FROM repo/image 

where 'repo/image' is the id of the image your are currently using.

and add your customizations below.

This way you build a new image that is based on another image.

In particular, to change the command that runs at startup, put in a CMD and/or ENTRYPOINT line.

Upvotes: 4

Related Questions