Skip to content

Commit

Permalink
[ECO-2117] Add local docker (#210)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt <[email protected]>
Co-authored-by: matt <[email protected]>
Co-authored-by: xbtmatt <[email protected]>
  • Loading branch information
4 people authored Aug 26, 2024
1 parent d7e8b25 commit 251f464
Show file tree
Hide file tree
Showing 13 changed files with 457 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/target
**/.env
**/node_modules
27 changes: 27 additions & 0 deletions src/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Running the emojicoin dot fun indexer with Docker

Ensure you've successfully pulled all submodule repositories required to
build the processor, otherwise you will get errors.

```shell
git submodule update --init --recursive
```

Ensure that your environment variables are set, typically with an `.env`
file that mirrors the `example.local.env` or `example.testnet.env`, depending on
which environment you're running in.

Then you can follow the simple examples below showing how to run the processor
with and without an Aptos local fullnode.

## Run the indexer processor by itself

```shell
docker compose -f compose.yaml up
```

## Run a local Aptos fullnode as well

```shell
docker compose -f compose.yaml -f compose.local.yaml up
```
63 changes: 63 additions & 0 deletions src/docker/aptos-node/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# cspell:word RUSTFLAGS

ARG GIT_REPO=https://github.com/aptos-labs/aptos-core.git
ARG GIT_TAG=aptos-cli-v4.0.0

ARG FULLNODE_BINARY=/aptos-core/target/cli/aptos

FROM rust:1-bookworm AS compile-cli
ARG GIT_REPO
ARG GIT_TAG
ARG FULLNODE_BINARY

ENV CARGO_NET_GIT_FETCH_WITH_CLI=true

RUN git clone $GIT_REPO --branch $GIT_TAG --depth 1
RUN apt-get update && apt-get install -y \
libudev-dev \
build-essential \
libclang-dev \
libpq-dev \
libssl-dev \
libdw-dev \
pkg-config \
lld \
curl \
&& rm -rf /var/lib/apt/lists/*

# Resolve outdated lockfile from upstream tag.
RUN cargo update --manifest-path /aptos-core/Cargo.toml

RUN RUSTFLAGS="--cfg tokio_unstable" cargo build \
--bin aptos \
--manifest-path /aptos-core/Cargo.toml \
--profile cli

RUN strip -s $FULLNODE_BINARY

FROM ubuntu
ARG FULLNODE_BINARY
COPY --from=compile-cli $FULLNODE_BINARY /usr/local/bin
RUN apt-get update && apt-get install -y \
libssl-dev \
git \
curl \
&& rm -rf /var/lib/apt/lists/*

ENV PATH=/usr/local/bin:$PATH

ARG EMOJICOIN_DOT_FUN_ROOT=src/move/emojicoin_dot_fun
ARG REWARDS_ROOT=src/move/rewards

WORKDIR /app

COPY $EMOJICOIN_DOT_FUN_ROOT/Move.toml emojicoin_dot_fun/
COPY $EMOJICOIN_DOT_FUN_ROOT/sources/* emojicoin_dot_fun/sources/
COPY $REWARDS_ROOT/Move.toml rewards/
COPY $REWARDS_ROOT/sources/* rewards/sources/
COPY src/docker/aptos-node/run-fullnode.sh .
COPY src/docker/aptos-node/initialize-contract.sh .
RUN chmod +x run-fullnode.sh
RUN chmod +x initialize-contract.sh

STOPSIGNAL SIGKILL
55 changes: 55 additions & 0 deletions src/docker/aptos-node/initialize-contract.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

# In simple cases like ours (where there is no account abstraction), the
# deployer of a smart contract on Aptos is the address that's used for the
# contract address.
# Thus we can use the publisher's profile name as the contract's named address,
# since the CLI resolves named addresses to a profile if one exists with the
# same name.
export PUBLISHER="publisher"
export BIG_MONEY_GUY="big_money_guy"

aptos init --profile $PUBLISHER \
--rest-url http://host.docker.internal:8080/v1 \
--faucet-url http://host.docker.internal:8081 \
--private-key $PUBLISHER_PK \
--encoding hex \
--assume-yes \
--network custom

aptos init --profile $BIG_MONEY_GUY \
--rest-url http://host.docker.internal:8080/v1 \
--faucet-url http://host.docker.internal:8081 \
--private-key $BIG_MONEY_GUY_PK \
--encoding hex \
--assume-yes \
--network custom

# Fund with 1,000,000 APT.
aptos account fund-with-faucet \
--profile $PUBLISHER \
--amount 100000000000000

# Fund with 10,000,000 APT.
aptos account fund-with-faucet \
--profile $BIG_MONEY_GUY \
--amount 100000000000000

aptos move publish \
--assume-yes \
--included-artifacts none \
--named-addresses emojicoin_dot_fun=$PUBLISHER \
--override-size-check \
--max-gas 2000000 \
--package-dir /app/emojicoin_dot_fun \
--profile $PUBLISHER

aptos move publish \
--assume-yes \
--included-artifacts none \
--named-addresses \
rewards=$PUBLISHER,integrator=$PUBLISHER,emojicoin_dot_fun=$PUBLISHER \
--override-size-check \
--max-gas 200000 \
--package-dir /app/rewards \
--profile $PUBLISHER
9 changes: 9 additions & 0 deletions src/docker/aptos-node/run-fullnode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

aptos node run-local-testnet \
--assume-yes \
--with-indexer-api \
--force-restart

# Run forever.
tail -f /dev/null
51 changes: 51 additions & 0 deletions src/docker/compose.local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# yamllint disable rule:empty-lines rule:key-ordering rule:brackets
---
services:
aptos-node:
network_mode: 'host'
build:
context: '../../'
dockerfile: 'src/docker/aptos-node/Dockerfile'
ports:
- '50051:50051'
- '8070:8070'
- '8090:8090'
- '8080:8080'
- '8081:8081'
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:8070/']
interval: '30s'
timeout: '10s'
retries: 5
start_period: '30s'
command: ['bash', '/app/run-fullnode.sh']
# In order to start the node with the indexer API; i.e., run
# `aptos node run-local-testnet --with-indexer-api`, the Docker socket must
# be mounted to the container. This mount enables the container to start a
# new container. Note that this is *not* "Docker-in-Docker", but rather
# "Docker-outside-Docker". That is, the container can act as the host in
# terms of creating and orchestrating other containers but still appears as
# a sibling to the existing containers and any new containers it creates.
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'

move:
extra_hosts:
- 'host.docker.internal:host-gateway'
build:
context: '../../'
dockerfile: 'src/docker/aptos-node/Dockerfile'
environment:
PUBLISHER_PK: '${PUBLISHER_PK}'
BIG_MONEY_GUY_PK: '${BIG_MONEY_GUY_PK}'
EMOJICOIN_MODULE_ADDRESS: '${EMOJICOIN_MODULE_ADDRESS}'
depends_on:
aptos-node:
condition: 'service_healthy'
command: ['bash', '/app/initialize-contract.sh']

processor:
depends_on:
move:
condition: 'service_completed_successfully'
...
52 changes: 45 additions & 7 deletions src/rust/compose.yaml → src/docker/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
services:
broker:
build:
context: '.'
context: '../rust'
dockerfile: 'broker/Dockerfile'
args:
FEATURES: 'ws'
depends_on:
processor:
condition: 'service_started'
condition: 'service_healthy'
environment:
PROCESSOR_WS_URL: 'ws://processor:${PROCESSOR_WS_PORT}/ws'
PORT: '${BROKER_PORT}'
Expand All @@ -30,11 +30,11 @@ services:
- 'db:/var/lib/postgresql/data'
healthcheck:
test: 'pg_isready -h localhost -p 5432 -U emojicoin || exit 1'
interval: '5s'
timeout: '3s'
retries: '3'
interval: '60s'
timeout: '1s'
retries: '1'
start_period: '15s'
start_interval: '5s'
start_interval: '1s'
ports:
- '5432:5432'

Expand All @@ -55,7 +55,7 @@ services:
extra_hosts:
- 'host.docker.internal:host-gateway'
build:
context: 'processor/rust'
context: '../rust/processor/rust'
dockerfile: 'Dockerfile'
environment:
DATABASE_URL: 'postgres://emojicoin:emojicoin@postgres:5432/emojicoin'
Expand All @@ -73,6 +73,44 @@ services:
ports:
- '${PROCESSOR_WS_PORT}:${PROCESSOR_WS_PORT}'

frontend:
build:
context: '../..'
dockerfile: 'src/docker/frontend/Dockerfile'
args:
INBOX_URL: 'http://postgrest:3000'
HASH_SEED: '${HASH_SEED}'
NEXT_PUBLIC_APTOS_NETWORK: '${APTOS_NETWORK}'
NEXT_PUBLIC_INTEGRATOR_ADDRESS: '${EMOJICOIN_INTEGRATOR_ADDRESS}'
NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS: '${FEE_RATE_BPS}'
NEXT_PUBLIC_IS_ALLOWLIST_ENABLED: 'false'
NEXT_PUBLIC_MODULE_ADDRESS: '${EMOJICOIN_MODULE_ADDRESS}'
NEXT_PUBLIC_MQTT_URL: 'ws://broker:${BROKER_PORT}'
NEXT_PUBLIC_REWARDS_MODULE_ADDRESS: >-
${EMOJICOIN_REWARDS_MODULE_ADDRESS}
REVALIDATION_TIME: '${REVALIDATION_TIME}'
image: 'econialabs/emojicoin-dot-fun:frontend'
environment:
INBOX_URL: 'http://postgrest:3000'
HASH_SEED: '${HASH_SEED}'
NEXT_PUBLIC_APTOS_NETWORK: '${APTOS_NETWORK}'
NEXT_PUBLIC_INTEGRATOR_ADDRESS: '${EMOJICOIN_INTEGRATOR_ADDRESS}'
NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS: '${FEE_RATE_BPS}'
NEXT_PUBLIC_IS_ALLOWLIST_ENABLED: 'false'
NEXT_PUBLIC_MODULE_ADDRESS: '${EMOJICOIN_MODULE_ADDRESS}'
NEXT_PUBLIC_MQTT_URL: 'ws://broker:${BROKER_PORT}'
NEXT_PUBLIC_REWARDS_MODULE_ADDRESS: '${EMOJICOIN_REWARDS_MODULE_ADDRESS}'
REVALIDATION_TIME: '${REVALIDATION_TIME}'
ports:
- '3001:3001'
depends_on:
postgrest:
condition: 'service_started'
broker:
condition: 'service_healthy'

restart: 'unless-stopped'

volumes:
db:
driver: 'local'
Expand Down
84 changes: 84 additions & 0 deletions src/docker/example.local.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# The Aptos network to use.
# - mainnet
# - testnet
# - devnet
# - local
APTOS_NETWORK="local"

# This is the package address of the main module address.
#
# - It must start with `0x`
# - Remove all leading 0s after the `0x`.
# - Examples:
# - GOOD: 0xabc
# - BAD: 0x0abc
# - BAD: abc
# - BAD: 0abc
EMOJICOIN_MODULE_ADDRESS="0xf000d910b99722d201c6cf88eb7d1112b43475b9765b118f289b5d65d919000d"

# This is the package address of the rewards wrapper smart contract.
EMOJICOIN_REWARDS_MODULE_ADDRESS="0xf000d910b99722d201c6cf88eb7d1112b43475b9765b118f289b5d65d919000d"

# This is the address that receives fees generated by any `emojicoin_dot_fun`
# smart contract. It is passed to the rewards contract at compile time, but
# used in all other contexts at runtime.
EMOJICOIN_INTEGRATOR_ADDRESS="0xf000d910b99722d201c6cf88eb7d1112b43475b9765b118f289b5d65d919000d"

# The GRPC endpoint from which the indexer receives event data. Aptos Labs
# runs several public endpoints, listed below.
#
# mainnet: https://grpc.mainnet.aptoslabs.com:443
# testnet: https://grpc.testnet.aptoslabs.com:443
# devnet: https://grpc.devnet.aptoslabs.com:443
# local: http://host.docker.internal:50051
#
# NOTE: If you get errors connecting to `host.docker.internal` and you're
# using Docker Desktop on WSL2 (Windows Subsystem for Linux), you need to make
# sure you enable the `WSL 2 based engine` setting and the `Add the
# *.docker.internal names to the host's /etc/hosts file` setting.
# You *also* need to enable the experimental `Enable host networking` feature.
# > To enable this feature, navigate to the Features in development tab in
# > Settings, and then select Enable host networking.
# See: https://docs.docker.com/engine/network/tutorials/host/
# And: https://docs.docker.com/desktop/windows/permission-requirements/
GRPC_DATA_SERVICE_URL="http://host.docker.internal:50051"

# For a public chain you have to get this token from https://developers.aptoslabs.com/.
# For local end-to-end testing you can use: "dummy_token"
GRPC_AUTH_TOKEN="dummy_token"

# The minimum transaction version at which to start indexing.
# Events that occur prior to this transaction version will not be indexed.
# This is most often set to the transaction version where the package is published.
MINIMUM_STARTING_VERSION="0"

# A hard limit to the number of rows PostgREST will fetch from a view, table, or stored procedure.
# Limits payload size for accidental or malicious requests.
POSTGREST_MAX_ROWS="500"

# The port the processor and broker use to communicate.
PROCESSOR_WS_PORT="3008"

# The port the broker listens on for client connections.
BROKER_PORT="3009"

# The private key used to deploy the package locally for tests.
# Note that this private key is obviously public and should never be used in
# production or for any real value transactions.
# If you change this, local tests will fail unless you also change the
# corresponding `*_ADDRESS` values that are derived from this key.
PUBLISHER_PK="0xeaa964d1353b075ac63b0c5a0c1e92aa93355be1402f6077581e37e2a846105e"

# The caching time for server-side requests for the NextJS web application.
REVALIDATION_TIME="1"

# The integrator fee rate basis points.
FEE_RATE_BPS="100"

# Secret hash seed.
HASH_SEED="some random string that is not public"

# The private key for the "big money guy", who sends transactions in tests.
# Corresponds to the address:
# 0xb168d5a1137a3254a9443459ae5b4959e8f5c835858f04e5a01fe133d237d00d
BIG_MONEY_GUY_PK="0xa5e11183d0c23b8c49b40dd71bba7fa0992aed9b89c42934a1bb8f6e4ccc4ec4"
Loading

0 comments on commit 251f464

Please sign in to comment.