<p>You could try giving <a href="https://docs.docker.com/engine/reference/commandline/commit/#commit-a-container-with-new-configurations" rel="nofollow noreferrer"><code>docker commit --change</code></a> a try.</p>
<pre><code>docker run --env FOO=BAR &lt;image&gt;
docker commit --change &quot;ENV FOO=SETVALUE&quot; &lt;container_from_image&gt; &lt;new_image_tagged_from_state_of_container&gt;
</code></pre>
<p>Please note that docker's engine specifies that <a href="https://docs.docker.com/engine/reference/run/#environment-variables" rel="nofollow noreferrer"><em>&quot;[If the operator] names an environment variable without specifying a value, then the current value of the named variable is propagated into the container’s environment&quot;</em></a> so you'll need to set the environment variable to something such as <code>SETVALUE</code>
an environment variable without specifying a value, the current value of the named variable on the host is propagated into the container's environment</p>

CC BY-SA 4.0
2022-05-16T03:12:34.250Z
2024-02-06T19:39:17.990Z
2024-02-06T19:39:17.990Z
treedust
<h1>Buildah</h1>
<blockquote>
<p>This creates some awfully confusing situations, as I consider arguments to docker run to be as ephemeral as the container it creates. I am only concerned about persisting package installs.</p>
</blockquote>
<p>Sure does. Don't use docker. =) Docker is just one method of creating an image. It blurs the line between and online (hot container) and offline build process. Instead try <code>buildah</code>, which works with any shell. No dockerfile needed, also runs rootless. Try the below with <code>buildah unshare ./image.sh</code></p>
<pre class="lang-sh prettyprint-override"><code>#!/bin/bash
# Call this script image.sh
# Invoke as regular user with `buildah unshare ./image.sh`
ctr=$(buildah from alpine:3)
mnt=$(buildah mount &quot;$ctr&quot;)

echo &quot;Created offline container $ctr&quot;
echo &quot;Got mount $mnt&quot;

# write/copy/move directly into $mnt
echo &quot;Write directly into mount&quot; &gt; &quot;$mnt/foo.txt&quot;

temp=$(mktemp)
echo &quot;Created temp $temp&quot;
echo foo &gt; &quot;$temp&quot;
mv &quot;$temp&quot; &quot;$mnt/bar&quot;

echo &quot;No container running&quot;

buildah run &quot;$ctr&quot; /bin/sh &lt;&lt;-EOF
  echo &quot;Hello from inside container.&quot;;
  apk update;
  apk add podman;
  echo 42 &gt; baz;
EOF

buildah config                     \
  --author &quot;Joe Doe &lt;foo@bar.com&gt;&quot; \
  --label &quot;apples=oranges&quot;         \
  --env &quot;foo=bar&quot;                  \
  &quot;$ctr&quot;;

buildah commit &quot;$ctr&quot; mynewimage
</code></pre>
<p>You can see what that includes</p>
<pre><code>podman run -i mynewimage /bin/sh &lt;&lt;-&quot;EOF&quot;
  echo -e &quot;\nfoo:&quot;
  cat foo

  echo -e &quot;\nbar:&quot;
  cat bar

  echo -e &quot;\nbaz:&quot;
  cat baz

  echo -e &quot;\nenv&quot;
  env
EOF
</code></pre>

CC BY-SA 4.0
2022-05-16T08:33:27.960Z
2022-05-16T08:50:20.290Z
2022-05-16T08:50:20.290Z
Evan Carroll
<p>Share us an example of your recurring &quot;image changes&quot;. I think your problem is not with docker, is with the architecture of your application.</p>
<ul>
<li>Data changes should be handled using a database not  the file system.</li>
<li>Source code changes, should be managed with a git repository and the respective new build, generating a new image version ready to be deployed</li>
<li>Infrastructure changes should be ... <strong>That's what Docker was created for.</strong> You should modify the Dockerfile, push the changes, build a new image, etc</li>
<li>Configurations should be managed with environment variables manually injected at docker run or using some external  service like consul, configurator, etc</li>
<li>If your application needs to upload or download files like images, reports, etc, you should use a specialized service like aws s3, gcp Filestore, some open source, etc</li>
</ul>
<p>As you can see, you don't need a huge native backup with docker commit.</p>

CC BY-SA 4.0
2022-04-12T00:20:49.327Z
2022-04-12T00:20:49.327Z
JRichardsz
<p>I am aware of two ways of creating Docker images:</p>
<ol>
<li>Build the image using a Dockerfile</li>
<li>Use <a href="https://docs.docker.com/engine/reference/commandline/commit/" rel="nofollow noreferrer"><code>docker commit &lt;container_id&gt;</code></a> against a running container with changes.</li>
</ol>
<p>I find changing a Dockerfile each time I need image changes to be awfully inconvenient.
Instead I have taken to launching ephemeral containers with <code>docker run</code>, installing packages I need on the fly with sudo, then committing the image.</p>
<p>I didn't realize however there is a footgun involved in this approach, especially if you frequently use and switch up <a href="https://docs.docker.com/engine/reference/commandline/run/" rel="nofollow noreferrer"><code>docker run</code></a> hacks. I launch containers with changing bind mounts, environment variables, differing networks, etc. A lot of that seems to be considered part of the configuration of the container, and is committed in <a href="https://docs.docker.com/engine/reference/commandline/commit/" rel="nofollow noreferrer"><code>docker commit</code></a> alongside actual filesystem changes.</p>
<p>For example if you do:</p>
<pre class="lang-sh prettyprint-override"><code>docker run --env FOO=BAR --name container_name ubuntu:focal
docker commit container_name new_image
docker run -it new_image
echo $FOO
</code></pre>
<p>You will see that the env variable FOO is now a part of new_image.</p>
<p>This creates some awfully confusing situations, as I consider arguments to <a href="https://docs.docker.com/engine/reference/commandline/run/" rel="nofollow noreferrer"><code>docker run</code></a> to be as <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#create-ephemeral-containers" rel="nofollow noreferrer">ephemeral</a> as the container it creates. I am only concerned about persisting package installs.</p>
<blockquote>
<p>I would like to commit <em>just</em> the actual image, just the file system changes.
Is there any way to do that?</p>
</blockquote>

CC BY-SA 4.0
2022-03-15T19:50:20.280Z
The way to go is as you said to write a Dockerfile. Why do you find it inconvenient? It should be roughly just adding some `RUN ...` directives similar to what you do manually when running the initial container.
Gaël J
CC BY-SA 4.0
2022-04-05T16:03:46.583Z
This has been answered in another thread:
https://stackoverflow.com/questions/18952572/how-to-remove-an-env-setting-from-a-docker-image/39684436
cmsmith7
<docker><dockerfile>
How do I create a Docker image from a container without configuration changes?
kcghost
# How do I create a Docker image from a container without configuration changes?

(Asked by: username_0 on 2022-03-13)

I am aware of two ways of creating Docker images:

Build the image using a Dockerfile
Use docker commit  against a running container with changes.

I find changing a Dockerfile each time I need image changes to be awfully inconvenient.
Instead I have taken to launching ephemeral containers with docker run, installing packages I need on the fly with sudo, then committing the image.
I didn't realize however there is a footgun involved in this approach, especially if you frequently use and switch up docker run hacks. I launch containers with changing bind mounts, environment variables, differing networks, etc. A lot of that seems to be considered part of the configuration of the container, and is committed in docker commit alongside actual filesystem changes.
For example if you do:
docker run --env FOO=BAR --name container_name ubuntu:focal
docker commit container_name new_image
docker run -it new_image
echo $FOO

You will see that the env variable FOO is now a part of new_image.
This creates some awfully confusing situations, as I consider arguments to docker run to be as ephemeral as the container it creates. I am only concerned about persisting package installs.

I would like to commit just the actual image, just the file system changes.
Is there any way to do that?

**Tags:** docker, dockerfile

> **Comments:**
> **username_1**: The way to go is as you said to write a Dockerfile. Why do you find it inconvenient? It should be roughly just adding some `RUN ...` directives similar to what you do manually when running the initial container.  
> **username_2**: This has been answered in another thread: https://stackoverflow.com/questions/18952572/how-to-remove-an-env-setting-from-a-docker-image/39684436  

---

## 3 answers

### Answer by username_3 on 2022-05-16. Score: 1

You could try giving docker commit --change a try.
docker run --env FOO=BAR 
docker commit --change "ENV FOO=SETVALUE"  

Please note that docker's engine specifies that "[If the operator] names an environment variable without specifying a value, then the current value of the named variable is propagated into the container’s environment" so you'll need to set the environment variable to something such as SETVALUE
an environment variable without specifying a value, the current value of the named variable on the host is propagated into the container's environment


---

### Answer by username_4 on 2022-05-16. Score: 0

Buildah

This creates some awfully confusing situations, as I consider arguments to docker run to be as ephemeral as the container it creates. I am only concerned about persisting package installs.

Sure does. Don't use docker. =) Docker is just one method of creating an image. It blurs the line between and online (hot container) and offline build process. Instead try buildah, which works with any shell. No dockerfile needed, also runs rootless. Try the below with buildah unshare ./image.sh
#!/bin/bash
# Call this script image.sh
# Invoke as regular user with `buildah unshare ./image.sh`
ctr=$(buildah from alpine:3)
mnt=$(buildah mount "$ctr")

echo "Created offline container $ctr"
echo "Got mount $mnt"

# write/copy/move directly into $mnt
echo "Write directly into mount" > "$mnt/foo.txt"

temp=$(mktemp)
echo "Created temp $temp"
echo foo > "$temp"
mv "$temp" "$mnt/bar"

echo "No container running"

buildah run "$ctr" /bin/sh <<-EOF
  echo "Hello from inside container.";
  apk update;
  apk add podman;
  echo 42 > baz;
EOF

buildah config                     \
  --author "Joe Doe " \
  --label "apples=oranges"         \
  --env "foo=bar"                  \
  "$ctr";

buildah commit "$ctr" mynewimage

You can see what that includes
podman run -i mynewimage /bin/sh <<-"EOF"
  echo -e "\nfoo:"
  cat foo

  echo -e "\nbar:"
  cat bar

  echo -e "\nbaz:"
  cat baz

  echo -e "\nenv"
  env
EOF


---

### Answer by username_5 on 2022-04-12. Score: 0

Share us an example of your recurring "image changes". I think your problem is not with docker, is with the architecture of your application.

* Data changes should be handled using a database not the file system.
* Source code changes, should be managed with a git repository and the respective new build, generating a new image version ready to be deployed
* Infrastructure changes should be ... **That's what Docker was created for.** You should modify the Dockerfile, push the changes, build a new image, etc
* Configurations should be managed with environment variables manually injected at docker run or using some external service like consul, configurator, etc
* If your application needs to upload or download files like images, reports, etc, you should use a specialized service like aws s3, gcp Filestore, some open source, etc

As you can see, you don't need a huge native backup with docker commit.


---

