Skip to content

Commit 78093bd

Browse files
authored
Merge pull request #1138 from erubboli/master
Create a docker build script
2 parents 620ebb5 + dfe0af0 commit 78093bd

File tree

9 files changed

+266
-0
lines changed

9 files changed

+266
-0
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
.git

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
# VSCode
1515
.vscode/
1616

17+
#exclude python env
18+
env/
19+
1720
# Test Python cache
1821
test/**/__pycache__
1922

build-tools/docker/BUILD.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Building Docker Images for Mintlayer
2+
3+
This document outlines the steps to build Docker images for the Mintlayer node daemon, wallet-cli, and node-gui.
4+
5+
Before building make sure you clone the repository and change the current directory in the root of the repository.
6+
7+
# The python build script
8+
9+
Make sure you have python installed together with the `toml` package, you may want to create a specific environment:
10+
11+
```bash
12+
python3 -m venv env
13+
source env/bin/activate
14+
python3 -m pip install --upgrade pip
15+
python3 -m pip install toml
16+
```
17+
18+
In order to build the images run:
19+
20+
```bash
21+
python3 build-tools/docker/build.py
22+
```
23+
24+
NOTE: to change the version of the images use the `-version` flag such as `--version=1.2.3`.
25+
26+
For verifing images are built with use the following command:
27+
28+
```bash
29+
docker images | grep mintlayer
30+
```
31+
32+
The result should similar to the following:
33+
34+
```
35+
$ docker images |grep mintlayer
36+
mintlayer/wallet-cli 0.1.1 57dcc4898a30 2 minutes ago 125MB
37+
mintlayer/node-gui 0.1.1 a2ed3937e081 2 minutes ago 290MB
38+
mintlayer/node-daemon 0.1.1 ad830bf576e3 3 minutes ago 119MB
39+
```
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM rust AS builder
2+
3+
WORKDIR /usr/src/
4+
5+
COPY . .
6+
7+
ARG NUM_JOBS=1
8+
RUN cargo build --release -j${NUM_JOBS}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Build Stage
2+
FROM mintlayer-builder:latest AS builder
3+
4+
5+
# Runtime Stage
6+
FROM debian:bookworm-slim
7+
8+
COPY --from=builder /usr/src/target/release/node-daemon /usr/bin
9+
10+
# Node daemon listens on ports 3030 and 13031
11+
EXPOSE 3030 13031
12+
13+
# Define mintlayer directory as a volume
14+
VOLUME ["/root/.mintlayer"]
15+
16+
CMD ["node-daemon"]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Build Stage
2+
FROM mintlayer-builder:latest AS builder
3+
4+
# Runtime Stage
5+
FROM debian:bookworm-slim
6+
7+
# Install any necessary dependencies for your GUI (such as X11, GTK, etc.)
8+
# Replace libgtk-3-0 with the appropriate dependencies for your application
9+
RUN apt-get update && apt-get install -y ca-certificates libgtk-3-0 && rm -rf /var/lib/apt/lists/*
10+
11+
COPY --from=builder /usr/src/target/release/node-gui /usr/bin/node-gui
12+
13+
CMD ["node-gui"]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Build Stage
2+
FROM mintlayer-builder:latest AS builder
3+
4+
# Runtime Stage
5+
FROM debian:bookworm-slim
6+
7+
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
8+
9+
COPY --from=builder /usr/src/target/release/wallet-cli /usr/bin/wallet-cli
10+
11+
CMD ["wallet-cli"]

build-tools/docker/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Mintlayer Node-Daemon and Wallet-CLI Docker Deployment
2+
3+
This guide will cover how to use Docker to deploy and run the Mintlayer `node-daemon` and `wallet-cli`.
4+
5+
## Prerequisites
6+
7+
You need to have Docker installed on your system. For Docker installation guide, please visit [official Docker documentation](https://docs.docker.com/get-docker/).
8+
9+
## Mintlayer Node-Daemon
10+
11+
First, let's pull the docker image for `node-daemon`:
12+
13+
```bash
14+
docker pull mintlayer/node-daemon:latest
15+
```
16+
17+
Create a network for the containers to communicate:
18+
19+
```bash
20+
docker network create mintlayer-net
21+
```
22+
23+
To run the `node-daemon` detached and on the testnet network:
24+
25+
```bash
26+
docker run -d -p 3030:3030 -p 13031:13031 --network=mintlayer-net --name mintlayer_node_daemon --user "$(id -u):$(id -g)" -v ~/.mintlayer:/root/.mintlayer mintlayer/node-daemon:latest node-daemon testnet --http-rpc-addr 0.0.0.0:3030
27+
```
28+
29+
The `-v` option is used to mount a local directory (in this case `~/.mintlayer`) as a volume in the Docker container.
30+
The `--user` option is used to specify the user that will write to the `~/.mintlayer` directory.
31+
NOTE: this won't work on windows hosts.
32+
33+
If you want to display logs you can pass the `-e RUST_LOG=info` argument, such as:
34+
35+
```bash
36+
docker run -d -p 3030:3030 -p 13031:13031 -e RUST_LOG=info --network=mintlayer-net --name mintlayer_node_daemon --user "$(id -u):$(id -g)" -v ~/.mintlayer:/root/.mintlayer mintlayer/node-daemon:latest node-daemon testnet --http-rpc-addr 0.0.0.0:3030
37+
```
38+
39+
## Mintlayer Wallet-CLI
40+
41+
Pull the docker image for `wallet-cli`:
42+
43+
```bash
44+
docker pull mintlayer/wallet-cli:latest
45+
```
46+
47+
Before running `wallet-cli`, ensure that the `node-daemon` container is running, as it generates the `.cookie` file required by wallet-cli, then find the IP address of the node:
48+
49+
```bash
50+
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aqf "name=mintlayer_node_daemon")
51+
```
52+
53+
this will display the IP address of your node in the `mintlayer-net`
54+
55+
To run `wallet-cli` with the RPC cookie file:
56+
57+
```bash
58+
docker run -it --network=mintlayer-net -v ~/.mintlayer:/root/.mintlayer mintlayer/wallet-cli:latest wallet-cli --rpc-cookie-file /root/.mintlayer/<NETWORK>/.cookie --rpc-address <IP_ADDRESS>:3030
59+
```
60+
61+
replace `<NETWORK>` with `mainnet` or `testnet` depending on what network you're running and `<IP_ADDRESS>` with the result of the command above.
62+
63+
This command mounts the same `~/.mintlayer` directory as a volume in the `wallet-cli` container and uses the `--rpc-cookie-file` option to specify the path to the cookie file.

build-tools/docker/build.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import toml
2+
import os
3+
import subprocess
4+
import argparse
5+
6+
7+
def get_cargo_version(cargo_toml_path):
8+
if not os.path.exists(cargo_toml_path):
9+
raise ValueError(f"No such file: {cargo_toml_path}")
10+
11+
# Read the Cargo.toml file
12+
config = toml.load(cargo_toml_path)
13+
14+
# Get the version
15+
version = config.get('package', {}).get('version')
16+
17+
if version is None:
18+
raise ValueError(f"No version specified in {cargo_toml_path}")
19+
20+
return version
21+
22+
23+
def build_docker_image(dockerfile_path, image_name, version, num_jobs=None):
24+
# Docker build command
25+
command = f"docker build -t {image_name}:{version} -f {dockerfile_path}"
26+
if num_jobs:
27+
command += f" --build-arg NUM_JOBS={num_jobs}"
28+
command += " ."
29+
30+
try:
31+
# Run the command
32+
subprocess.check_call(command, shell=True)
33+
print(f"Built {image_name}:{version} successfully.")
34+
catch:
35+
print(f"Error occurred: {error}")
36+
exit(1) # stop the build
37+
38+
39+
def push_docker_image(image_name, version, latest=False):
40+
# Docker tag command
41+
full_image_name = f"{image_name}:{version}"
42+
if latest:
43+
latest_image_name = f"{image_name}:latest"
44+
tag_command = f"docker tag {full_image_name} {latest_image_name}"
45+
subprocess.check_call(tag_command, shell=True)
46+
47+
# Docker push command
48+
push_command = f"docker push {full_image_name}"
49+
subprocess.check_call(push_command, shell=True)
50+
51+
# if latest flag is true, push the image with 'latest' tag
52+
if latest:
53+
push_command_latest = f"docker push {latest_image_name}"
54+
subprocess.check_call(push_command_latest, shell=True)
55+
56+
print(f"Pushed {full_image_name} successfully.")
57+
if latest:
58+
print(f"Pushed {latest_image_name} successfully.")
59+
60+
61+
def delete_docker_image(image_name, version):
62+
# Full image name
63+
full_image_name = f"{image_name}:{version}"
64+
65+
# Docker rmi command
66+
command = f"docker rmi {full_image_name}"
67+
68+
# Run the command
69+
try:
70+
subprocess.check_call(command, shell=True)
71+
print(f"Deleted {full_image_name} successfully.")
72+
except subprocess.CalledProcessError:
73+
print(f"Failed to delete {full_image_name}.")
74+
75+
76+
def build_instances(version, num_jobs=None):
77+
build_docker_image("build-tools/docker/Dockerfile.builder", "mintlayer-builder", "latest", num_jobs)
78+
build_docker_image("build-tools/docker/Dockerfile.node-daemon", "mintlayer/node-daemon", version)
79+
build_docker_image("build-tools/docker/Dockerfile.node-gui", "mintlayer/node-gui", version)
80+
build_docker_image("build-tools/docker/Dockerfile.wallet-cli", "mintlayer/wallet-cli", version)
81+
delete_docker_image("mintlayer-builder", "latest")
82+
83+
84+
def push_instances(version, latest):
85+
push_docker_image("mintlayer/node-daemon",version , latest)
86+
push_docker_image("mintlayer/node-gui",version , latest)
87+
push_docker_image("mintlayer/wallet-cli",version , latest)
88+
89+
90+
def main():
91+
parser = argparse.ArgumentParser()
92+
parser.add_argument('--push', action='store_true', help='Push the Docker image to Docker Hub')
93+
parser.add_argument('--latest', action='store_true', help='Tag the Docker image as latest while pushing')
94+
parser.add_argument('--build', type=lambda x: (str(x).lower() == 'true'), default=True, help="Set to false avoid the build")
95+
parser.add_argument('--version', help='Override version number', default=None)
96+
parser.add_argument('--num_jobs', help='Number of parallel jobs, defaults to # of CPUs', default=None)
97+
args = parser.parse_args()
98+
99+
version = args.version if args.version else get_cargo_version("Cargo.toml")
100+
101+
if args.build:
102+
build_instances(version, num_jobs)
103+
104+
# Only push the image if the --push flag is provided
105+
if args.push:
106+
latest = args.latest
107+
push_instances(version, latest)
108+
109+
110+
if __name__ == "__main__":
111+
main()

0 commit comments

Comments
 (0)