Merge pull request #44 from Snapchat/docker_build
Docker Build for keydb-internal (Snap sepcific)
This commit is contained in:
commit
a58a7f55c3
1
docker-internal/.gitignore
vendored
Normal file
1
docker-internal/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
GHE_PersonalAccessToken.txt
|
116
docker-internal/Dockerfile
Normal file
116
docker-internal/Dockerfile
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
FROM ubuntu:20.04
|
||||||
|
SHELL ["/bin/bash","-c"]
|
||||||
|
RUN groupadd -r keydb && useradd -r -g keydb keydb
|
||||||
|
# use gosu for easy step-down from root: https://github.com/tianon/gosu/releases
|
||||||
|
ENV GOSU_VERSION 1.14
|
||||||
|
RUN set -eux; \
|
||||||
|
savedAptMark="$(apt-mark showmanual)"; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y --no-install-recommends ca-certificates dirmngr gnupg wget; \
|
||||||
|
rm -rf /var/lib/apt/lists/*; \
|
||||||
|
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
|
||||||
|
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
|
||||||
|
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
|
||||||
|
export GNUPGHOME="$(mktemp -d)"; \
|
||||||
|
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
|
||||||
|
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
|
||||||
|
gpgconf --kill all; \
|
||||||
|
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
|
||||||
|
apt-mark auto '.*' > /dev/null; \
|
||||||
|
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
|
||||||
|
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||||
|
chmod +x /usr/local/bin/gosu; \
|
||||||
|
gosu --version; \
|
||||||
|
gosu nobody true
|
||||||
|
# build KeyDB
|
||||||
|
ARG KEYDB_DIR
|
||||||
|
COPY $KEYDB_DIR /tmp/keydb-internal/
|
||||||
|
RUN set -eux; \
|
||||||
|
\
|
||||||
|
savedAptMark="$(apt-mark showmanual)"; \
|
||||||
|
apt-get update; \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -qqy --no-install-recommends \
|
||||||
|
dpkg-dev \
|
||||||
|
pkg-config \
|
||||||
|
ca-certificates \
|
||||||
|
build-essential \
|
||||||
|
nasm \
|
||||||
|
autotools-dev \
|
||||||
|
autoconf \
|
||||||
|
libjemalloc-dev \
|
||||||
|
tcl \
|
||||||
|
tcl-dev \
|
||||||
|
uuid-dev \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
libbz2-dev \
|
||||||
|
libzstd-dev \
|
||||||
|
liblz4-dev \
|
||||||
|
libsnappy-dev \
|
||||||
|
libssl-dev; \
|
||||||
|
cd /tmp/keydb-internal; \
|
||||||
|
# disable protected mode as it relates to docker
|
||||||
|
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' ./src/config.cpp; \
|
||||||
|
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' ./src/config.cpp; \
|
||||||
|
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' ./src/config.cpp; \
|
||||||
|
make -j$(nproc) BUILD_TLS=yes NO_LICENSE_CHECK=yes; \
|
||||||
|
cd src; \
|
||||||
|
strip keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel; \
|
||||||
|
mv keydb-server keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel /usr/local/bin/; \
|
||||||
|
# clean up unused dependencies
|
||||||
|
echo $savedAptMark; \
|
||||||
|
apt-mark auto '.*' > /dev/null; \
|
||||||
|
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
|
||||||
|
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||||
|
| awk '/=>/ { print $(NF-1) }' \
|
||||||
|
| sed 's:.*/::' \
|
||||||
|
| sort -u \
|
||||||
|
| xargs -r dpkg-query --search \
|
||||||
|
| cut -d: -f1 \
|
||||||
|
| sort -u \
|
||||||
|
| xargs -r apt-mark manual \
|
||||||
|
; \
|
||||||
|
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||||
|
rm -rf /var/lib/apt/lists/*; \
|
||||||
|
# create working directories and organize files
|
||||||
|
RUN \
|
||||||
|
mkdir /data && chown keydb:keydb /data; \
|
||||||
|
mkdir /flash && chown keydb:keydb /flash; \
|
||||||
|
mkdir -p /etc/keydb; \
|
||||||
|
cp /tmp/keydb-internal/keydb.conf /etc/keydb/; \
|
||||||
|
sed -i 's/^\(daemonize .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(dir .*\)$/# \1\ndir \/data/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(logfile .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/protected-mode yes/protected-mode no/g' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(bind .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
ln -s keydb-cli redis-cli; \
|
||||||
|
cd /etc/keydb; \
|
||||||
|
ln -s keydb.conf redis.conf; \
|
||||||
|
rm -rf /tmp/*
|
||||||
|
# generate entrypoint script
|
||||||
|
RUN set -eux; \
|
||||||
|
echo '#!/bin/sh' > /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'set -e' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# first arg is '-f' or '--some-option'" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# or first arg is `something.conf`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo ' set -- keydb-server "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# allow the container to be started with `--user`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'if [ "$1" = "keydb-server" -a "$(id -u)" = "0" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo " find . \! -user keydb -exec chown keydb '{}' +" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo ' exec gosu keydb "$0" "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'exec "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
# set remaining image properties
|
||||||
|
VOLUME /data
|
||||||
|
WORKDIR /data
|
||||||
|
ENV KEYDB_PRO_DIRECTORY=/usr/local/bin/
|
||||||
|
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||||
|
EXPOSE 6379
|
||||||
|
CMD ["keydb-server","/etc/keydb/keydb.conf"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
74
docker-internal/README.md
Normal file
74
docker-internal/README.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# KeyDB Docker Image (Snap Internal)
|
||||||
|
|
||||||
|
This docker image builds KeyDB within the image and cleans up afterwards. A few notes about the image:
|
||||||
|
* use gosu to avoid running as root https://github.com/tianon/gosu
|
||||||
|
* packages are installed, tracked and cleaned up to minimize container sizes
|
||||||
|
* keydb-server binary symbols remain for troubleshooting. All other KeyDB binaries are stripped
|
||||||
|
* keydb.conf added and linked to redis.conf for legacy compatibility and as default config file
|
||||||
|
* use entrypoint and cmd for best practices. Remove protected-mode during build incase user specifies binary without .conf, or just wants append parameters
|
||||||
|
|
||||||
|
## Building the Docker Image Using Local KeyDB Directory
|
||||||
|
|
||||||
|
If you have a local keydb-internal repository you would like to generate the binaries from, use the command below. This will simply copy over all the files within the local keydb-internal repo and then build the image.
|
||||||
|
|
||||||
|
One issue with COPY is that it creates an additional layer. If we remove the source directory in a later layer the size of the original COPY layer remains creating a large image, hence we need to squash the layers into one layer. This feature is available with experimental mode enabled. This can be done by modifying /etc/docker/daemon.json to include `"experimental": true,`. You may also be able to pass at the build line as shown below.
|
||||||
|
|
||||||
|
Modify the DIR build argument to your local KeyDB repo and update your image tag in the line below
|
||||||
|
|
||||||
|
```
|
||||||
|
DOCKER_CLI_EXPERIMENTAL=enabled docker build --squash --build-arg DIR=/path/to/keydb-internal -t myImageName:imageTag .
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that directories are relative to the docker build context. You can use the `-f /path/to/Dockerfile` to specify Dockerfile which will also set the build context, your repo location will be relative to it.
|
||||||
|
|
||||||
|
|
||||||
|
## Building the Docker Image Using PAT & Clone
|
||||||
|
|
||||||
|
This image clones the keydb-internal repo, hence a GHE PAT token or SSH access is needed. See more on [obtaining GHE PAT](https://wiki.sc-corp.net/display/TOOL/Using+the+GHE+API#UsingtheGHEAPI-Step1:PersonalTokens). It is not secure to pass tokens/credentials as build-args, env variables, or COPYing then deleting, so we use secrets. This option is only available with the [Docker BuildKit](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information)so the docker build kit must be enabled via `DOCKER_BUILDKIT=1`, or permanently by appending `"features": { "buildkit": true }` to /etc/docker/daemon.json.
|
||||||
|
|
||||||
|
#### To Build:
|
||||||
|
|
||||||
|
Run the command below updating your info as follows:
|
||||||
|
* Pass in the branch name as a build argument
|
||||||
|
* Tag your image to whatever you want to use
|
||||||
|
* Add your PAT info to GHE_PersonalAccessToken.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
cd docker_PAT_build
|
||||||
|
DOCKER_BUILDKIT=1 docker build --no-cache --build-arg BRANCH=keydbpro --secret id=PAT,src=GHE_PersonalAccessToken.txt . -t myImageName:imageTag
|
||||||
|
```
|
||||||
|
|
||||||
|
For a detailed conventional build view pass `--progress=plain` while building. Note that `--no-cache` must be used to ensure your credentials are pulled in as they are not cached.
|
||||||
|
|
||||||
|
#### Troubleshooting
|
||||||
|
|
||||||
|
If you are building on macOS or with docker frontend you may need to append the following line to the top of the Dockerfile:
|
||||||
|
|
||||||
|
```
|
||||||
|
# syntax=docker/dockerfile:1.3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using The Image
|
||||||
|
|
||||||
|
#### Bind port
|
||||||
|
|
||||||
|
Bind the container to the node/machine by passing the parameter `-p 6379:6379` when you run the docker container
|
||||||
|
|
||||||
|
#### Configuration file
|
||||||
|
|
||||||
|
By default KeyDB launches by specifiying its internal keydb.conf file at `/etc/keydb/keydb.conf`. If you would like to use your own config file you can link to the config file with `-v /path-to-config-file/keydb.conf:/etc/keydb/keydb.conf` then run the container whose default command is `keydb-server /etc/keydb/keydb.conf`
|
||||||
|
|
||||||
|
Alternatively specify any config file location, by specifying the location following the binary to override default: `docker run ThisDockerImage keydb-server /path/to/my/config-file/`. You can also just append parameters to default image with `docker run ThisDockerImage keydb-server /etc/keydb/keydb.conf --dir /data --server-threads 4`.
|
||||||
|
|
||||||
|
#### Persistent storage
|
||||||
|
|
||||||
|
If persistence is enabled, data is stored in the VOLUME /data, which can be used with --volumes-from some-volume-container or -v /docker/host/dir:/data (see [docs.docker volumes](https://docs.docker.com/storage/volumes/)).
|
||||||
|
|
||||||
|
#### Connect via keydb-cli
|
||||||
|
|
||||||
|
you can grab the ip of the container with `docker inspect --format '{{ .NetworkSettings.IPAddress }}' mycontainername` then run the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -it --rm ThisDockerImage keydb-cli -h <ipaddress-from-above> -p 6379
|
||||||
|
```
|
||||||
|
|
118
docker-internal/docker_PAT_build/Dockerfile
Normal file
118
docker-internal/docker_PAT_build/Dockerfile
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
FROM ubuntu:20.04
|
||||||
|
SHELL ["/bin/bash","-c"]
|
||||||
|
RUN groupadd -r keydb && useradd -r -g keydb keydb
|
||||||
|
# use gosu for easy step-down from root: https://github.com/tianon/gosu/releases
|
||||||
|
ENV GOSU_VERSION 1.14
|
||||||
|
RUN set -eux; \
|
||||||
|
savedAptMark="$(apt-mark showmanual)"; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get install -y --no-install-recommends ca-certificates dirmngr gnupg wget; \
|
||||||
|
rm -rf /var/lib/apt/lists/*; \
|
||||||
|
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
|
||||||
|
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
|
||||||
|
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
|
||||||
|
export GNUPGHOME="$(mktemp -d)"; \
|
||||||
|
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
|
||||||
|
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
|
||||||
|
gpgconf --kill all; \
|
||||||
|
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
|
||||||
|
apt-mark auto '.*' > /dev/null; \
|
||||||
|
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
|
||||||
|
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||||
|
chmod +x /usr/local/bin/gosu; \
|
||||||
|
gosu --version; \
|
||||||
|
gosu nobody true
|
||||||
|
# build KeyDB
|
||||||
|
ARG BRANCH
|
||||||
|
RUN --mount=type=secret,id=PAT export $(cat /run/secrets/PAT | xargs); \
|
||||||
|
set -eux; \
|
||||||
|
\
|
||||||
|
savedAptMark="$(apt-mark showmanual)"; \
|
||||||
|
apt-get update; \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -qqy --no-install-recommends \
|
||||||
|
dpkg-dev \
|
||||||
|
pkg-config \
|
||||||
|
ca-certificates \
|
||||||
|
build-essential \
|
||||||
|
nasm \
|
||||||
|
autotools-dev \
|
||||||
|
autoconf \
|
||||||
|
libjemalloc-dev \
|
||||||
|
tcl \
|
||||||
|
tcl-dev \
|
||||||
|
uuid-dev \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
libbz2-dev \
|
||||||
|
libzstd-dev \
|
||||||
|
liblz4-dev \
|
||||||
|
libsnappy-dev \
|
||||||
|
libssl-dev \
|
||||||
|
git; \
|
||||||
|
cd /tmp && git clone --branch $BRANCH https://$PAT_ID:$TOKEN@github.sc-corp.net/Snapchat/keydb-internal.git --recursive; \
|
||||||
|
cd /tmp/keydb-internal; \
|
||||||
|
# disable protected mode as it relates to docker
|
||||||
|
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' ./src/config.cpp; \
|
||||||
|
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' ./src/config.cpp; \
|
||||||
|
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' ./src/config.cpp; \
|
||||||
|
make -j$(nproc) BUILD_TLS=yes NO_LICENSE_CHECK=yes; \
|
||||||
|
cd src; \
|
||||||
|
strip keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel; \
|
||||||
|
mv keydb-server keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel /usr/local/bin/; \
|
||||||
|
# clean up unused dependencies
|
||||||
|
echo $savedAptMark; \
|
||||||
|
apt-mark auto '.*' > /dev/null; \
|
||||||
|
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
|
||||||
|
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||||
|
| awk '/=>/ { print $(NF-1) }' \
|
||||||
|
| sed 's:.*/::' \
|
||||||
|
| sort -u \
|
||||||
|
| xargs -r dpkg-query --search \
|
||||||
|
| cut -d: -f1 \
|
||||||
|
| sort -u \
|
||||||
|
| xargs -r apt-mark manual \
|
||||||
|
; \
|
||||||
|
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||||
|
rm -rf /var/lib/apt/lists/*; \
|
||||||
|
# create working directories and organize files
|
||||||
|
RUN \
|
||||||
|
mkdir /data && chown keydb:keydb /data; \
|
||||||
|
mkdir /flash && chown keydb:keydb /flash; \
|
||||||
|
mkdir -p /etc/keydb; \
|
||||||
|
cp /tmp/keydb-internal/keydb.conf /etc/keydb/; \
|
||||||
|
sed -i 's/^\(daemonize .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(dir .*\)$/# \1\ndir \/data/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(logfile .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/protected-mode yes/protected-mode no/g' /etc/keydb/keydb.conf; \
|
||||||
|
sed -i 's/^\(bind .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||||
|
ln -s keydb-cli redis-cli; \
|
||||||
|
cd /etc/keydb; \
|
||||||
|
ln -s keydb.conf redis.conf; \
|
||||||
|
rm -rf /tmp/*
|
||||||
|
# generate entrypoint script
|
||||||
|
RUN set -eux; \
|
||||||
|
echo '#!/bin/sh' > /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'set -e' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# first arg is '-f' or '--some-option'" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# or first arg is `something.conf`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo ' set -- keydb-server "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo "# allow the container to be started with `--user`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'if [ "$1" = "keydb-server" -a "$(id -u)" = "0" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo " find . \! -user keydb -exec chown keydb '{}' +" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo ' exec gosu keydb "$0" "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
echo 'exec "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||||
|
chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
# set remaining image properties
|
||||||
|
VOLUME /data
|
||||||
|
WORKDIR /data
|
||||||
|
ENV KEYDB_PRO_DIRECTORY=/usr/local/bin/
|
||||||
|
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||||
|
EXPOSE 6379
|
||||||
|
CMD ["keydb-server","/etc/keydb/keydb.conf"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
PAT_ID=
|
||||||
|
TOKEN=
|
Loading…
x
Reference in New Issue
Block a user