Compare commits

..

19 Commits

Author SHA1 Message Date
hackerESQ 1cad9b83fb Update build-and-push-images.yml 2024-12-20 23:05:05 -06:00
hackerESQ 780ee76dc3 Update build-and-push-images.yml 2024-12-20 23:02:36 -06:00
hackerESQ 4d8e17f59f Update build-and-push-images.yml 2024-12-20 22:57:02 -06:00
hackerESQ 21c27e22da Update build-and-push-images.yml 2024-12-20 22:55:56 -06:00
hackerESQ 2e978089b5 rename workflow 2024-12-20 22:25:39 -06:00
hackerESQ 803fe7147e Set up github workflow to build and push images 2024-12-20 22:24:54 -06:00
hackerESQ 6490364a5d chore: update dockerignore 2024-12-20 16:19:07 -06:00
hackerESQ 2ad773952e chore: slim down docker build 2024-12-19 21:53:50 -06:00
hackerESQ 138e71107e chore: clean up dockerfile and entrypoint script 2024-12-19 21:34:58 -06:00
hackerESQ bde399f589 chore: move dockerfile back to repo 2024-12-19 21:10:00 -06:00
hackerESQ 8a43602363 docs: clarify upsert 2024-12-18 16:03:32 -06:00
hackerESQ 5a56790fd4 docs: more refinement and word choice 2024-12-18 16:03:01 -06:00
hackerESQ 892f681174 docs: add self-hosted llm to readme intro section 2024-12-18 15:53:09 -06:00
hackerESQ 997b5420ee Merge pull request #44 from investbrainapp/create-docker-image
Use the investbrainapp/investbrain docker image
2024-12-17 18:28:03 -06:00
hackerESQ 643bbe3af2 wait for db to be ready in order to migrate 2024-12-16 21:54:59 -06:00
hackerESQ f85f0f19b9 wip 2024-12-16 21:33:45 -06:00
hackerESQ 3f9a1bafa0 Merge pull request #37 from investbrainapp/feat-use-openai-compatible-endpoints
Feat use openai compatible endpoints
2024-12-06 16:10:54 -06:00
hackerESQ 6f72a03ecf fix: specifically use factory import 2024-12-06 16:10:27 -06:00
hackerESQ 5b8e4c634e fix: remove validation which could prevent selfhosting w ollama 2024-12-06 16:09:03 -06:00
12 changed files with 131 additions and 63 deletions
+10
View File
@@ -0,0 +1,10 @@
.git
.env
node_modules
packages
vendor
tests
.DS_Store
vapor.yml
.vapor
storage
+1 -1
View File
@@ -52,7 +52,7 @@ QUEUE_CONNECTION=redis
CACHE_STORE=redis
REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1
REDIS_HOST=investbrain-redis
REDIS_PATH=/tmp/database_server.sock
REDIS_PASSWORD=null
REDIS_PORT=6379
@@ -0,0 +1,49 @@
name: Build and push Docker images
on:
push:
tags:
- "v*"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GIT_HUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract version from tag
id: extract-version
run: |
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
file: ./docker/Dockerfile
push: true
tags: |
investbrainapp/investbrain:latest
investbrainapp/investbrain:${{ env.version }}
ghcr.io/investbrainapp/investbrain:latest
ghcr.io/investbrainapp/investbrain:${{ env.version }}
+3 -3
View File
@@ -20,7 +20,7 @@ Investbrain is a smart open-source investment tracker that helps you manage, tra
## Under the hood
Investbrain is a Laravel PHP web application that leverages Livewire and Tailwind for its frontend. Most databases should work, including MySQL and SQLite. Out of the box, we feature three market data providers: [Yahoo Finance](https://finance.yahoo.com/), [Finnhub](https://finnhub.io/pricing-stock-api-market-data), and [Alpha Vantage](https://www.alphavantage.co/support/). But we also offer an extensible market data provider interface for intrepid developers to create their own! We also offer an integration with OpenAI for our ["chat with your holdings"](#chat-with-your-holdings) capability. Finally, of course we have robust support for i18n, a11y, and dark mode.
Investbrain is a Laravel PHP web application that leverages Livewire and Tailwind for its frontend. Most databases should work, including MySQL and SQLite. Out of the box, we feature three market data providers: [Yahoo Finance](https://finance.yahoo.com/), [Finnhub](https://finnhub.io/pricing-stock-api-market-data), and [Alpha Vantage](https://www.alphavantage.co/support/). But we also offer an extensible market data provider interface for intrepid developers to create their own! We also offer integrations with OpenAI and Ollama for our ["chat with your holdings"](#chat-with-your-holdings) capability. Finally, of course we have robust support for i18n, a11y, and dark mode.
## Self hosting
@@ -109,11 +109,11 @@ Feel free to submit a PR with any custom providers you create.
## Import / Export
Investbrain includes a convenient feature which allows you to import and export portfolios and transaction data.
Investbrain includes a convenient feature which allows you to maintain the portability of your portfolios and transaction data.
### Import
Imports are "upserted" to the database. If the record does not already exist in the database, the record will be created. However, when a portfolio or transaction exists (the record's ID matches an existing record), the record will be updated. This way, you can simultaneously create new records, but also bulk update records.
Imports are "upserted" to the database. If the record does not already exist in the database, the record will be created. However, when a portfolio or transaction exists (i.e. the record's ID matches an existing record), the record will be updated. This way, you can simultaneously create new records, but also bulk update records.
### Export
+12 -3
View File
@@ -3,9 +3,7 @@ networks:
driver: bridge
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
image: investbrainapp/investbrain:latest
container_name: investbrain-app
restart: unless-stopped
tty: true
@@ -15,8 +13,18 @@ services:
- .:/var/www/app:delegated
depends_on:
- mysql
- redis
networks:
- investbrain-network
redis:
image: redis:alpine
container_name: investbrain-redis
restart: unless-stopped
tty: true
networks:
- investbrain-network
volumes:
- investbrain-redis:/data
nginx:
image: nginx:alpine
container_name: investbrain-nginx
@@ -46,4 +54,5 @@ services:
networks:
- investbrain-network
volumes:
investbrain-redis:
investbrain-mysql:
-1
View File
@@ -1 +0,0 @@
dump.rdb
+34 -30
View File
@@ -1,47 +1,51 @@
FROM php:8.3-fpm
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# Set the working directory
COPY . /var/www/app
WORKDIR /var/www/app
# Set permissions
RUN chown -R www-data:www-data . \
&& chmod -R 775 ./storage \
&& chmod +x ./docker/entrypoint.sh \
# Install common php extension dependencies
RUN apt-get update && apt-get install -y \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
zlib1g-dev \
libzip-dev \
unzip \
libicu-dev \
git \
curl \
redis \
supervisor \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
zip \
pdo_mysql \
mysqli \
intl
&& apt-get update && apt-get install -y \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
zlib1g-dev \
libzip-dev \
unzip \
libicu-dev \
git \
curl \
supervisor \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
zip \
pdo_mysql \
mysqli \
intl \
# Install Node.js and npm
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm@latest
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm@latest
# Copy over supervisor configuration
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Update permissions
RUN chown -R www-data:www-data . \
&& chmod -R 775 ./storage \
&& chmod +x ./docker/entrypoint.sh
# install composer
# Install composer
COPY --from=composer:2.6.5 /usr/bin/composer /usr/local/bin/composer
# Serve on port 80
EXPOSE 80
# Set up healthcheck
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f http://localhost || exit 1
# Run everything else
ENTRYPOINT ["/bin/bash", "./docker/entrypoint.sh"]
CMD ["./docker/entrypoint.sh"]
Executable → Regular
+20 -10
View File
@@ -2,20 +2,17 @@
cd /var/www/app
echo "====================== Running entrypoint script... ====================== "
echo -e "\n====================== Running entrypoint script... ====================== "
if [ ! -f ".env" ]; then
echo " > Ope, gotta create an .env file!"
cp .env.example .env
fi
echo "====================== Checking for updates... ====================== "
/usr/bin/git pull
echo "====================== Installing Composer dependencies... ====================== "
echo -e "\n====================== Installing Composer dependencies... ====================== "
/usr/local/bin/composer install
echo "====================== Validating environment... ====================== "
echo -e "\n====================== Validating environment... ====================== "
if [ $(stat -c '%U' .) != "www-data" ]; then
echo " > Setting correct permissions for pwd..."
chown -R www-data:www-data .
@@ -33,12 +30,25 @@ if [ ! -L "public/storage" ]; then
/usr/local/bin/php artisan storage:link
fi
echo "====================== Installing NPM dependencies and building frontend... ====================== "
echo -e "\n====================== Installing NPM dependencies and building frontend... ====================== "
/usr/bin/npm install
/usr/bin/npm run build
echo "====================== Running migrations... ====================== "
/usr/local/bin/php artisan migrate --force
echo -e "\n====================== Running migrations... ====================== "
run_migrations() {
/usr/local/bin/php artisan migrate --force
}
RETRIES=30
DELAY=5
until run_migrations; do
RETRIES=$((RETRIES-1))
if [ $RETRIES -le 0 ]; then
echo " > Database is not ready after multiple attempts. Exiting..."
exit 1
fi
echo " > Waiting for database to be ready... retrying in $DELAY seconds."
sleep $DELAY
done
echo "====================== Spinning up Supervisor daemon... ====================== "
echo -e "\n====================== Spinning up Supervisor daemon... ====================== "
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
-2
View File
@@ -1,2 +0,0 @@
# Redis RDB and AOF file location
dir /var/www/app/docker
-7
View File
@@ -11,13 +11,6 @@ autorestart=true
stdout_logfile=/var/log/supervisor/php.log
stderr_logfile=/var/log/supervisor/php_error.log
[program:redis]
command=redis-server /var/www/app/docker/redis.conf
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/redis.log
stderr_logfile=/var/log/supervisor/redis_error.log
[program:scheduler]
command=php artisan schedule:work
autorestart=true
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "investbrain",
"name": "app",
"lockfileVersion": 3,
"requires": true,
"packages": {
@@ -5,7 +5,7 @@ use App\Models\AiChat;
use App\Models\Holding;
use Illuminate\Database\Eloquent\Model;
use Livewire\Volt\Component;
use OpenAI;
use OpenAI\Factory;
use OpenAI\Responses\StreamResponse;
new class extends Component {
@@ -202,10 +202,6 @@ new class extends Component {
$organization = config('openai.organization');
$baseUri = config('openai.base_uri');
if (! is_string($apiKey) || ($organization !== null && ! is_string($organization))) {
throw new \InvalidArgumentException('The OpenAI API Key is missing. Please publish the [openai.php] configuration file and set the [api_key].');
}
return OpenAI::factory()
->withApiKey($apiKey)
->withOrganization($organization)