diff --git a/.env b/.env new file mode 100644 index 0000000..a80f794 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +GLOBAL_CONFIG_URL=https://ton.org/global.config.json +MYTONCTRL_VERSION=master +TELEMETRY=true +IGNORE_MINIMAL_REQS=false +MODE=validator +DUMP=false diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..7215331 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,57 @@ +name: Docker Ubuntu 22.04 image + +on: + workflow_dispatch: + push: + branches: + - 'main' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-22.04 + steps: + - name: Check out repository + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get next tag + id: tag + run: | + git fetch --all --tags + git tag -l + NEW_TAG=v$(date +'%Y.%m') + FOUND=$(git tag -l | grep $NEW_TAG | wc -l) + if [ $FOUND -eq 0 ]; then + echo "TAG=$NEW_TAG" >> $GITHUB_OUTPUT + else + echo "TAG=$NEW_TAG-$FOUND" >> $GITHUB_OUTPUT + fi + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64 + push: true + context: ./ + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.TAG }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c7a3819 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/local-build +/private +/state +Dockerfile.local +.idea diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7040ae8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +FROM ghcr.io/ton-blockchain/ton:latest +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y lsb-release software-properties-common gnupg gperf make cmake libblas-dev wget gcc openssl libgsl-dev zlib1g-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev liblz4-dev python3-dev python3-pip sudo git fio iproute2 plzip pv curl libjemalloc-dev ninja-build rocksdb-tools \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /var/ton-work/db/static /var/ton-work/db/import /var/ton-work/db/keyring /usr/bin/ton /usr/bin/ton/lite-client /usr/bin/ton/validator-engine /usr/bin/ton/validator-engine-console /usr/bin/ton/utils /usr/src/ton/crypto/fift/lib/ /usr/src/ton/crypto/smartcont /usr/bin/ton/crypto \ + && cd /usr/src/ton && git init && git remote add origin https://github.com/ton-blockchain/ton.git + +RUN wget https://apt.llvm.org/llvm.sh && \ + chmod +x llvm.sh && \ + ./llvm.sh 16 all && \ + ln /usr/bin/clang-16 /usr/bin/clang && \ + ln /usr/bin/clang++-16 /usr/bin/clang++ + +ARG MYTONCTRL_VERSION=master +ARG TELEMETRY=false +ARG DUMP=false +ARG MODE=validator +ARG IGNORE_MINIMAL_REQS=true +ARG GLOBAL_CONFIG_URL=https://ton.org/global.config.json + +RUN cp /usr/local/bin/lite-client /usr/bin/ton/lite-client/ \ + && cp /usr/local/bin/validator-engine /usr/bin/ton/validator-engine \ + && cp /usr/local/bin/validator-engine-console /usr/bin/ton/validator-engine-console/ \ + && cp /usr/local/bin/generate-random-id /usr/bin/ton/utils/ \ + && cp /usr/local/bin/fift /usr/bin/ton/crypto/ \ + && cp /usr/local/bin/func /usr/bin/ton/crypto/ \ + && cp /usr/lib/fift/* /usr/src/ton/crypto/fift/lib/ \ + && cp -r /usr/share/ton/smartcont/* /usr/src/ton/crypto/smartcont/ + +RUN wget -nv https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py -O /usr/bin/systemctl \ + && chmod +x /usr/bin/systemctl \ + && wget https://raw.githubusercontent.com/ton-blockchain/mytonctrl/${MYTONCTRL_VERSION}/scripts/install.sh -O /tmp/install.sh \ + && wget -nv ${GLOBAL_CONFIG_URL} -O /usr/bin/ton/global.config.json \ + && if [ "$TELEMETRY" = false ]; then export TELEMETRY="-t"; else export TELEMETRY=""; fi && if [ "$IGNORE_MINIMAL_REQS" = true ]; then export IGNORE_MINIMAL_REQS="-i"; else export IGNORE_MINIMAL_REQS=""; fi \ + && /bin/bash /tmp/install.sh ${TELEMETRY} ${IGNORE_MINIMAL_REQS} -b ${MYTONCTRL_VERSION} -m ${MODE} \ + && ln -sf /proc/$$/fd/1 /usr/local/bin/mytoncore/mytoncore.log \ + && ln -sf /proc/$$/fd/1 /var/log/syslog \ + && sed -i 's/--logname \/var\/ton-work\/log//g; s/--verbosity 1/--verbosity 3/g' /etc/systemd/system/validator.service \ + && sed -i 's/\[Service\]/\[Service\]\nStandardOutput=null\nStandardError=syslog/' /etc/systemd/system/validator.service \ + && sed -i 's/\[Service\]/\[Service\]\nStandardOutput=null\nStandardError=syslog/' /etc/systemd/system/mytoncore.service \ + && rm -rf /var/lib/apt/lists/* && rm -rf /root/.cache/pip VOLUME ["/var/ton-work", "/usr/local/bin/mytoncore"] + +COPY --chmod=755 scripts/entrypoint.sh/ /scripts/entrypoint.sh + +ENTRYPOINT ["/scripts/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 8ddb4e5..01f2a92 100644 --- a/README.md +++ b/README.md @@ -1 +1,63 @@ -# ton-docker-ctrl \ No newline at end of file +# ton-docker-ctrl + +Tested operating systems: +* Ubuntu 20.04 +* Ubuntu 22.04 +* Ubuntu 24.04 +* Debian 11 +* Debian 12 + +## Prerequisites +To run, you need docker-ce, docker-buildx-plugin, docker-compose-plugin: + +* [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) +* [Install Docker Engine on Debian](https://docs.docker.com/engine/install/debian/) + +Build environment variables (are configured in the .env file): + +* **GLOBAL_CONFIG_URL** - URL of the TON blockchain configuration (default: [Mainnet](https://ton.org/global.config.json)) +* **MYTONCTRL_VERSION** - MyTonCtrl build branch (default **master**) +* **TELEMETRY** - Enable/Disable telemetry (default **true**) +* **IGNORE_MINIMAL_REQS** - Ignore hardware requirements (default **true**) +* **MODE** - Install MyTonCtrl with specified mode (validator or liteserver, default **validator**) +* **DUMP** - Use pre-packaged dump. Reduces duration of initial synchronization, but it takes time to download the dump. You can view the download status in the logs `docker compose logs -f`. (default **false**). + +## Run MyTonCtrl v2 in docker: +* Run `docker run -d --name ton-node -v /mnt/data/ton-work1:/var/ton-work -it ghcr.io/ton-blockchain/ton-docker-ctrl:latest` + +## Build Docker image from sources and run MyTonCtrl v2: + +* Clone: `git clone https://github.com/ton-blockchain/ton-docker-ctrl.git && cd ./ton-docker-ctrl` +* Run: `docker compose up --build -d` +* Connect `docker compose exec -it node bash -c "mytonctrl"` + +## Upgrade MyTonCtrl docker image from repository: +* Pull docker image: `docker pull docker pull ghcr.io/ton-blockchain/ton-docker-ctrl:latest` + +## Upgrade MyTonCtrl docker images from sources: + +* Build new image: `docker compose build ton-node` +* Run new version: `docker compose up -d` + +## Migrate non-Docker fullnode or validator to a dockerized MyTonCtrl v2 + +Specify paths to TON binaries and sources, as well as to TON work directory, but most importantly to MyTonCtrl settings and wallets. + +```bash +docker run -d --name ton-node --restart always \ +-v /mnt/data/ton-work:/var/ton-work \ +-v /usr/bin/ton:/usr/bin/ton \ +-v /usr/src/ton:/usr/src/ton \ +-v /home//.local/share:/usr/local/bin \ +ghcr.io/ton-blockchain/ton-docker-ctrl:latest +``` + +Read the logs +```bash +docker logs ton-node +``` + +Get inside the container and run MyTonCtrl +```bash +docker exec -ti ton-node bash +``` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ccd4ee7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: "3.3" +services: + ton-node: + image: mytonctrl:2 + build: + context: . + dockerfile: Dockerfile + args: + GLOBAL_CONFIG_URL: ${GLOBAL_CONFIG_URL} + MYTONCTRL_VERSION: ${MYTONCTRL_VERSION} + TELEMETRY: ${TELEMETRY} + IGNORE_MINIMAL_REQS: ${IGNORE_MINIMAL_REQS} + MODE: ${MODE} + restart: always + tty: true + volumes: + - ton:/var/ton-work + - mytoncore:/usr/local/bin/mytoncore + network_mode: host + environment: + GLOBAL_CONFIG_URL: ${GLOBAL_CONFIG_URL} + IGNORE_MINIMAL_REQS: ${IGNORE_MINIMAL_REQS} + DUMP: ${DUMP} + logging: + driver: "json-file" + options: + max-size: 100m + max-file: "3" +volumes: + ton: + mytoncore: diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100644 index 0000000..4b38aad --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -e + +# check machine configuration +echo -e "Checking system requirements" + +cpus=$(nproc) +memory=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}') +CPUS=$(expr $(nproc) - 1) +GLOBAL_CONFIG_URL=${GLOBAL_CONFIG_URL:-https://ton.org/testnet-global.config.json} + +echo "This machine has ${cpus} CPUs and ${memory}KB of Memory" +if [ "$IGNORE_MINIMAL_REQS" != true ] && ([ "${cpus}" -lt 16 ] || [ "${memory}" -lt 64000000 ]); then + echo "Insufficient resources. Requires a minimum of 16 processors and 64Gb RAM." + exit 1 +fi + +echo "Setting global config..." +wget ${GLOBAL_CONFIG_URL} -O /usr/bin/ton/global.config.json + +URL="https://dump.ton.org" +if [ ! -f /var/ton-work/db/dump_done ]; then + if [ "$DUMP" == true ] ; then + if [[ "$GLOBAL_CONFIG_URL" == *"testnet"* ]]; then + DUMP_NAME="latest_testnet" + else + DUMP_NAME="latest" + fi + echo "Start DownloadDump $DUMP_NAME" + DUMPSIZE=$(curl --silent ${URL}/dumps/${DUMP_NAME}.tar.size.archive.txt) + DISKSPACE=$(df -B1 --output=avail /var/ton-work | tail -n1) + NEEDSPACE=$(expr 3 '*' "$DUMPSIZE") + if [ "$DISKSPACE" -gt "$NEEDSPACE" ]; then + (curl --silent ${URL}/dumps/${DUMP_NAME}.tar.lz | pv --force | plzip -d -n${CPUS} | tar -xC /var/ton-work/db) 2>&1 | stdbuf -o0 tr '\r' '\n' + mkdir -p /var/ton-work/db/static /var/ton-work/db/import + chown -R validator:validator /var/ton-work/db + touch /var/ton-work/db/dump_done + echo "Done DownloadDump $DUMP_NAME" + else + echo "A minimum of $NEEDSPACE bytes of free disk space is required" + exit 1 + fi + fi +fi + +echo "Setting processor cores" +sed -i -e "s/--threads\s[[:digit:]]\+/--threads ${CPUS}/g" /etc/systemd/system/validator.service + +echo "Starting validator" +systemctl start validator +echo "Starting mytoncore" +systemctl start mytoncore + +echo "Service started!" +exec /usr/bin/systemctl