Skip to content

Commit 35abd46

Browse files
authored
Add docker setup (#12)
1 parent a1e6d97 commit 35abd46

12 files changed

Lines changed: 256 additions & 17 deletions

File tree

.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.env
2+
.git
3+
.DS_Store
4+
target
5+
web/node_modules
6+
web/dist
7+
web/.env

.env.example

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
POSTGRES_USER=postgres
2+
POSTGRES_PASSWORD=password
3+
POSTGRES_DB=lending-indexer
4+
POSTGRES_PORT=5432
5+
DATABASE_URL=postgresql://postgres:password@postgres:5432/lending-indexer
6+
WEB_PORT=80
7+
8+
# Build-time variables for web image
9+
VITE_API_URL=http://localhost/api
10+
VITE_ESPLORA_BASE_URL=https://blockstream.info/liquidtestnet/api
11+
VITE_ESPLORA_EXPLORER_URL=https://blockstream.info/liquidtestnet

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,24 @@ In case the Borrower fails to pay interest before the lending contract expiry, t
2424

2525
## How to use
2626

27+
### Through Docker
28+
29+
From repo root:
30+
31+
```bash
32+
docker compose up --build
33+
```
34+
35+
36+
### Locally (without Docker)
37+
2738
To run the **demo frontend** (web app for borrowers and lenders), you need the **Indexer** API running. The web app talks to it to list and manage offers.
2839

2940
**Quick start (from repo root):**
3041

3142
1. **Indexer** — set up PostgreSQL, configure `crates/indexer` (see [crates/indexer/README.md](crates/indexer/README.md)), then:
3243
```bash
33-
cd creates/indexer && cargo run -p lending-indexer
44+
cd crates/indexer && cargo run -p lending-indexer
3445
```
3546
By default this starts the API (port 8000). For full indexing you also need the indexer worker (`RUN_MODE=indexer`).
3647

crates/indexer/Dockerfile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
FROM rust:1.90-bookworm AS builder
2+
3+
RUN apt-get update && apt-get install -y --no-install-recommends pkg-config libssl-dev && rm -rf /var/lib/apt/lists/*
4+
5+
WORKDIR /app
6+
7+
COPY Cargo.toml Cargo.lock ./
8+
COPY .sqlx ./.sqlx
9+
COPY crates ./crates
10+
11+
RUN SQLX_OFFLINE=true cargo build --locked --release -p lending-indexer --bin simplicity-lending-indexer
12+
13+
FROM builder AS sqlx-builder
14+
RUN cargo install --locked sqlx-cli --no-default-features --features rustls,postgres
15+
16+
FROM debian:bookworm-slim AS runtime
17+
18+
RUN apt-get update && apt-get install -y --no-install-recommends bash ca-certificates libssl3 nodejs npm && rm -rf /var/lib/apt/lists/*
19+
RUN npm install --global --no-fund --no-update-notifier bunyan
20+
RUN useradd --system --create-home --uid 10001 appuser
21+
22+
WORKDIR /app
23+
COPY --from=builder /app/target/release/simplicity-lending-indexer /usr/local/bin/simplicity-lending-indexer
24+
COPY crates/indexer/configuration/ configuration/
25+
26+
USER appuser
27+
CMD ["bash", "-o", "pipefail", "-c", "simplicity-lending-indexer 2>&1 | bunyan"]
28+
29+
FROM debian:bookworm-slim AS migrate
30+
31+
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
32+
33+
WORKDIR /app
34+
COPY --from=sqlx-builder /usr/local/cargo/bin/sqlx /usr/local/bin/sqlx
35+
COPY crates/indexer/migrations/ migrations/
36+
37+
CMD ["sqlx", "migrate", "run"]

crates/indexer/configuration/base.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ esplora:
1111
timeout: 10
1212
indexer:
1313
interval: 10000
14-
last_indexed_height: 2309541
14+
last_indexed_height: 2360000
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
application:
2-
host: 0.0.0.0
2+
host: 0.0.0.0
3+
database:
4+
host: postgres

crates/indexer/src/configuration.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub fn get_configuration() -> Result<Settings, config::ConfigError> {
5959
.add_source(config::File::from(
6060
configuration_directory.join(environment_filename),
6161
))
62+
// Environment variables override file-based configuration
63+
.add_source(config::Environment::default().separator("__"))
6264
.build()?;
6365

6466
settings.try_deserialize::<Settings>()

docker-compose.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
services:
2+
postgres:
3+
image: postgres:16-alpine
4+
restart: unless-stopped
5+
env_file:
6+
- .env
7+
environment:
8+
POSTGRES_USER: ${POSTGRES_USER}
9+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
10+
POSTGRES_DB: ${POSTGRES_DB}
11+
volumes:
12+
- postgres_data:/var/lib/postgresql/data
13+
healthcheck:
14+
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
15+
interval: 5s
16+
timeout: 5s
17+
retries: 5
18+
19+
migrate:
20+
build:
21+
context: .
22+
dockerfile: crates/indexer/Dockerfile
23+
target: migrate
24+
restart: "no"
25+
env_file:
26+
- .env
27+
command: ["sqlx", "migrate", "run"]
28+
depends_on:
29+
postgres:
30+
condition: service_healthy
31+
32+
api:
33+
build:
34+
context: .
35+
dockerfile: crates/indexer/Dockerfile
36+
target: runtime
37+
env_file:
38+
- .env
39+
environment:
40+
APP_ENVIRONMENT: production
41+
RUN_MODE: api
42+
DATABASE__HOST: postgres
43+
DATABASE__PORT: ${POSTGRES_PORT}
44+
DATABASE__USERNAME: ${POSTGRES_USER}
45+
DATABASE__PASSWORD: ${POSTGRES_PASSWORD}
46+
DATABASE__DATABASE_NAME: ${POSTGRES_DB}
47+
depends_on:
48+
migrate:
49+
condition: service_completed_successfully
50+
expose:
51+
- 8000
52+
53+
indexer:
54+
build:
55+
context: .
56+
dockerfile: crates/indexer/Dockerfile
57+
target: runtime
58+
restart: unless-stopped
59+
env_file:
60+
- .env
61+
environment:
62+
APP_ENVIRONMENT: production
63+
RUN_MODE: indexer
64+
DATABASE__HOST: postgres
65+
DATABASE__PORT: ${POSTGRES_PORT}
66+
DATABASE__USERNAME: ${POSTGRES_USER}
67+
DATABASE__PASSWORD: ${POSTGRES_PASSWORD}
68+
DATABASE__DATABASE_NAME: ${POSTGRES_DB}
69+
depends_on:
70+
migrate:
71+
condition: service_completed_successfully
72+
73+
web:
74+
build:
75+
context: .
76+
dockerfile: web/Dockerfile
77+
args:
78+
VITE_API_URL: ${VITE_API_URL}
79+
VITE_ESPLORA_BASE_URL: ${VITE_ESPLORA_BASE_URL}
80+
VITE_ESPLORA_EXPLORER_URL: ${VITE_ESPLORA_EXPLORER_URL}
81+
restart: unless-stopped
82+
ports:
83+
- '${WEB_PORT}:80'
84+
depends_on:
85+
api:
86+
condition: service_started
87+
88+
volumes:
89+
postgres_data:

nginx/nginx.conf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
events {}
2+
3+
http {
4+
include /etc/nginx/mime.types;
5+
6+
server {
7+
listen 80;
8+
server_name _;
9+
10+
root /usr/share/nginx/html;
11+
index index.html;
12+
13+
location = /api {
14+
return 308 /api/;
15+
}
16+
17+
location /api/ {
18+
proxy_pass http://api:8000/;
19+
proxy_http_version 1.1;
20+
proxy_set_header Host $host;
21+
proxy_set_header X-Real-IP $remote_addr;
22+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23+
proxy_set_header X-Forwarded-Proto $scheme;
24+
}
25+
26+
location = /esplora {
27+
return 308 /esplora/;
28+
}
29+
30+
location /esplora/ {
31+
proxy_pass https://blockstream.info/liquidtestnet/api/;
32+
proxy_http_version 1.1;
33+
proxy_ssl_server_name on;
34+
proxy_redirect off;
35+
}
36+
37+
location = /runtime-config.js {
38+
add_header Cache-Control "no-store";
39+
try_files /runtime-config.js =404;
40+
}
41+
42+
location / {
43+
try_files $uri $uri/ /index.html;
44+
}
45+
}
46+
}

web/Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
FROM rust:1.90-bookworm AS lwk-builder
2+
3+
ARG LWK_REF=wasm_0.15.0
4+
ARG LWK_COMMIT=5b015d6548a2e5ce60c5fcaae449248447e4c02d
5+
6+
RUN apt-get update && apt-get install -y --no-install-recommends git pkg-config libssl-dev ca-certificates clang && rm -rf /var/lib/apt/lists/*
7+
RUN rustup target add wasm32-unknown-unknown
8+
RUN cargo install wasm-pack --locked
9+
RUN git clone --depth 1 --branch "${LWK_REF}" https://github.com/Blockstream/lwk.git /tmp/lwk
10+
RUN test "$(git -C /tmp/lwk rev-parse HEAD)" = "${LWK_COMMIT}"
11+
WORKDIR /tmp/lwk/lwk_wasm
12+
RUN RUSTFLAGS='--cfg web_sys_unstable_apis' wasm-pack build --target web --out-dir pkg_web --features simplicity,serial
13+
14+
FROM node:24-alpine AS builder
15+
16+
WORKDIR /app
17+
18+
COPY --from=lwk-builder /tmp/lwk/lwk_wasm/pkg_web /app/lwk_wasm/pkg_web
19+
20+
COPY web/package.json web/package-lock.json ./web/
21+
WORKDIR /app/web
22+
RUN npm install --no-audit --no-fund
23+
24+
# Copy application sources
25+
WORKDIR /app
26+
COPY web ./web
27+
COPY crates/contracts/src ./crates/contracts/src
28+
29+
WORKDIR /app/web
30+
ARG VITE_API_URL
31+
ARG VITE_ESPLORA_BASE_URL
32+
ARG VITE_ESPLORA_EXPLORER_URL
33+
ENV VITE_API_URL=$VITE_API_URL
34+
ENV VITE_ESPLORA_BASE_URL=$VITE_ESPLORA_BASE_URL
35+
ENV VITE_ESPLORA_EXPLORER_URL=$VITE_ESPLORA_EXPLORER_URL
36+
RUN npm run build
37+
38+
FROM nginx:1.27-alpine AS runtime
39+
40+
COPY nginx/nginx.conf /etc/nginx/nginx.conf
41+
COPY --from=builder /app/web/dist /usr/share/nginx/html
42+
43+
EXPOSE 80
44+
CMD ["nginx", "-g", "daemon off;"]

0 commit comments

Comments
 (0)