docs: Initial import/conversion

This commit is contained in:
Chloe Kudryavtsev committed 2019-05-03 19:58:59 -04:00
1 parent ba87ffadc1
commit b924dfa326
6 files changed
+184 -7

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
= docker-alpine
:ao: alpinelinux.org
:hubp: _/alpine
:hub: https://hub.docker.com/r/{hubp}/
image:https://img.shields.io/docker/stars/{hubp}.svg[link={hub}]
image:https://img.shields.io/docker/pulls/{hubp}.svg[link={hub}]
The official Docker image for https://{ao}[Alpine Linux].
The image is only 5MB and has access to a package repository that is much more featureful than other BusyBox based images.
== Why
Docker images today are big.
Usually much larger than they need to be.
There are a lot of ways to make them smaller, but the Docker populace still jumps to the `ubuntu` base image for most projects.
The size savings over `ubuntu` and other bases are huge:
[source]
----
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest cbc475bbc33b 55 seconds ago 5.53MB
ubuntu latest d131e0fa2585 7 days ago 102MB
debian latest 2d337f242f07 5 weeks ago 101MB
centos latest 9f38484d220f 7 weeks ago 202MB
----
There are images such as `progrium/busybox` which get us close to a minimal container and package system, but these particular BusyBox builds piggyback on the OpenWRT package index, which is often lacking and not tailored towards generic everyday applications.
Alpine Linux has a much more featureful and up to date https://pkgs.{ao}[Package Index]:
[source]
----
$ docker run progrium/busybox opkg-install nodejs
Unknown package 'nodejs'.
Collected errors:
* opkg_install_cmd: Cannot install package nodejs.
$ docker run alpine apk add --no-cache nodejs
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/7) Installing ca-certificates (20190108-r0)
(2/7) Installing c-ares (1.15.0-r0)
(3/7) Installing libgcc (8.3.0-r0)
(4/7) Installing http-parser (2.8.1-r0)
(5/7) Installing libstdc++ (8.3.0-r0)
(6/7) Installing libuv (1.23.2-r0)
(7/7) Installing nodejs (10.14.2-r0)
Executing busybox-1.29.3-r10.trigger
Executing ca-certificates-20190108-r0.trigger
OK: 31 MiB in 21 packages
----
This makes Alpine Linux a great image base for utilities, as well as production applications.
https://www.{ao}/about/[Read more about Alpine Linux here] and it will become obvious how its mantra fits in right at home with Docker images.
NOTE: All of the example outputs above were last generated/updated on May 3rd 2019.
== Usage
Stop doing this:
[source, docker]
----
FROM ubuntu-debootstrap:14.04
RUN apt-get update -q \
&& DEBIAN_FRONTEND=noninteractive apt-get install -qy mysql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt
ENTRYPOINT ["mysql"]
----
This took 28 seconds to build and yields a 169 MB image.
Start doing this:
[source, docker]
----
FROM alpine:3.9
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]
----
Only 4 seconds to build and results in a 41 MB image!
-7
View File
@@ -1,7 +0,0 @@
# docker-alpine
[![Docker Stars](https://img.shields.io/docker/stars/library/alpine.svg)][hub]
[![Docker Pulls](https://img.shields.io/docker/pulls/library/alpine.svg)][hub]
[hub]: https://hub.docker.com/r/gliderlabs/alpine/
+29
View File
@@ -0,0 +1,29 @@
= About
https://alpinelinux.org[Alpine Linux] is a lightweight Linux distribution based on the https://www.musl-libc.org[musl libc] and https://busybox.net/[BusyBox].
The base is extremely small, builds as a Docker image in a matter of seconds, and has a full-featured package index.
== Musl Libc
Musl is consistent and provides high implementation quality regardless of whether the user is a tiny embedded system or a full-fledged server.
Minimal machine-specific code means less chance of breakage on minority architectures and better success with “write once run everywhere” C development.
Designed from the ground up for static linking, musl carefully avoids pulling in large amounts of code or data that the applications will not use.
Using musl maximizes application deployability.
Binaries statically linked with musl have no external dependencies, even for features like DNS lookups or character set conversions that are implemented with dynamic loading on glibc.
An application truly can be deployed as a single binary file and run on any machine with the appropriate instruction set architecture and Linux kernel or Linux syscall ABI emulation layer.
== BusyBox
BusyBox combines tiny versions of many common UNIX utilities into a single small executable.
It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc.
The utilities in BusyBox generally have fewer features than their full-featured GNU cousins.
However, the otions that *are* included provide the expected functionality and are tuned to behave like their GNU counterparts.
BusyBox provides a fairly complete environment for any small or embedded system.
BusyBox has been written with size-optimization and limited resources in mind.
It is also extremely modular so you can easily include or exclude commands (or features) at compile time.
This makes it easy to customize your embedded systems.
To create a working system, just add some device nodes in `/dev`, a few configuration files in `/etc`, and a Linux kernel.
== Match made in heaven
Pairing musl libc with BusyBox to combine common UNIX utilities into a single small executable, it makes for an excellent Docker image base.
We get extremely small builds (the base image is only 5 MB) that end up cutting time during push and pull.
+13
View File
@@ -0,0 +1,13 @@
= Build
Normally, it is sufficient to simply run `docker pull alpine:tag` to get a locally cached image.
However, you can use the scripts present in this repository to build your own local copies.
== Automatic
You can use `prepare-branch.sh` in order to generate the tarballs and Dockerfiles necessary to create an Alpine image for all of the supported architectures.
Simply decide which release of alpine you wish to be able to build (such as `v3.9` or `edge`) and call the `prepare` function of `prepare-branch.sh`.
For example, to generate edge images, you would run `prepare-branch.sh prepare edge`.
This will create a directory under `/tmp`, download release tarballs for the selected version, generate necessary Dockerfiles, run tests and print the directory.
At that point, you may enter it and use any of the desired Dockerfiles as per usual.
CAUTION: This process currently relies on Alpine already being available as a specific tagged image.
+24
View File
@@ -0,0 +1,24 @@
= Caveats
The musl libc may work differently than what you are used to.
Musl's https://wiki.musl-libc.org/functional-differences-from-glibc.html[functional differences from glibc] document does a good job of outlining everything.
Please do go over it.
This document will outline the most common kinds of issues you are likely to find.
== Incompatible Binaries
While there are binaries that will run on musl libc without needing to be recompiled, you will likely encounter binaries and applications that rely on specific glibc functionality that will fail to start up.
An example of this would be Oracle's Java implementation, which relies on specific symbols only found in glibc.
You can often use ldd to determine the exact symbol:
[source]
----
# ldd bin/java
/lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
libjli.so => bin/../lib/amd64/jli/libjli.so (0x7f542e9a0000)
libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
Error relocating bin/../lib/amd64/jli/libjli.so: __rawmemchr: symbol not found
----
In this case, upstream would need to remove the dependency on the offending symbol, or offer you the ability to compile the software natively on a musl-based system.
Be sure to check the https://pkgs.alpinelinux.org[Alpine Linux package index] to see if a suitable replacement package already exists.
+45
View File
@@ -0,0 +1,45 @@
= Usage
== Packages
Replacing your current base image with the Docker Alpine Linux image usually requires updating the package names to the corresponding ones in the https://pkgs.alpinelinux.org[Alpine Linux package index].
We use the `apk` command to manage packages.
It works similarly to `apt` and `yum`.
For example, installing the `nginx` package would be done by running `apk add --no-cache nginx`.
The `--no-cache` argument prevents `apk` from caching the package index - something that would normally take up precious space, as well as go stale quickly.
=== Example
This is an example of a complete Dockerfile for `nginx`:
[source, docker]
----
FROM alpine
RUN apk --no-cache add nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
----
=== Virtual Packages
Another great `apk` feature is the concept of user-defined virtual packages.
Packages added under a virtual package name can later be removed as one group.
An example use-case would be removing all build dependencies at once, as in this example:
[source, docker]
----
FROM alpine
WORKDIR /myapp
COPY . /myapp
RUN apk add --no-cache python py-pip openssl ca-certificates
RUN apk add --no-cache --virtual build-dependencies python-dev build-base wget \
&& pip install -r requirements.txt \
&& python setup.py install \
&& apk del build-dependencies
CMD ["myapp", "start"]
----
// COMBAK: update docs link
=== Further Details
For further details on `apk` and how it's used, you can look at https://docs.alpinelinux.org/user-handbook/0.1a/Working/apk.html[Alpine's User Documentation] for it.