8

I built Alpine Linux in a Docker container with the following Dockerfile:

FROM alpine:3.2
RUN apk add --update jq curl && rm -rf /var/cache/apk/*

the build run successfully:

$ docker build -t collector .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update jq curl && rm -rf /var/cache/apk/*
 ---> Running in 888571296e79
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/11) Installing run-parts (4.4-r0)
(2/11) Installing openssl (1.0.2a-r1)
(3/11) Installing lua5.2-libs (5.2.4-r0)
(4/11) Installing lua5.2 (5.2.4-r0)
(5/11) Installing ncurses-terminfo-base (5.9-r3)
(6/11) Installing ncurses-widec-libs (5.9-r3)
(7/11) Installing lua5.2-posix (33.3.1-r2)
(8/11) Installing ca-certificates (20141019-r2)
(9/11) Installing libssh2 (1.5.0-r0)
(10/11) Installing curl (7.42.1-r0)
(11/11) Installing jq (1.4-r0)
Executing busybox-1.23.2-r0.trigger
Executing ca-certificates-20141019-r2.trigger
OK: 9 MiB in 26 packages
 ---> 7625779b773d
Removing intermediate container 888571296e79
Successfully built 7625779b773d

anyway when I run date -d it fails:

$ docker run -i -t collector sh
/ # date -d yesterday
date: invalid date 'yesterday'
/ # date -d now
date: invalid date 'now'
/ # date -d next-month
date: invalid date 'next-month'

while the rest of the options seem running ok:

/ # date 
Sat May 30 18:57:24 UTC 2015
/ # date +"%A"
Saturday
/ # date +"%Y-%m-%dT%H:%M:%SZ"
2015-05-30T19:00:38Z
  • Don't count on the date command supporting reference dates with "now", "yesterday", etc., or other non-standard extensions. – Janis May 30 '15 at 21:09
22

BusyBox/Alpine version of date doesn't support -d options, even if the help is exatly the same in the Ubuntu version as well as in others more fat distros.

Also the "containerization" doesn't miss anything here.

To work with -d options you just need to add coreutils package:

$ cat Dockerfile.alpine-coreutils
FROM alpine:3.2
RUN apk add --update coreutils && rm -rf /var/cache/apk/*


$ docker build -t alpine-coreutils - <  Dockerfile.alpine-coreutils
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update coreutils && rm -rf /var/cache/apk/*
 ---> Running in 694fa5cb271c
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/3) Installing libattr (2.4.47-r3)
(2/3) Installing libacl (2.2.52-r2)
(3/3) Installing coreutils (8.23-r0)
Executing busybox-1.23.2-r0.trigger
OK: 12 MiB in 18 packages
 ---> a7d9116a00ee
Removing intermediate container 694fa5cb271c
Successfully built a7d9116a00ee


$ docker run -i -t alpine-coreutils sh
/ # date -d last-week
Sun May 24 09:19:34 UTC 2015
/ # date -d yesterday 
Sat May 30 09:19:46 UTC 2015
/ # date 
Sun May 31 09:19:50 UTC 2015

The image size will double but is till 11.47 MB, more than an order of siZe less, compared to Debian standard :

$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
alpine-coreutils           latest              a7d9116a00ee        2 minutes ago       11.47 MB
alpine                     3.2                 8697b6cc1f48        2 days ago          5.242 MB
debian                     latest              df2a0347c9d0        11 days ago         125.2 MB

Thanks to Andy Shinn: https://github.com/gliderlabs/docker-alpine/issues/40#issuecomment-107122371

And to Christopher Horrell: https://github.com/docker-library/official-images/issues/771#issuecomment-107101595

1

I suppose the date you can run in that container is not GNU coreutils date which is commonly available on Linux hosts, but one of the Busybox applets. Try to get help messages from both of them.

# date --help
BusyBox v1.22.1 (Ubuntu 1:1.22.0-9ubuntu1) multi-call binary.

Usage: date [OPTIONS] [+FMT] [TIME]

Display time (using +FMT), or set time

    [-s,--set] TIME Set time to TIME
    -u,--utc    Work in UTC (don't convert to local time)
    -R,--rfc-2822   Output RFC-2822 compliant date string
    -I[SPEC]    Output ISO-8601 compliant date string
            SPEC='date' (default) for date only,
            'hours', 'minutes', or 'seconds' for date and
            time to the indicated precision
    -r,--reference FILE Display last modification time of FILE
    -d,--date TIME  Display TIME, not 'now'
    -D FMT      Use FMT for -d TIME conversion

Recognized TIME formats:
    hh:mm[:ss]
    [YYYY.]MM.DD-hh:mm[:ss]
    YYYY-MM-DD hh:mm[:ss]
    [[[[[YY]YY]MM]DD]hh]mm[.ss]
    'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead

BusyBox offers many applets for Posix standard commands with single crunched binary, but most of them has very restricted functions in exchange for its saved size (compare outputs of find --help or tar --help in both environments for example). It frequently happens that a script which runs successfully in the development/host environment doesn't work at all in the container/target environment with BusyBox.

0

busybox date supports a -D option which (like zsh's strftime but contrary to GNU date) gives you an interface to strptime() where you can parse dates (though not relative dates) in any format (ast-open date and ksh93's printf also have ways to customize the input format).

Where busybox is built against a C library implementation whose strptime() and strftime() support the non-standard %s flag, you could do:

date -D %s -d "$(($(date +%s) - 86400))"

In the musl C library which alpine Linux uses however, strftime() does support %s but strptime() doesn't. It's OK though as busybox date, like GNU date supports the @epochtime date specification, so you can do:

date -d "@$(($(date +%s) - 86400))"

Which will give you the date 86400 seconds ago, without the ambiguity of GNU date's yesterday (is it 86400 ago, or is it yesterday at the same time of the day? What if there was no such time of the day yesterday because the clock changed for DST?).

That syntax should also work with GNU date.

With ast-open's date (or ksh93's printf '%(%c)T'), you'd use:

date -d "#$(($(date +%s) - 86400))"

instead.

Note that if you want to report UTC (Zulu) time, you should use TZ=UTC0 date or date -u as otherwise, you'd get the time in the system's/user's timezone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.