@@ -255,11 +255,11 @@
255 255 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h2 id="docker">5.0 Building a Docker Container</h2>
256 256 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
257 257 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Fossil ships a <tt>Dockerfile</tt> at the top of its source tree which
258 258 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
you can build like so:
259 259 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
260 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code> $ docker build -t fossil --no-cache .</code></pre>
260 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker build -t fossil .</code></pre>
261 261 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
262 262 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
If the image built successfully, you can create a container from it and
263 263 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
test that it runs:
264 264 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
265 265 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<pre><code> $ docker run --name fossil -p 9999:8080/tcp fossil</code></pre>
@@ -272,14 +272,10 @@
272 272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Our stock <tt>Dockerfile</tt> configures Fossil with the default feature
273 273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
set, so you may wish to modify the <tt>Dockerfile</tt> to add
274 274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
configuration options, add APK packages to support those options, and so
275 275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
forth.
276 276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- It builds tip-of-trunk. To get a release version instead, append
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "<tt>?r=release</tt>" to the URL in the <tt>Dockerfile</tt>, then
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- (re)build it.
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
281 277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
282 278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h3>5.1 Running It in Production</h3>
283 279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
284 280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
If you want the container to serve an existing repository, there are at
285 281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
least two right ways to do it.
@@ -324,23 +320,14 @@
324 320 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
host machine, which is unlikely to map to anything in the container's
325 321 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<tt>/etc/passwd</tt> and <tt>/etc/group</tt> files, effectively
326 322 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
preventing the server from reading the copied-in repository file.
327 323 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
499 is the default "fossil" user ID inside the container, causing Fossil to run
328 324 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
with that user's privileges after it enters the chroot.
325 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ (See [#docker-args | below] for how to change this default.)
329 326 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
You don't have to restart the server after fixing this with
330 327 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<tt>chmod</tt>: simply reload the browser, and Fossil will try again.
331 328 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- (Why 499? Because regular user IDs start at 500 or 1000 on most Unix
333 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- type systems, leaving those below it for "system" users like this Fossil
334 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- daemon owner; standard OS system users start at 0 and go upward, so we
335 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- started at 500 and went down one to avoid a conflict. If you use Docker
336 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- volumes, you may wish to override this at container creation time — the
337 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "run" or "create" command — by passing an option like "<tt>-e
338 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- UID=501</tt>". The internal container user IDs are used for permissions
339 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- on the volume, where the host's user/group IDs come into play, so
340 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- syncing the in-container user ID with the host can be useful.)
341 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
342 329 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
This simple method has a problem: Docker containers are designed to be
343 330 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
killed off at the slightest cause, rebuilt, and redeployed. If you do
344 331 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
that with the repo inside the container, it gets destroyed, too. The
345 332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
solution is to replace the "run" command above with the following:
346 333 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@@ -355,11 +342,11 @@
355 342 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
rebuild the container or its underlying image — such as to upgrade to a newer version of Fossil
356 343 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
— the volume remains behind and gets remapped into the new container
357 344 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
when you recreate it by giving the above command again.
358 345 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
359 346 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
360 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <h3>5.2 Why Chroot?</h3>
347 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h3 id="docker-chroot">5.2 Why Chroot?</h3>
361 348 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
362 349 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
A potentially surprising feature of this container is that it runs
363 350 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Fossil as root. Since that causes [./chroot.md | Fossil's chroot jail
364 351 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
feature] to kick in, and a Docker container is a type of über-jail
365 352 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
already, you may be wondering why we don't either:
@@ -391,11 +378,11 @@
391 378 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
without restarting it: each hit reevaluates the repository file
392 379 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
permissions when deciding what user to become when dropping root
393 380 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
privileges.
394 381 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
395 382 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
396 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <h3>5.3 Extracting a Static Binary</h3>
383 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h3 id="docker-static">5.3 Extracting a Static Binary</h3>
397 384 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
398 385 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Our 2-stage build process uses Alpine Linux only as a build host. Once
399 386 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
we've got everything reduced to the two key static binaries — Fossil and
400 387 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Busybox — we throw all the rest of it away.
401 388 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@@ -413,10 +400,71 @@
413 400 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</code></pre>
414 401 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
415 402 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
The resulting binary is the single largest file inside that container,
416 403 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
at about 6 MiB. (It's built stripped.)
417 404 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
405 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
406 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h3 id="docker-args">5.4 Container Build Arguments</h3>
407 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
408 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h4>5.4.1 Package Versions</h4>
409 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
410 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ You can override the default versions of Fossil and BusyBox that get
411 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fetched in the build step. To get the latest-and-greatest of
412 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ everything, you could say:
413 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
414 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker build -t fossil \
415 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ --build-arg FSLVER=trunk \
416 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ --build-arg BBXVER=master .</code></pre>
417 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
418 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ (But don't, for reasons we will get to.)
419 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
420 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Because the BusyBox configuration file we ship was created with and
421 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tested against a specific stable release, that's the version we pull by
422 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ default. It does try to merge the defaults for any new configuration
423 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ settings into the stock set, but since it's possible this will fail, we
424 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ don't blindly update the BusyBox version merely because a new release
425 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ came out. Someone needs to get around to vetting it against our stock
426 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ configuration first.
427 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
428 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ As for Fossil, it defaults to fetching the same version as the checkout
429 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ you're running the build command from, based on checkin ID. The most
430 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ common reason to override this is to get a release version:
431 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
432 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker build -t fossil \
433 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ --build-arg FSLVER=version-2.19 .</code></pre>
434 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
435 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ It's best to use a specific version number rather than the generic
436 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "release" tag because Docker caches downloaded files and tries to reuse
437 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ them across builds. If you ask for "release" before a new version is
438 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tagged and then immediately after, you expect to get two different
439 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tarballs, but because the URL hasn't changed, if you have an old release
440 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tarball in your Docker cache, you'll get the old version even if you
441 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pass the "docker build --no-cache" option.
442 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
443 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ This is why we default to a checkin ID rather than a generic tag like
444 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "trunk": so the URL will change each time you update your Fossil source
445 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tree, forcing Docker to pull a fresh tarball.
446 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
447 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h4>5.4.2 User & Group IDs</h4>
448 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
449 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ The "fossil" user and group IDs inside the container default to 499.
450 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Why? Regular user IDs start at 500 or 1000 on most Unix type systems,
451 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ leaving those below it for "system" users like this Fossil daemon owner.
452 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Since standard OS system users start at 0 and go upward, we started at
453 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ 500 and went down one to reduce the chance of a conflict to as close to
454 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zero as we can manage.
455 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
456 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ To change it to something else, say:
457 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
458 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker build -t fossil --build-arg UID=501 .</code></pre>
459 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
460 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ This is particularly useful if you're putting your repository on a
461 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Docker volume since the IDs "leak" out into the host environment via
462 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ file permissions. You may therefore wish them to mean something on both
463 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ sides of the container barrier rather than have "499" appear on the host
464 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ in "<tt>ls -l</tt>" output.
465 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
418 466 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
419 467 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h2>6.0 Building on/for Android</h2>
420 468 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
421 469 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h3>6.1 Cross-compiling from Linux</h3>
422 470 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
423 471 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!