Compare commits

...

16 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
11 changed files with 130 additions and 58 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 CACHE_STORE=redis
REDIS_CLIENT=predis REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1 REDIS_HOST=investbrain-redis
REDIS_PATH=/tmp/database_server.sock REDIS_PATH=/tmp/database_server.sock
REDIS_PASSWORD=null REDIS_PASSWORD=null
REDIS_PORT=6379 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 ## 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 ## Self hosting
@@ -109,11 +109,11 @@ Feel free to submit a PR with any custom providers you create.
## Import / Export ## 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 ### 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 ### Export
+12 -3
View File
@@ -3,9 +3,7 @@ networks:
driver: bridge driver: bridge
services: services:
app: app:
build: image: investbrainapp/investbrain:latest
context: .
dockerfile: docker/Dockerfile
container_name: investbrain-app container_name: investbrain-app
restart: unless-stopped restart: unless-stopped
tty: true tty: true
@@ -15,8 +13,18 @@ services:
- .:/var/www/app:delegated - .:/var/www/app:delegated
depends_on: depends_on:
- mysql - mysql
- redis
networks: networks:
- investbrain-network - investbrain-network
redis:
image: redis:alpine
container_name: investbrain-redis
restart: unless-stopped
tty: true
networks:
- investbrain-network
volumes:
- investbrain-redis:/data
nginx: nginx:
image: nginx:alpine image: nginx:alpine
container_name: investbrain-nginx container_name: investbrain-nginx
@@ -46,4 +54,5 @@ services:
networks: networks:
- investbrain-network - investbrain-network
volumes: volumes:
investbrain-redis:
investbrain-mysql: investbrain-mysql:
-1
View File
@@ -1 +0,0 @@
dump.rdb
+34 -30
View File
@@ -1,47 +1,51 @@
FROM php:8.3-fpm FROM php:8.3-fpm
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND=noninteractive
# Set the working directory # Set the working directory
COPY . /var/www/app COPY . /var/www/app
WORKDIR /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 # Install common php extension dependencies
RUN apt-get update && apt-get install -y \ && apt-get update && apt-get install -y \
libfreetype-dev \ libfreetype-dev \
libjpeg62-turbo-dev \ libjpeg62-turbo-dev \
libpng-dev \ libpng-dev \
zlib1g-dev \ zlib1g-dev \
libzip-dev \ libzip-dev \
unzip \ unzip \
libicu-dev \ libicu-dev \
git \ git \
curl \ curl \
redis \ supervisor \
supervisor \ && docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) \
&& docker-php-ext-install -j$(nproc) \ gd \
gd \ zip \
zip \ pdo_mysql \
pdo_mysql \ mysqli \
mysqli \ intl \
intl
# Install Node.js and npm # Install Node.js and npm
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \ && apt-get install -y nodejs \
&& npm install -g npm@latest && npm install -g npm@latest
# Copy over supervisor configuration # Copy over supervisor configuration
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Update permissions # Install composer
RUN chown -R www-data:www-data . \
&& chmod -R 775 ./storage \
&& chmod +x ./docker/entrypoint.sh
# install composer
COPY --from=composer:2.6.5 /usr/bin/composer /usr/local/bin/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 # Run everything else
ENTRYPOINT ["/bin/bash", "./docker/entrypoint.sh"]
CMD ["./docker/entrypoint.sh"] CMD ["./docker/entrypoint.sh"]
Executable → Regular
+20 -10
View File
@@ -2,20 +2,17 @@
cd /var/www/app cd /var/www/app
echo "====================== Running entrypoint script... ====================== " echo -e "\n====================== Running entrypoint script... ====================== "
if [ ! -f ".env" ]; then if [ ! -f ".env" ]; then
echo " > Ope, gotta create an .env file!" echo " > Ope, gotta create an .env file!"
cp .env.example .env cp .env.example .env
fi fi
echo "====================== Checking for updates... ====================== " echo -e "\n====================== Installing Composer dependencies... ====================== "
/usr/bin/git pull
echo "====================== Installing Composer dependencies... ====================== "
/usr/local/bin/composer install /usr/local/bin/composer install
echo "====================== Validating environment... ====================== " echo -e "\n====================== Validating environment... ====================== "
if [ $(stat -c '%U' .) != "www-data" ]; then if [ $(stat -c '%U' .) != "www-data" ]; then
echo " > Setting correct permissions for pwd..." echo " > Setting correct permissions for pwd..."
chown -R www-data:www-data . chown -R www-data:www-data .
@@ -33,12 +30,25 @@ if [ ! -L "public/storage" ]; then
/usr/local/bin/php artisan storage:link /usr/local/bin/php artisan storage:link
fi fi
echo "====================== Installing NPM dependencies and building frontend... ====================== " echo -e "\n====================== Installing NPM dependencies and building frontend... ====================== "
/usr/bin/npm install /usr/bin/npm install
/usr/bin/npm run build /usr/bin/npm run build
echo "====================== Running migrations... ====================== " echo -e "\n====================== Running migrations... ====================== "
/usr/local/bin/php artisan migrate --force 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 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 stdout_logfile=/var/log/supervisor/php.log
stderr_logfile=/var/log/supervisor/php_error.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] [program:scheduler]
command=php artisan schedule:work command=php artisan schedule:work
autorestart=true autorestart=true
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"name": "investbrain", "name": "app",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {