Skip to content

Commit 5a9cf7c

Browse files
authored
Docker image support added. (#325)
# Describe Request Docker image support added. Fixed #288 # Change Type New feature. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Docker containerization for easy deployment, including containerized builds of the app and runtime. * Automated CI/CD publishing of Docker images on release tags. * Container entrypoint to run data synchronization and backtests with configurable options (API key, timeframe, asset selection, output location). * **Documentation** * Added Docker quick start, usage examples, and local build workflow to the README. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 029ada2 commit 5a9cf7c

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed

.github/workflows/docker.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
7+
jobs:
8+
docker:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
packages: write
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Docker Buildx
17+
uses: docker/setup-buildx-action@v3
18+
19+
- name: Login to Container Registry
20+
uses: docker/login-action@v3
21+
with:
22+
registry: ghcr.io
23+
username: ${{ github.actor }}
24+
password: ${{ secrets.GITHUB_TOKEN }}
25+
26+
- name: Docker metadata
27+
id: meta
28+
uses: docker/metadata-action@v5
29+
with:
30+
images: ghcr.io/cinar/indicator
31+
tags: |
32+
type=semver,pattern={{version}}
33+
type=semver,pattern={{major}}.{{minor}}
34+
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}
35+
36+
- name: Build and push
37+
uses: docker/build-push-action@v6
38+
with:
39+
context: .
40+
push: true
41+
tags: ${{ steps.meta.outputs.tags }}
42+
labels: ${{ steps.meta.outputs.labels }}
43+
cache-from: type=gha
44+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) 2021-2026 Onur Cinar.
2+
# The source code is provided under GNU AGPLv3 License.
3+
# https://github.com/cinar/indicator
4+
5+
FROM golang:1.22-alpine AS builder
6+
7+
RUN apk add --no-cache git
8+
9+
WORKDIR /build
10+
11+
COPY go.mod ./
12+
13+
RUN go mod download
14+
15+
COPY . .
16+
17+
RUN go build -o indicator-sync ./cmd/indicator-sync/main.go
18+
RUN go build -o indicator-backtest ./cmd/indicator-backtest/main.go
19+
20+
FROM alpine:3.19
21+
22+
RUN apk add --no-cache ca-certificates
23+
24+
WORKDIR /app
25+
26+
COPY --from=builder /build/indicator-sync /app/
27+
COPY --from=builder /build/indicator-backtest /app/
28+
29+
RUN mkdir -p /app/data /app/output
30+
31+
RUN addgroup -S indicator && adduser -S indicator -G indicator \
32+
&& chown -R indicator:indicator /app
33+
34+
COPY docker-entrypoint.sh /usr/local/bin/
35+
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
36+
37+
USER indicator
38+
39+
ENTRYPOINT ["docker-entrypoint.sh"]

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,74 @@ $ indicator-backtest \
242242
-workers 1
243243
```
244244

245+
🐳 Docker
246+
---------
247+
248+
The easiest way to get started is using our Docker image. It handles everything - syncing market data from Tiingo and generating backtest reports - in a single command.
249+
250+
### Quick Start
251+
252+
```bash
253+
# Get your free Tiingo API key at: https://www.tiingo.com/
254+
255+
# Run backtest for specific assets
256+
docker run -it --rm \
257+
-v $(pwd)/output:/app/output \
258+
ghcr.io/cinar/indicator:latest \
259+
--api-key YOUR_TIINGO_API_KEY \
260+
--days 365 \
261+
--assets aapl msft googl
262+
263+
# View results (macOS)
264+
open output/index.html
265+
266+
# View results (Linux)
267+
xdg-open output/index.html
268+
```
269+
270+
### Options
271+
272+
| Flag | Description | Default |
273+
|------|-------------|---------|
274+
| `--api-key` | Tiingo API key (required) | - |
275+
| `--days` | Days of historical data to fetch | 365 |
276+
| `--last` | Days to backtest | 365 |
277+
| `--assets` | Space-separated ticker symbols (default: all) | all |
278+
| `--output` | Output directory for reports | /app/output |
279+
280+
### Examples
281+
282+
```bash
283+
# Backtest all available assets for 1 year
284+
docker run -it --rm \
285+
-v $(pwd)/reports:/app/output \
286+
ghcr.io/cinar/indicator:latest \
287+
--api-key YOUR_TIINGO_API_KEY
288+
289+
# Backtest specific stocks for last 6 months, test last 30 days
290+
docker run -it --rm \
291+
-v $(pwd)/reports:/app/output \
292+
ghcr.io/cinar/indicator:latest \
293+
--api-key YOUR_TIINGO_API_KEY \
294+
--days 180 \
295+
--last 30 \
296+
--assets aapl msft googl amzn
297+
298+
# Custom output directory
299+
docker run -it --rm \
300+
-v /path/to/my/reports:/app/output \
301+
ghcr.io/cinar/indicator:latest \
302+
--api-key YOUR_TIINGO_API_KEY \
303+
--output /app/output
304+
```
305+
306+
### Build Locally
307+
308+
```bash
309+
docker build -t indicator .
310+
docker run -it --rm -v $(pwd)/output:/app/output indicator --api-key YOUR_KEY
311+
```
312+
245313
☁️ MCP Server
246314
--------------
247315

docker-entrypoint.sh

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/bin/sh
2+
# Copyright (c) 2021-2026 Onur Cinar.
3+
# The source code is provided under GNU AGPLv3 License.
4+
# https://github.com/cinar/indicator
5+
6+
set -e
7+
8+
API_KEY=""
9+
DAYS=365
10+
LAST=365
11+
ASSETS=""
12+
OUTPUT="/app/output"
13+
DATA_DIR="/app/data"
14+
15+
show_usage() {
16+
echo "Usage: indicator [OPTIONS]"
17+
echo ""
18+
echo "Sync market data from Tiingo and run backtests."
19+
echo ""
20+
echo "Options:"
21+
echo " --api-key KEY Tiingo API key (required)"
22+
echo " --days N Days of historical data to fetch (default: 365)"
23+
echo " --last N Days to backtest (default: 365)"
24+
echo " --assets TICKERS Space-separated list of ticker symbols (default: all available)"
25+
echo " --output DIR Output directory for reports (default: /app/output)"
26+
echo " --help Show this help message"
27+
echo ""
28+
echo "Example:"
29+
echo " indicator --api-key YOUR_KEY --days 365 --assets aapl msft googl"
30+
echo ""
31+
echo "Get your free Tiingo API key at: https://www.tiingo.com/"
32+
}
33+
34+
while [ $# -gt 0 ]; do
35+
case "$1" in
36+
--api-key)
37+
API_KEY="$2"
38+
shift 2
39+
;;
40+
--days)
41+
DAYS="$2"
42+
shift 2
43+
;;
44+
--last)
45+
LAST="$2"
46+
shift 2
47+
;;
48+
--assets)
49+
shift
50+
ASSETS=""
51+
while [ $# -gt 0 ] && [ "${1#-}" = "$1" ]; do
52+
ASSETS="${ASSETS:+$ASSETS }$1"
53+
shift
54+
done
55+
;;
56+
--output)
57+
OUTPUT="$2"
58+
shift 2
59+
;;
60+
--help)
61+
show_usage
62+
exit 0
63+
;;
64+
*)
65+
echo "Unknown option: $1"
66+
show_usage
67+
exit 1
68+
;;
69+
esac
70+
done
71+
72+
if [ -z "$API_KEY" ]; then
73+
echo "Error: --api-key is required"
74+
echo ""
75+
show_usage
76+
exit 1
77+
fi
78+
79+
echo "=========================================="
80+
echo "Indicator Docker - Sync & Backtest"
81+
echo "=========================================="
82+
echo ""
83+
echo "Configuration:"
84+
echo " API Key: ***"
85+
echo " Days: $DAYS"
86+
echo " Backtest Period: $LAST days"
87+
echo " Assets: ${ASSETS:-all}"
88+
echo " Output: $OUTPUT"
89+
echo ""
90+
91+
mkdir -p "$OUTPUT"
92+
93+
echo "Step 1: Syncing market data from Tiingo..."
94+
echo "-------------------------------------------"
95+
96+
if [ -z "$ASSETS" ]; then
97+
./indicator-sync \
98+
-source-name tiingo \
99+
-source-config "$API_KEY" \
100+
-target-name filesystem \
101+
-target-config "$DATA_DIR" \
102+
-days "$DAYS"
103+
else
104+
./indicator-sync \
105+
-source-name tiingo \
106+
-source-config "$API_KEY" \
107+
-target-name filesystem \
108+
-target-config "$DATA_DIR" \
109+
-days "$DAYS" \
110+
$ASSETS
111+
fi
112+
113+
echo ""
114+
echo "Step 2: Running backtests..."
115+
echo "-------------------------------------------"
116+
117+
if [ -z "$ASSETS" ]; then
118+
./indicator-backtest \
119+
-repository-name filesystem \
120+
-repository-config "$DATA_DIR" \
121+
-report-name html \
122+
-report-config "$OUTPUT" \
123+
-last "$LAST"
124+
else
125+
./indicator-backtest \
126+
-repository-name filesystem \
127+
-repository-config "$DATA_DIR" \
128+
-report-name html \
129+
-report-config "$OUTPUT" \
130+
-last "$LAST" \
131+
$ASSETS
132+
fi
133+
134+
echo ""
135+
echo "=========================================="
136+
echo "Done! Reports generated in: $OUTPUT"
137+
echo "=========================================="
138+
echo ""
139+
echo "Open $OUTPUT/index.html in your browser to view the results."

0 commit comments

Comments
 (0)