Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docker artifact. #333

Merged
merged 2 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# dockerized libbitcoin

## bitcoin server

A linux image can be generated with the script below. Currently, this is only tested against the `version3` branch with or without the `v3.8.0` tag.

### linux

The following outlines usage of the `bs-linux` artifacts.
It is of note that the generated image includes a `startup.sh` script which conditionally initializes the blockchain database if not found.

#### Initialization

The following populates a provided image build directory:

```
./bs-linux.sh --build-dir=<image build dir> --source=<gsl xml source> --init-only
```

The reader then needs to edit the generated `bs-linux.env` to provide storage paths for volume mounting.
Additionally, the `STORAGE_BITCOIN_CONF` path should contain a `bs.cfg` containing a `directory` field for `[database]` which has some depth from the volume mount point, due to `bs` implementation attempts to create the blockchain containing directory.

#### Image construction

The image construction can then continue via an other invocatio with the following parameters:

```
./bs-linux.sh --build-dir=<image build dir> --source=<gsl xml source> --build-only
```

#### Container management

The file `bs-linux.yml` is provided in the image build directory in order to allow `docker compose` to control container construction and destruction.
The reader is free to translate this file and the `bs-linux.env` into `docker` commands derived from the declative `yaml`.
The timeout parameter should be noted: `bs` has been known to take an extended period of time to write memory to disk and `SIGKILL` will likely corrupt the database.

##### Instantiating container
```
docker compose --env-file bs-linux.env --file bs-linux.yml up -t 3600 -d
```

##### Terminating container
```
docker compose --env-file bs-linux.env --file bs-linux.yml down -t 3600 -v
```
72 changes: 72 additions & 0 deletions docker/bs-linux-startup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

set -ex

SCRIPT_IDENTITY=$(basename "$0")

display_message()
{
printf "%s\n" "$@"
}

display_error()
{
>&2 printf "%s\n" "$@"
}

display_help()
{
display_message "Usage: ./${SCRIPT_IDENTITY} [OPTION]..."
display_message "Docker instance startup script."
display_message "Script options:"
display_message " --unconditional-init Force database reset."
display_message ""
}

fatal_error()
{
display_error "$@"
display_error ""
display_help
exit 1
}

dispatch_help()
{
if [[ ${DISPLAY_HELP} ]]; then
display_help
exit 0
fi
}

parse_command_line_options()
{
for OPTION in "$@"; do
case ${OPTION} in
# Specific
(--unconditional-init) INIT_UNCONDITIONAL="yes";;

# Standard
(--help) DISPLAY_HELP="yes";;
esac
done
}

initialize()
{
if [[ -z "$( ls -A blockchain )" ]]; then
./bs -c conf/bs.cfg --initchain
elif [[ $INIT_UNCONDITIONAL ]]; then
./bs -c conf/bs.cfg --initchain
fi
}

execute_service()
{
./bs -c conf/bs.cfg
}

parse_command_line_options "$@"
dispatch_help
initialize
execute_service
13 changes: 9 additions & 4 deletions docker/bs.Dockerfile → docker/bs-linux.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ RUN /build/developer_setup.sh \

FROM alpine:latest AS runtime

COPY --from=build /build/prefix/bin/bs /bitcoin
ENV BUILD_DEPS="build-base linux-headers gcc make autoconf automake libtool pkgconf git wget bash"

RUN apk update && \
apk add --update ${BUILD_DEPS}

COPY --from=build /build/prefix/bin/bs /bitcoin/bs
COPY bs-linux-startup.sh /bitcoin/startup.sh
# Bitcoin P2P
EXPOSE 8333/tcp
EXPOSE 8333/udp
Expand All @@ -52,6 +57,6 @@ EXPOSE 9093/tcp
EXPOSE 9084/tcp
EXPOSE 9094/tcp

VOLUME ["/bitcoin/data", "/bitcoin/conf"]
ENTRYPOINT ["/bitcoin/bs"]
CMD ["-c", "/bitcoin/conf/bs.cfg", "-i", "/bitcoin/data"]
WORKDIR /bitcoin
VOLUME ["/bitcoin/blockchain", "/bitcoin/conf"]
CMD [ "/bitcoin/startup.sh" ]
4 changes: 4 additions & 0 deletions docker/bs-linux.env.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
COMPOSE_PROJECT_NAME=bitcoin
VERSION_BITCOIN_SERVER=%version%
STORAGE_BITCOIN_CONF=%SET_ME%
STORAGE_BITCOIN_DATA=%SET_ME%
202 changes: 202 additions & 0 deletions docker/bs-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#!/bin/bash

set -e

SCRIPT_IDENTITY=$(basename "$0")

display_message()
{
printf "%s\n" "$@"
}

display_error()
{
>&2 printf "%s\n" "$@"
}

fatal_error()
{
display_error "$@"
display_error ""
display_help
exit 1
}

display_help()
{
display_message "Usage: ./${SCRIPT_IDENTITY} [OPTION]..."
display_message "Manage the generation of a docker image of bitcoin-server (bs)."
display_message "Script options:"
display_message " --build-dir=<value> Directory for building docker image"
display_message " --source=<value> xml file for gsl generation."
display_message " --tag=<value> git tag to utilize with source instructions."
display_message " --build-only docker build without reinitializing build-dir."
display_message " --init-only Initialize build-dir for docker image building."
display_message ""
}

parse_command_line_options()
{
for OPTION in "$@"; do
case ${OPTION} in
# Specific
(--build-dir=*) DIR_BUILD="${OPTION#*=}";;
(--source=*) SOURCE="${OPTION#*=}";;
(--tag=*) TAG="${OPTION#*=}";;
(--build-only) BUILD_ONLY="yes";;
(--init-only) INIT_ONLY="yes";;
# Standard
(--help) DISPLAY_HELP="yes";;
esac
done
}

display_state()
{
display_message "Parameters:"
display_message " DIR_BUILD : ${DIR_BUILD}"
display_message " SOURCE : ${SOURCE}"
display_message " TAG : ${TAG}"
display_message " BUILD_ONLY : ${BUILD_ONLY}"
display_message " INIT_ONLY : ${INIT_ONLY}"
display_message "Deduced:"
display_message " DIR_BUILD_PROJ : ${DIR_BUILD_PROJ}"
display_message " VERSION : ${VERSION}"
}

dispatch_help()
{
if [[ ${DISPLAY_HELP} ]]; then
display_help
exit 0
fi
}

validate_parameterization()
{
if [ -z ${DIR_BUILD} ]; then
fatal_error " --build-dir=<value> required."
fi

if [ -z ${SOURCE} ]; then
fatal_error " --source=<value> required."
fi
}

initialize_environment()
{
# https://stackoverflow.com/questions/59895/how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script
local DIR_SCRIPT=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# initialize DIR_BUILD_PROJ
pushd "${DIR_SCRIPT}/.."
DIR_BUILD_PROJ="$(pwd)"
popd

if [ -f ${DIR_BUILD_PROJ}/${SOURCE} ]; then
SOURCE_VERSION=$(grep '<repository' ${DIR_BUILD_PROJ}/${SOURCE} | \
grep libbitcoin-server | \
sed -n s/.*version=\"//p | \
sed -n s/\".*//p)
else
fatal_error " --source=<value> must be a valid filename in the expected path."
fi

# rationalize intended version
if [ -z ${TAG} ]; then
VERSION="${SOURCE_VERSION}"
else
if [[ "${TAG}" =~ ^v.* ]]; then
VERSION=$(echo "${TAG}" | sed -n s/v//p)
else
VERSION="${TAG}"
fi
fi
}

generate_instructions()
{
display_message "Generate developer_setup.sh..."

# create developer_setup.sh
pushd ${DIR_BUILD_PROJ}
eval gsl -q -script:templates/gsl.developer_setup.sh ${SOURCE}
chmod +x output/libbitcoin-*/developer_setup.sh
popd
}

emit_compose()
{
cp ${DIR_BUILD_PROJ}/docker/bs-linux.yml ${DIR_BUILD}/bs-linux.yml
sed "s/%version%/${VERSION}/" \
${DIR_BUILD_PROJ}/docker/bs-linux.env.in > ${DIR_BUILD}/bs-linux.env
}

clean_build_directory()
{
# cleanup build directory
if [ -d ${DIR_BUILD} ]; then
display_message "Directory '${DIR_BUILD}' found, emptying..."
pushd ${DIR_BUILD}
rm -rf bs-linux-startup.sh developer_setup.sh src/
mkdir -p "${DIR_BUILD}/src"
popd
else
display_message "Directory '${DIR_BUILD}' not found, building..."
mkdir -p "${DIR_BUILD}/src"
fi
}

initialize_build_directory()
{
if [[ $BUILD_ONLY ]]; then
return 0
fi

clean_build_directory
generate_instructions

display_message "Initialize build directory contents..."
cp ${DIR_BUILD_PROJ}/output/libbitcoin-server/developer_setup.sh ${DIR_BUILD}
cp ${DIR_BUILD_PROJ}/docker/bs-linux-startup.sh ${DIR_BUILD}

pushd ${DIR_BUILD}

local BUILD_TAG_PARAM=""
if [ -z ${TAG} ]; then
BUILD_TAG_PARAM=""
else
BUILD_TAG_PARAM="--build-tag=${TAG}"
fi

./developer_setup.sh ${BUILD_TAG_PARAM} \
--build-sync-only \
--build-src-dir="${DIR_BUILD}/src" \
--build-target=all

popd

emit_compose
}

dockerize()
{
if [[ $INIT_ONLY ]]; then
return 0
fi

pushd ${DIR_BUILD}
display_message "----------------------------------------------------------------------"
display_message "docker build : libbitcoin/bitcoin-server:${VERSION}"
display_message "----------------------------------------------------------------------"
docker build -t libbitcoin/bitcoin-server:${VERSION} -f ${DIR_BUILD_PROJ}/docker/bs-linux.Dockerfile .
popd
}

parse_command_line_options "$@"
dispatch_help
validate_parameterization
initialize_environment
initialize_build_directory
display_state
dockerize
25 changes: 25 additions & 0 deletions docker/bs-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
networks:
net:

services:
bitcoin-server:
container_name: bitcoin-server
hostname: bitcoin-server
image: libbitcoin/bitcoin-server:${VERSION_BITCOIN_SERVER}
# restart: unless-stopped
ports:
- 8333:8333/tcp
- 8333:8333/udp
- 9081:9081/tcp
- 9082:9082/tcp
- 9083:9083/tcp
- 9084:9084/tcp
- 9091:9091/tcp
- 9092:9092/tcp
- 9093:9093/tcp
- 9094:9094/tcp
volumes:
- ${STORAGE_BITCOIN_DATA}:/bitcoin/blockchain
- ${STORAGE_BITCOIN_CONF}:/bitcoin/conf
networks:
- net
Loading
Loading