Skip to main content

Docker Deployment

Multiple Modes

As mentioned in the flow of operations section, deployments of the Data API will be in an online environment and deployments of the Construction API will be in an offline environment. "Offline environment" in this case means that the deployment will not be able to make any outbound connections over the internet. The only traffic allowed in this environment will be inbound requests to the exposed Construction API endpoints (with the exception of /construction/metadata and /construction/submit, which require an internet connection to work properly).

To support deployment in these distinct environments, it must be possible to specify an "offline" or "online" mode at startup (it is ok to default to "online"). When the "offline" mode is specified, the implementation must not attempt to open any outbound connections over the internet (i.e. attempt to peer with other nodes).

We do not recommend using multiple Dockerfiles to support these 2 modes as the overhead of maintaining two deployment artifacts across upgrades can end up being unnecessarily burdensome for both Rosetta implementers and integrators.

Online Mode Endpoints

The following endpoints must work properly in "online" mode:

  • /network/*
  • /block/*
  • /account/*
  • /mempool/*
  • /call
  • /construction/metadata
  • /construction/submit

Some integrators do not require transaction construction to occur offline and may only run your implementation in "online" mode. For this reason, you should not disable any endpoints when in "online" mode.

Offline Mode Endpoints

The following endpoints must work properly in "offline" mode:

  • /network/list
  • /network/options
  • /construction/derive
  • /construction/preprocess
  • /construction/payloads
  • /construction/combine
  • /construction/parse
  • /construction/hash

Dockerfile Expectations

There are many ways to write functional Dockerfiles, however, some approaches are less secure and make deployment and/or maintenance more difficult. In this section, we outline a few guidelines we expect any implementation to meet.

Ubuntu Image Compatibility

It must be possible to compile and run your implementation using exclusively Ubuntu-based images. This does not mean that the Dockerfile you share on your repository must use Ubuntu-based images (although it is highly recommended), however, it should still be possible to compile and run your implementation on Ubuntu-based images. In other words, if compilation of your implementation relies on musl-libc from Alpine, it would not be considered Ubuntu-compatible.

You may be wondering why Ubuntu is required instead of Debian or Alpine, or why there is any base image requirement at all (outside of maybe requiring any linux-based image). Many companies (especially ones exteremly concerned with security) very purposely limit the number of operating systems they support on their infrastructure to simplify the tracking and patching of critical vulnerabilities in the OS. Ubuntu is one of the most popular Linux distributions and nearly all developers that will be running your implementation can support Ubuntu (eventhough they may not support other Linux distributions).

Build Anywhere

It must be possible to build your Dockerfile from any location (i.e. run docker build). For this reason, your Dockerfile must not copy any files from the directory where it is built. Instead, any required files must be downloaded from the internet with explicit versioning. If it is not possible to fetch a specific version, the hash of downloaded files must be compared with a constant defined in the Dockerfile.

Good Example

# Use multi-stage build
FROM golang:1.13 as builder

# Download from GitHub instead of using COPY
git clone https://github.com/blockchain-team/node

# Checkout a specific version
git checkout v1.2
make build

# Create final container
FROM ubuntu:latest
# It is ok to COPY files from a build container (when using multi-stage builds)
COPY --from=builder bin/node bin/node
CMD node run

Bad Example: Copy Files from Build Environment

FROM golang:1.13

# Do not COPY files into container from directory where built
COPY . .
make build

CMD node run

Compile from Source

Your Dockerfile must build both the node you are working on and Rosetta implementation exclusively from source. In other words, your Dockerfile must not rely on any images that contain previously compiled code relevant to the blockchain you are working on.

Good Example

FROM golang:1.13 as builder
git clone https://github.com/blockchain-team/node
git checkout v1.2
make build

FROM ubuntu:latest
# It is ok to rely on build containers in a multi-stage build
COPY --from=builder bin/node bin/node

CMD node run

Bad Example: Build on Pre-Compiled Image

# Do not use previously built images (even if it
# is just for the node you are working on and not your Rosetta implementation)
FROM previously-built-blockchain-node-image:latest

git clone https://github.com/blockchain-team/rosetta-node
make build

CMD node run

Was this helpful?