320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
|
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
-
-
-
-
|
$ docker exec fossil chown -R 499 /jail/museum</code></pre>
That copies the local Fossil repo into the container where the server
expects to find it, so that the "start" command causes it to serve from
that copied-in file instead. Since it lives atop the immutable base layers, it
persists as part of the container proper, surviving restarts.
(The same is true of the default mode of operation: the <tt>fossil
server --create</tt> flag initializes a fresh Fossil repo atop the base
image.)
Notice that the copy command changes the name of the repository database.
The container configuration expects it to be called
<tt>repo.fossil</tt>, which it almost certainly was not out on the host
system. This is because there is only one repository inside this
container, so we don't have to name it after the project it contains, as
is traditional. A generic name lets us hard-code the server start
command.
|
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
|
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
|
<h4>5.1.2 Storing the Repo Outside the Container</h4>
The simple storage method above has a problem: Docker containers are designed to be
killed off at the slightest cause, rebuilt, and redeployed. If you do
that with the repo inside the container, it gets destroyed, too. The
solution is to replace the "run" command above with the following:
<pre><code> $ docker create \
--name fossil -p 9999:8080/tcp \
-v museum:/jail/museum fossil
<pre><code> $ docker run \
--name fossil-bind-mount -p 9999:8080 \
-v ~/museum:/jail/museum fossil
</code></pre>
Because this bind mount maps a host-side directory (<tt>~/museum</tt>)
into the container, you don't need to <tt>docker cp</tt> the repo into
the container at all. It still expects to find the repository as
<tt>repo.fossil</tt> under that directory, but now both the host and the
container can see that file. (Beware: This may create a
[https://www.sqlite.org/howtocorrupt.html | risk of data corruption] due
to SQLite locking issues if you try to modify the DB from both sides at
once.)
Now when you "docker cp" the local repo into the container, it lands on
a separate [https://docs.docker.com/storage/volumes/ | Docker volume]
mounted inside it, giving those files an independent lifetime. When you need to
Instead of a bind mount, you could instead set up
a separate [https://docs.docker.com/storage/volumes/ | Docker volume],
at which point you <i>would</i> need to <tt>docker cp</tt> the repo file
into the container.
Either way, files in these mounted directories have a lifetime independent
of the container(s) they're mounted into. When you need to
rebuild the container or its underlying image — such as to upgrade to a newer version of Fossil
— the volume remains behind and gets remapped into the new container
when you recreate it by giving the above command again.
— the external directory remains behind and gets remapped into the new container
when you recreate it with <tt>-v</tt>.
<h3 id="docker-chroot">5.2 Why Chroot?</h3>
A potentially surprising feature of this container is that it runs
Fossil as root. Since that causes [./chroot.md | Fossil's chroot jail
feature] to kick in, and a Docker container is a type of über-jail
|