diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..28832631b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +* +!scripts/docker diff --git a/Makefile b/Makefile index b17964ebc..4c764411e 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ RPMBUILD=$(HOME)/rpmbuild DEBBUILD=$(HOME)/debbuild SHELL := bash -.PHONY: all help libs exe race trace-pointer debug debug-kill test test-go test-api test-api-attach linux_static deb_init deb_build deb debpub_dev debpub_prod rpm_init rpm_build rpm rpmpub_dev rpmpub_prod clean distclean +.PHONY: all help libs exe race trace-pointer debug debug-kill test test-go test-api test-api-attach linux_static deb_init deb_build deb debpub_dev debpub_prod rpm_init rpm_build rpm rpmpub_dev rpmpub_prod clean distclean docker all: libs bash ./scripts/go_executable_build.sh -S @@ -157,3 +157,6 @@ go-vet: go-test: go test -vet=all -race ./... + +docker: + docker build --pull -t harmonyone/$(PKGNAME):latest -f scripts/docker/Dockerfile . diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile index fee63a061..6e13cd499 100644 --- a/scripts/docker/Dockerfile +++ b/scripts/docker/Dockerfile @@ -1,31 +1,67 @@ -FROM alpine +ARG GOPATH_DEFAULT=/root/go +ARG SRC_PATH=src/github.com/harmony-one -RUN apk add --no-cache bash libstdc++ gmp-dev libc6-compat bind-tools jq && ln -s libcrypto.so.1.1 /lib/libcrypto.so.10 +FROM golang:1.18-bullseye as builder -# default base port, rpc port and rest port -EXPOSE 9000/tcp 9500/tcp 9800/tcp 6000/tcp +ARG GOPATH_DEFAULT +ARG SRC_PATH + +ENV GOPATH=${GOPATH_DEFAULT} +ENV GO111MODULE=on +ENV HMY_PATH=${GOPATH}/${SRC_PATH} + +ENV PACKAGES libgmp-dev libssl-dev curl git \ + psmisc dnsutils jq make gcc g++ bash tig tree + +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -y $PACKAGES --no-install-recommends + +WORKDIR ${HMY_PATH} + +RUN git clone https://github.com/harmony-one/harmony.git harmony \ + && git clone https://github.com/harmony-one/bls.git bls \ + && git clone https://github.com/harmony-one/mcl.git mcl \ + && git clone https://github.com/harmony-one/go-sdk.git go-sdk + +WORKDIR ${HMY_PATH}/harmony +RUN make linux_static -VOLUME ["/harmony/harmony_db_0","/harmony/harmony_db_1","/harmony/harmony_db_2","/harmony/harmony_db_3","/harmony/log","/harmony/.hmy"] +# Pull harmony into a second stage deploy alpine container +FROM alpine:3.16.0 -# Default BN for S3/mainnet -ENV NODE_BN_MNET "/ip4/100.26.90.187/tcp/9874/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv,/ip4/54.213.43.194/tcp/9874/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9,/ip4/13.113.101.219/tcp/12019/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX,/ip4/99.81.170.167/tcp/12019/p2p/QmRVbTpEYup8dSaURZfF6ByrMTSKa4UyUzJhSjahFzRqNj" +ARG GOPATH_DEFAULT +ARG SRC_PATH -# Long Running Test Net -ENV NODE_BN_LRTN "/ip4/54.213.43.194/tcp/9868/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9,/ip4/100.26.90.187/tcp/9868/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv,/ip4/13.113.101.219/tcp/12018/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX" +ARG HARMONY_USER=harmony +ARG HARMONY_USER_UID=1000 +ARG HARMONY_USER_GID=1000 -# Open Staking Test Net -ENV NODE_BN_OSTN "/ip4/54.86.126.90/tcp/9880/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv,/ip4/52.40.84.2/tcp/9880/p2p/QmbPVwrqWsTYXq1RxGWcxx9SWaTUCfoo1wA6wmdbduWe29" +ENV HARMONY_HOME=/harmony +ENV HOME=${HARMONY_HOME} -ENV NODE_PORT "9000" -ENV NODE_BLSKEY "" -ENV NODE_BLSPASS "" -ENV NODE_DNS_ZONE "t.hmny.io" -ENV NODE_RPC "true" -ENV NODE_BLACKLIST "" -ENV NODE_NETWORK_TYPE "mainnet" +RUN apk add --no-cache bash~=5.1.16-r2 bind-tools~=9.16.29-r0 tini~=0.19.0 curl==7.83.1-r2 sed~=4.8-r0 \ + && rm -rf /var/cache/apk/* \ + && addgroup -g ${HARMONY_USER_GID} ${HARMONY_USER} \ + && adduser -u ${HARMONY_USER_UID} -G ${HARMONY_USER} --shell /sbin/nologin --no-create-home -D ${HARMONY_USER} \ + && addgroup ${HARMONY_USER} tty \ + && sed -i -e "s/bin\/sh/bin\/bash/" /etc/passwd -ENTRYPOINT ["/bin/run"] -WORKDIR /harmony +RUN echo "[ ! -z \"\$TERM\" -a -r /etc/motd ] && cat /etc/motd" >> /etc/bash/bashrc + +WORKDIR ${HARMONY_HOME} + +COPY --from=builder ${GOPATH_DEFAULT}/${SRC_PATH}/harmony/bin/harmony /usr/local/bin/ + +RUN chmod +x /usr/local/bin/harmony \ + && mkdir -p /data \ + && chown -R ${HARMONY_USER_UID}:${HARMONY_USER_GID} ${HARMONY_HOME} /data + +VOLUME /data + +USER ${HARMONY_USER_UID}:${HARMONY_USER_GID} + +# default base port, rpc port and rest port +EXPOSE 9000/tcp 9500/tcp 9800/tcp 6000/tcp -COPY run /bin/run -COPY harmony /bin/ +ENTRYPOINT ["tini", "--"] +CMD ["harmony", "-c", "harmony.conf"] diff --git a/scripts/docker/README.md b/scripts/docker/README.md new file mode 100644 index 000000000..1aab228c3 --- /dev/null +++ b/scripts/docker/README.md @@ -0,0 +1,70 @@ +## Docker Image + +Included in this repo is a Dockerfile that you can launch harmony node for trying it out. Docker images are available on `harmonyone/harmony`. + +You can build the docker image with the following commands: +```bash +make docker +``` + +If your build machine has an ARM-based chip, like Apple silicon (M1), the image is built for `linux/arm64` by default. To build for `x86_64`, apply the --platform arg: + +```bash +docker build --platform linux/amd64 -t harmonyone/harmony -f Dockerfile . +``` + +Before start the docker, dump the default config `harmony.conf` by running: + +for testnet +```bash +docker run -v $(pwd)/config:/harmony --rm --name harmony harmonyone/harmony harmony config dump --network testnet harmony.conf +``` +for mainnet +```bash +docker run -v $(pwd)/config:/harmony --rm --name harmony harmonyone/harmony harmony config dump harmony.conf +``` + +make your customization. `harmony.conf` should be mounted into default `HOME` directory `/harmony` inside the container. Assume `harmony.conf`, `blskeys` and `hmykey` are under `./config` in your current working directory, you can start your docker container with the following command: +```bash +docker run -v $(pwd)/config:/harmony --rm --name harmony -it harmonyone/harmony +``` + +If you need to open another shell, just do: +```bash +docker exec -it harmonyone/harmony /bin/bash +``` + +We also provide a `docker-compose` file for local testing + +To use the container in kubernetes, you can use a configmap or secret to mount the `harmony.conf` into the container +```bash +containers: + - name: harmony + image: harmonyone/harmony + ports: + - name: p2p + containerPort: 9000 + - name: rpc + containerPort: 9500 + - name: ws + containerPort: 9800 + volumeMounts: + - name: config + mountPath: /harmony/harmony.conf + volumes: + - name: config + configMap: + name: cm-harmony-config + +``` + +Your configmap `cm-harmony-config` should look like this: +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm-harmony-config +data: + harmony.conf: | + ... +``` \ No newline at end of file diff --git a/scripts/docker/docker-compose.yaml b/scripts/docker/docker-compose.yaml new file mode 100644 index 000000000..dd6aefca1 --- /dev/null +++ b/scripts/docker/docker-compose.yaml @@ -0,0 +1,45 @@ +version: '3.6' +services: + init: + image: alpine + command: + - /bin/sh + - -c + - | + chown -R 1000:1000 /data + echo "done grant data directory permission" + volumes: + - data:/data + + harmony: + build: + context: ../../ + dockerfile: ./scripts/docker/Dockerfile + restart: unless-stopped + ports: + - 9500:9500 + - 9000:9000 + - 9700:9700 + healthcheck: + test: netstat -tunlp | grep 9500 > /dev/null; if [ 0 != $$? ]; then exit 1; else exit 0; fi; + interval: 5s + retries: 5 + start_period: 10s + timeout: 3s + volumes: + - data:/data + - config:/harmony + +volumes: + config: + driver: local + driver_opts: + type: 'none' + o: 'bind' + device: '/tmp/harmony/config/testnet' + data: + driver: local + driver_opts: + type: 'none' + o: 'bind' + device: '/tmp/harmony/data/testnet'