Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
50 changes: 45 additions & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
# Git / workspace metadata
.git
.github
.devcontainer
.husky
.codex
.vscode

# Dependency installs and caches
node_modules
**/node_modules
.turbo
**/.turbo
**/.next
**/out
**/build
**/dist
**/standalone
**/coverage

# Docs and generated content
LICENSE
NOTICE
README.md
.prettierrc
.prettierignore
README.md
.gitignore
.husky
.github
.devcontainer
.env.example
node_modules
/apps/docs/.source
/apps/docs/.contentlayer
/apps/docs/.content-collections
/apps/docs/.next
/apps/docs/out
/apps/docs/build
/apps/docs/coverage

# Environment and local secrets
.env
*.env
.env.local
.env.development
.env.test
.env.production

# Miscellaneous
*.log
*.map
.DS_Store
*.pem
**/postgres_data/
CURSOR_MEMORY
27 changes: 19 additions & 8 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,21 @@ After running this command, open [http://localhost:3000/](http://localhost:3000/
git clone https://github.com/<your-username>/TradingGoose-Studio.git
cd TradingGoose-Studio

# Start TradingGoose
docker compose -f docker-compose.prod.yml up -d
# Copy the Docker Compose env template and set the required secrets/tags
cp apps/tradinggoose/.env.example.docker apps/tradinggoose/.env

docker compose --env-file ./apps/tradinggoose/.env -f docker-compose.prod.yml up -d
```

Your Docker `.env` must include `POSTGRES_*`, `NEXT_PUBLIC_APP_URL`,
`NEXT_PUBLIC_SOCKET_URL`, `BETTER_AUTH_SECRET`, `ENCRYPTION_KEY`,
`API_ENCRYPTION_KEY`, and `INTERNAL_API_SECRET`. The `ENCRYPTION_KEY` value
must be available to both the app and realtime containers. Use
`http://localhost:3002` for `NEXT_PUBLIC_SOCKET_URL` in local Compose runs, and
override it with a browser-reachable public URL for production. The prod and
Ollama compose files also require `IMAGE_TAG` and `OLLAMA_IMAGE_TAG`
respectively.

Access the application at [http://localhost:3000/](http://localhost:3000/)

#### Using Local Models
Expand All @@ -178,14 +189,13 @@ ollama pull gemma3:4b

```bash
# With NVIDIA GPU support
docker compose --profile local-gpu -f docker-compose.ollama.yml up -d
docker compose --env-file ./apps/tradinggoose/.env --profile gpu --profile setup -f docker-compose.ollama.yml up -d

# Without GPU (CPU only)
docker compose --profile local-cpu -f docker-compose.ollama.yml up -d
docker compose --env-file ./apps/tradinggoose/.env --profile cpu --profile setup -f docker-compose.ollama.yml up -d

# If hosting on a server, update the environment variables in the docker-compose.prod.yml file
# to include the server's public IP then start again (OLLAMA_URL to i.e. http://1.1.1.1:11434)
docker compose -f docker-compose.prod.yml up -d
# If hosting on a server, point OLLAMA_URL in .env to the remote endpoint
# before starting docker compose -f docker-compose.prod.yml up -d
```

### Option 3: Using VS Code / Cursor Dev Containers
Expand Down Expand Up @@ -238,7 +248,8 @@ If you prefer not to use Docker or Dev Containers:
cd apps/tradinggoose
```
- Copy `.env.example` to `.env`
- Configure required variables (DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL)
- Configure required variables (DATABASE_URL, NEXT_PUBLIC_APP_URL, BETTER_AUTH_SECRET, ENCRYPTION_KEY, INTERNAL_API_SECRET)
- Add `API_ENCRYPTION_KEY` if you want encrypted API-key storage in local development

3. **Set Up Database:**

Expand Down
168 changes: 36 additions & 132 deletions .github/workflows/images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,178 +5,82 @@ on:
branches: [main]
workflow_dispatch:

concurrency:
group: build-and-push-images
cancel-in-progress: false

permissions:
contents: read
packages: write
id-token: write

jobs:
build-amd64:
name: Build AMD64
build-images:
name: Build Images
runs-on: blacksmith-4vcpu-ubuntu-2404
strategy:
fail-fast: false
matrix:
include:
- dockerfile: ./docker/app.Dockerfile
ghcr_image: ghcr.io/tradinggoose/tradinggoose
ecr_repo_secret: ECR_APP
repo: tradinggoose
- dockerfile: ./docker/db.Dockerfile
ghcr_image: ghcr.io/tradinggoose/migrations
ecr_repo_secret: ECR_MIGRATIONS
repo: migrations
- dockerfile: ./docker/realtime.Dockerfile
ghcr_image: ghcr.io/tradinggoose/realtime
ecr_repo_secret: ECR_REALTIME
outputs:
registry: ${{ steps.login-ecr.outputs.registry }}
repo: realtime

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
aws-region: ${{ github.ref == 'refs/heads/main' && secrets.AWS_REGION || secrets.STAGING_AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
platforms: arm64

- name: Login to GHCR
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Login to Docker Hub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: useblacksmith/setup-docker-builder@v1

- name: Generate tags
id: meta
run: |
ECR_REGISTRY="${{ steps.login-ecr.outputs.registry }}"
ECR_REPO="${{ secrets[matrix.ecr_repo_secret] }}"
GHCR_IMAGE="${{ matrix.ghcr_image }}"

# ECR tags (always build for ECR)
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
ECR_TAG="latest"
else
ECR_TAG="staging"
set -euo pipefail

repo="${{ matrix.repo }}"
ghcr_image="ghcr.io/tradinggoose/${repo}"
sha_tag="${{ github.sha }}"
tags=("${ghcr_image}:${sha_tag}")

if [ "$GITHUB_REF" = "refs/heads/main" ]; then
dockerhub_image="docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${repo}"
tags+=("${ghcr_image}:latest")
tags+=("${dockerhub_image}:${sha_tag}")
tags+=("${dockerhub_image}:latest")
fi
ECR_IMAGE="${ECR_REGISTRY}/${ECR_REPO}:${ECR_TAG}"

# Build tags list
TAGS="${ECR_IMAGE}"

# Add GHCR tags only for main branch
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
GHCR_AMD64="${GHCR_IMAGE}:latest-amd64"
GHCR_SHA="${GHCR_IMAGE}:${{ github.sha }}-amd64"
TAGS="${TAGS},$GHCR_AMD64,$GHCR_SHA"
fi

echo "tags=${TAGS}" >> $GITHUB_OUTPUT
tags_csv=$(IFS=,; printf '%s' "${tags[*]}")
echo "tags=${tags_csv}" >> "$GITHUB_OUTPUT"

- name: Build and push images
uses: useblacksmith/build-push-action@v2
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
provenance: false
sbom: false

build-ghcr-arm64:
name: Build ARM64 (GHCR Only)
runs-on: linux-arm64-8-core
if: github.ref == 'refs/heads/main'
strategy:
fail-fast: false
matrix:
include:
- dockerfile: ./docker/app.Dockerfile
image: ghcr.io/tradinggoose/tradinggoose
- dockerfile: ./docker/db.Dockerfile
image: ghcr.io/tradinggoose/migrations
- dockerfile: ./docker/realtime.Dockerfile
image: ghcr.io/tradinggoose/realtime

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: useblacksmith/setup-docker-builder@v1

- name: Generate ARM64 tags
id: meta
run: |
IMAGE="${{ matrix.image }}"
echo "tags=${IMAGE}:latest-arm64,${IMAGE}:${{ github.sha }}-arm64" >> $GITHUB_OUTPUT

- name: Build and push ARM64 to GHCR
uses: useblacksmith/build-push-action@v2
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
provenance: false
sbom: false

create-ghcr-manifests:
name: Create GHCR Manifests
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: [build-amd64, build-ghcr-arm64]
if: github.ref == 'refs/heads/main'
strategy:
matrix:
include:
- image: ghcr.io/tradinggoose/tradinggoose
- image: ghcr.io/tradinggoose/migrations
- image: ghcr.io/tradinggoose/realtime

steps:
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create and push manifests
run: |
IMAGE_BASE="${{ matrix.image }}"

# Create latest manifest
docker manifest create "${IMAGE_BASE}:latest" \
"${IMAGE_BASE}:latest-amd64" \
"${IMAGE_BASE}:latest-arm64"
docker manifest push "${IMAGE_BASE}:latest"

# Create SHA manifest
docker manifest create "${IMAGE_BASE}:${{ github.sha }}" \
"${IMAGE_BASE}:${{ github.sha }}-amd64" \
"${IMAGE_BASE}:${{ github.sha }}-arm64"
docker manifest push "${IMAGE_BASE}:${{ github.sha }}"
provenance: true
sbom: true
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ It is built for analytics, research, charting, monitoring, and workflow automati
bun install
```

#### 2. Start PostgreSQL database
#### 2. Start PostgreSQL database and Redis
```
docker run --name tradinggoose-db `
-e POSTGRES_PASSWORD=postgres `
-e POSTGRES_USER=tradinggoose `
-e POSTGRES_PASSWORD=<your-postgres-password> `
-e POSTGRES_DB=tradinggoose `
-p 5432:5432 `
-d pgvector/pgvector:pg17

docker run -d --name tradinggoose-redis -p 6379:6379 redis
```

#### 3. Setup environment variables
```
cd apps/tradinggoose && cp .env.example .env
Expand All @@ -90,6 +94,25 @@ cd ../..
bun run dev:full
```

## Docker Compose

If you use Docker Compose, copy `apps/tradinggoose/.env.example.docker` to
`apps/tradinggoose/.env` and set the required secrets before running the
compose manifests. The `.env` must include `POSTGRES_*`,
`NEXT_PUBLIC_APP_URL`, `NEXT_PUBLIC_SOCKET_URL`, `BETTER_AUTH_SECRET`,
`ENCRYPTION_KEY`, `API_ENCRYPTION_KEY`, and `INTERNAL_API_SECRET`. The
`ENCRYPTION_KEY` value is shared by both the app and realtime containers, and
`API_ENCRYPTION_KEY` enables encrypted API-key storage in the app container.
`NEXT_PUBLIC_SOCKET_URL` should point at `http://localhost:3002` for local
Compose runs; production deployments must override it with a browser-reachable
public URL. The prod and Ollama compose files also require `IMAGE_TAG` and
`OLLAMA_IMAGE_TAG` respectively.

```
docker compose --env-file ./apps/tradinggoose/.env -f docker-compose.local.yml up
```


## Contributing

Pull requests are welcome.
Expand Down
Loading