Skip to content

Commit

Permalink
docker: Mover Docker images to Alpine
Browse files Browse the repository at this point in the history
  • Loading branch information
lutter committed May 26, 2020
1 parent b449223 commit e4bc51f
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 47 deletions.
76 changes: 38 additions & 38 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
FROM rust:latest
# Full build with debuginfo for graph-node
FROM rust:alpine as graph-node-bld

# Replace this with the graph-node branch you want to build the image from;
# Note: Docker Hub substitutes this automatically using our hooks/post_checkout script.
ENV SOURCE_BRANCH "master"

# Install clang (required for dependencies)
RUN apt-get update \
&& apt-get install -y clang libclang-dev

# Clone and build the graph-node repository
RUN git clone https://github.com/graphprotocol/graph-node \
&& cd graph-node \
&& git checkout "$SOURCE_BRANCH" \
&& cargo install --locked --path node \
&& cd .. \
&& rm -rf graph-node

# Clone and install wait-for-it
RUN git clone https://github.com/vishnubob/wait-for-it \
&& cp wait-for-it/wait-for-it.sh /usr/local/bin \
&& chmod +x /usr/local/bin/wait-for-it.sh \
&& rm -rf wait-for-it
# See https://github.com/rust-lang/cargo/issues/7563 for why we use -crt-static
# in the RUSTFLAGS
RUN apk update \
&& apk add musl-dev openssl-dev postgresql-dev git \
&& git clone https://github.com/lutter/graph-node /graph-node \
&& cd /graph-node \
&& git checkout "$SOURCE_BRANCH" \
&& RUSTFLAGS="-g -C target-feature=-crt-static" cargo install --locked --path node \
&& cargo clean \
&& objcopy --only-keep-debug /usr/local/cargo/bin/graph-node /usr/local/cargo/bin/graph-node.debug \
&& strip -g /usr/local/cargo/bin/graph-node \
&& cd /usr/local/cargo/bin \
&& objcopy --add-gnu-debuglink=graph-node.debug graph-node

# The graph-node runtime image with only the executable
FROM alpine:latest as graph-node-run
ENV RUST_LOG ""
ENV GRAPH_LOG ""
ENV EARLY_LOG_CHUNK_SIZE ""
Expand All @@ -33,34 +32,35 @@ ENV postgres_user ""
ENV postgres_pass ""
ENV postgres_db ""
ENV ipfs ""
# The etherum network(s) to connect to. Set this to a space-separated
# list of the networks where each entry has the form NAME:URL
ENV ethereum ""

# HTTP port
EXPOSE 8000

# WebSocket port
EXPOSE 8001

# JSON-RPC port
EXPOSE 8020

# Start everything on startup
ADD start-node /usr/local/bin
RUN apk add libgcc libssl1.1 libcrypto1.1 postgresql-libs bash

ADD wait_for start /usr/local/bin
COPY --from=graph-node-bld /usr/local/cargo/bin/graph-node /usr/local/bin

# The query-node image
FROM graph-node-run as query-node
CMD start query-node

# The index-node image
FROM graph-node-run as index-node
CMD start index-node

RUN apt-get install gawk
# The combined-node image used for the public docker compose setup
FROM graph-node-run as graph-node
CMD start combined-node

# Wait for IPFS and Postgres to start up.
#
# The awk commands below take the IPFS and Postgres and extract
# hostname:port from them. The IPFS port defaults to 443 for HTTPS
# and 80 for HTTP. The Postgres port defaults to 5432.
CMD wait-for-it.sh \
$(echo $ipfs | \
gawk 'match($0, /^([a-z]+:\/\/)?([^\/:]+)(:([0-9]+))?.*$/, m) { print m[2]":"(m[4] ? m[4] : (m[1] == "https://" ? 443 : 80)) }') \
-t 120 \
&& wait-for-it.sh \
$(echo $postgres_host | \
gawk 'match($0, /^([a-z]+:\/\/)?([^\/:]+)(:([0-9]+))?.*$/, m) { print m[2]":"(m[4] ? m[4] : 5432) }') \
-t 120 \
&& sleep 5 \
&& start-node
# Debug image to access core dumps
FROM graph-node-bld as graph-node-dbg
RUN apk add gdb
ADD debug /usr/local/bin
16 changes: 16 additions & 0 deletions docker/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#! /bin/bash

# This file is only here to ease testing/development. The commands in this
# file should ultimately be moved to the corresponding commands for Cloud Build
# in the cloudbuild.*.yaml files

type -p podman > /dev/null && docker=podman || docker=docker

for stage in graph-node-bld \
graph-node-run \
query-node \
index-node \
graph-node-dbg
do
$docker build -t $stage --target $stage .
done
9 changes: 9 additions & 0 deletions docker/debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#! /bin/bash

if [ -f "$1" ]
then
exec gdb -c "$1" /usr/local/bin/graph-node
else
echo "usage: debug <core-file>"
exit 1
fi
91 changes: 91 additions & 0 deletions docker/start
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/bin/bash

save_coredumps() {
core_dir=/var/lib/graph/cores
datestamp=$(date +"%Y-%m-%dT%H:%M:%S")
ls /core.* >& /dev/null && have_cores=yes || have_cores=no
if [ -d "$core_dir" -a "$have_cores" = yes ]
then
exec >> "$core_dir"/messages 2>&1
echo "${HOSTNAME##*-} Saving core dump on ${HOSTNAME} at ${datestamp}"

dst="$core_dir/$datestamp-${HOSTNAME}"
mkdir "$dst"
cp /usr/local/cargo/bin/graph-node "$dst"
cp /proc/loadavg "$dst"
dmesg -e > "$dst/dmesg"
# Capture environment variables, but filter out passwords
env | sort | sed -r -e 's/^(postgres_pass|ELASTICSEARCH_PASSWORD)=.*$/\1=REDACTED/' > "$dst/env"

for f in /core.*
do
echo "${HOSTNAME##*-} Found core dump $f"
mv "$f" "$dst"
done
echo "${HOSTNAME##*-} Saving done"
fi
}

start_query_node() {
export DISABLE_BLOCK_INGESTOR=true
graph-node \
--postgres-url "$postgres_url" \
--ethereum-rpc $ethereum \
--ipfs "$ipfs"
}

start_index_node() {
POD_INDEX=${pod_name##*-}

# FIXME: Users should just pass this in or something
# Only enable block ingestion for `index-node-<network>-0`;
# disable it for all tracing and production nodes
if [[ ${pod_name} != *"block-ingestor"* ]]; then
export DISABLE_BLOCK_INGESTOR=true
fi

if [ -z $MULTIPLE_ETHEREUM_NETWORKS ]; then
graph-node \
--node-id "${pod_name//-/_}" \
--postgres-url "$postgres_url" \
--ethereum-rpc "$ETHEREUM_NETWORK" \
--ipfs "$ipfs"
else
graph-node \
--node-id "${pod_name//-/_}" \
--postgres-url "$postgres_url" \
--ethereum-rpc $ethereum \
--ipfs "$ipfs"
fi
}

start_combined_node() {
graph-node \
--postgres-url "$postgres_url" \
--ethereum-rpc $ethereum \
--ipfs "$ipfs"
}

postgres_url="postgresql://$postgres_user:$postgres_pass@$postgres_host/$postgres_db"

wait_for "$ipfs" -t 120
wait_for "$postgres_host:5432" -t 120
sleep 5

trap save_coredumps EXIT

case "$1" in
query-node)
start_query_node
;;
index-node)
start_index_node
;;
combined-node)
start_combined_node
;;
*)
echo "Unknown mode for start-node: $1"
echo "usage: start-node (query-node|index-node)"
exit 1
esac
9 changes: 0 additions & 9 deletions docker/start-node

This file was deleted.

83 changes: 83 additions & 0 deletions docker/wait_for
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/sh

# POSIX compatible clone of wait-for-it.sh
# This copy is from https://github.com/eficode/wait-for/commits/master
# at commit 8d9b4446

TIMEOUT=15
QUIET=0

echoerr() {
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}

usage() {
exitcode="$1"
cat << USAGE >&2
Usage:
$cmdname host:port [-t timeout] [-- command args]
-q | --quiet Do not output any status messages
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit "$exitcode"
}

wait_for() {
for i in `seq $TIMEOUT` ; do
nc -z "$HOST" "$PORT" > /dev/null 2>&1

result=$?
if [ $result -eq 0 ] ; then
if [ $# -gt 0 ] ; then
exec "$@"
fi
exit 0
fi
sleep 1
done
echo "Operation timed out" >&2
exit 1
}

while [ $# -gt 0 ]
do
case "$1" in
*:* )
HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-t)
TIMEOUT="$2"
if [ "$TIMEOUT" = "" ]; then break; fi
shift 2
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
break
;;
--help)
usage 0
;;
*)
echoerr "Unknown argument: $1"
usage 1
;;
esac
done

if [ "$HOST" = "" -o "$PORT" = "" ]; then
echoerr "Error: you need to provide a host and port to test."
usage 2
fi

wait_for "$@"

0 comments on commit e4bc51f

Please sign in to comment.