@@ -248,85 +248,84 @@
248 248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
TCC += -Dsocketlen_t=int
249 249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
TCC += -DSQLITE_MAX_MMAP_SIZE=0
250 250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</pre></blockquote>
251 251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
</ul>
252 252 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
253 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <h2>5.0 Building a Static Binary on Linux using Docker</h2>
254 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
255 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Building a static binary on Linux is not as straightforward as it
256 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- could be because the GNU C library requires that certain components be
257 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- dynamically loadable. That can be worked around by building against a
258 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- different C library, which is simplest to do by way of a container
259 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- environment like [https://www.docker.com/ | Docker].
260 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
261 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- The following instructions for building fossil using Docker
262 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- were adapted from [https://fossil-scm.org/forum/forumpost/5dd2d61e5f | forumpost/5dd2d61e5f].
263 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- These instructions assume that docker is installed and that the user running
264 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- these instructions has permission to do so (i.e., they are <tt>root</tt> or
265 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- are a member of the <tt>docker</tt> group).
266 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
267 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- First, create a file named <tt>Dockerfile</tt> with the following contents:
268 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
269 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code>
270 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- FROM alpine:edge
271 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- RUN apk update \
272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && apk upgrade \
273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && apk add --no-cache \
274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- curl gcc make tcl \
275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- musl-dev \
276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- openssl-dev zlib-dev \
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- openssl-libs-static zlib-static \
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && curl \
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "https://fossil-scm.org/home/tarball/fossil-src.tar.gz?name=fossil-src&uuid=trunk" \
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- -o fossil-src.tar.gz \
281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && tar xf fossil-src.tar.gz \
282 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && cd fossil-src \
283 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && ./configure \
284 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --static \
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --disable-fusefs \
286 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --with-th1-docs \
287 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- --with-th1-hooks \
288 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- && make
289 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </code></pre>
290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Be sure to modify the <tt>configure</tt> flags, if desired. e.g., add <tt>--json</tt>
292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- for JSON support.
293 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
294 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- From the directory containing that file, build it with docker:
295 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
296 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code># docker build -t fossil_static .</code></pre>
297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- If you get permissions errors when running that as a non-root user,
299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- be sure to add the user to the <tt>docker</tt> group before trying
300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- again.
301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- That creates a docker image and builds a static fossil binary inside
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- it. That step will take several minutes or more, depending on the
304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- speed of the build environment.
305 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Next, create a docker container to host the image we just created:
307 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
308 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code># docker create --name fossil fossil_static</code></pre>
309 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
310 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Then copy the fossil binary from that container:
311 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
312 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code># docker cp fossil:/fossil-src/fossil fossil</code></pre>
313 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
314 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- The resulting binary will be <em>huge</em> because it is built with
315 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- debug info. To strip that information, reducing the size greatly:
316 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
317 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code># strip fossil</code></pre>
318 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
319 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- To delete the Docker container and image (if desired), run:
320 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
321 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code># docker container rm fossil
322 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # docker image ls
323 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- </code></pre>
324 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
325 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Note the IDs of the images named <tt>fossil_static</tt> and <tt>alpine</tt>, then:
326 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
-
327 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- <pre><code>docker image rm THE_FOSSIL_ID THE_ALPINE_ID</code></pre>
253 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
254 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <h2 id="docker">5.0 Building a Docker Container</h2>
255 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
256 { 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
257 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ you can build like so:
258 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
259 { 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!
+
261 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ If the image built successfully, you can create a container from it and
262 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ test that it runs:
263 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
264 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker run --name fossil -p 9999:8080/tcp fossil</code></pre>
265 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
266 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ This shows us remapping the internal TCP listening port as 9999 on the
267 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ host. As a rule, there's little point to using the "<tt>fossil server
268 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ --port</tt>" feature inside a Docker container. Let it default to 8080
269 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ internally, then remap it to wherever you want it on the host instead.
270 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
271 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Our stock <tt>Dockerfile</tt> configures Fossil with the default feature
272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set, so you may wish to modify the <tt>Dockerfile</tt> to add
273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ configuration options, add APK packages to support those options, and so
274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ forth.
275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ It builds tip-of-trunk. To get a release version instead, append
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "<tt>?r=release</tt>" to the URL in the <tt>Dockerfile</tt>, then
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ (re)build it.
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ You may wish to direct Docker to copy an existing repo into the image at
281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ build time, rather than let it create a blank one automatically. Simply
282 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ add this to the <tt>Dockerfile</tt> before the first "RUN" directive:
283 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
284 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> COPY /local/path/to/my-project.fossil /jail/repo.fossil</code></pre>
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
286 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ A potentially surprising feature of this container is that it runs
287 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Fossil as root, which causes [./chroot.md | Fossil's chroot jail
288 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ feature] to kick in. Since a Docker container is a type of über-jail
289 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ already, you may be wondering why we don't either:
290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # run <tt>fossil server --nojail</tt> to skip the internal chroot; or
292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # create a non-root user and force Docker to use that instead
293 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
294 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ The reason is, although this container is quite stripped-down by today's
295 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ standards, it's based on the [https://www.busybox.net/BusyBox.html |
296 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ surprisingly powerful Busybox project]. (This author made a living for
297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ years in the early 1990s using Unix systems that were less powerful than
298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this container.) If someone ever figured out how to make a Fossil binary
299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ execute arbitrary commands on the host or to open up a remote shell,
300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ they'd likely be able to island-hop from there into the rest of your
301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ network. We need this cute double-jail dance to keep the Fossil instance
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from accessing the Busybox features.
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ We deem this risk low since a) it's never happened, that we know of;
305 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ and b) we've turned off all of the risky features like TH1 docs.
306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Nevertheless, we believe in defense-in-depth.
307 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
308 { 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
309 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ we've got everything reduced to the two key static binaries — Fossil and
310 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Busybox — we throw all the rest of it away.
311 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
312 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ A secondary benefit falls out of this process for free: it's arguably
313 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ the easiest way to build a purely static Fossil binary for Linux. Most
314 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ modern Linux distros make this surprisingly difficult, but Alpine's
315 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ back-to-basics nature makes static builds work the way they used to,
316 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ back in the day. If that's what you're after, you can skip the "run"
317 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ command above and extract the executable from the image instead:
318 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
319 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ <pre><code> $ docker create --name fossil_static fossil_static
320 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $ docker cp fossil_static:/jail/bin/fossil .
321 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $ docker container rm fossil_static
322 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ $ docker image rm fossil_static
323 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ </code></pre>
324 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
325 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ The resulting binary is the single largest file inside that container,
326 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ at about 6 MiB. (It's built stripped.)
328 327 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
329 328 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
330 329 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h2>6.0 Building on/for Android</h2>
331 330 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
332 331 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
<h3>6.1 Cross-compiling from Linux</h3>
333 332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!