diff --git a/.github/workflows/build-docker.yaml b/.github/workflows/build-docker.yaml new file mode 100644 index 0000000..cf7db15 --- /dev/null +++ b/.github/workflows/build-docker.yaml @@ -0,0 +1,61 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Install Docker Compose + run: | + sudo curl -L "https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + + - name: Prepare QEMU Environment + uses: docker/setup-qemu-action@v1 + + - name: Configure Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Authenticate Docker Hub + uses: docker/login-action@v1 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get version from app/params.json file + id: get_version + run: | + VERSION=$(jq -r '.VERSION' < app/params.json) + echo "version=$VERSION" >> $GITHUB_ENV + + - name: Build and Push Image to Docker Hub + env: + FLASK_RUN_HOST: "0.0.0.0" + FLASK_RUN_PORT: "8080" + SECRET_KEY: "none" + GOOGLE_GEMINI_API_KEY: "none" + ENABLE_GEMINI_API: "false" + GEMINI_MODEL: "gemini-2.0-flash" + run: | + docker-compose -f docker-compose.yaml config > docker-stack.yml + docker buildx create --use + docker buildx build --push --platform linux/amd64,linux/arm64 \ + --tag ${{ secrets.DOCKERHUB_USERNAME }}/bookworm:latest \ + --tag ${{ secrets.DOCKERHUB_USERNAME }}/bookworm:stable \ + --tag ${{ secrets.DOCKERHUB_USERNAME }}/bookworm:${{ env.version }} \ + --file Dockerfile . + + # - name: Clean Up Environment + # run: docker-compose down \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1ee8711 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Use the official Python image from the Docker Hub +FROM python:3.10-slim + +# Set the working directory in the container +WORKDIR /app + +# Copy the requirements file into the container +COPY requirements.txt . + +# Install the dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the rest of the application code into the container (app -> /app/app, run.py -> /app) +COPY app /app/app +COPY run.py /app/ + +# Set environment variables +ENV FLASK_RUN_HOST=0.0.0.0 +ENV FLASK_RUN_PORT=8080 + +# Expose the port the app runs on +EXPOSE 8080 + +# Run the application +CMD ["python", "run.py"] \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index fa5657c..0026cdd 100644 --- a/app/routes.py +++ b/app/routes.py @@ -218,4 +218,9 @@ def api_chat_status(): 'initialized': gemini_ai.initialized, 'available': gemini_ai.is_available(), 'model': gemini_ai.model - }) \ No newline at end of file + }) + +@main_bp.route('/healthcheck', methods=['GET']) +def healthcheck(): + """Health check endpoint for the application""" + return jsonify({'status': 'ok'}), 200 \ No newline at end of file diff --git a/app/static/images/Logo.ico b/app/static/images/Logo.ico new file mode 100644 index 0000000..0296b8f Binary files /dev/null and b/app/static/images/Logo.ico differ diff --git a/app/static/images/Logo.png b/app/static/images/Logo.png new file mode 100644 index 0000000..8379542 Binary files /dev/null and b/app/static/images/Logo.png differ diff --git a/app/templates/base.html b/app/templates/base.html index bb063d2..272349f 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -6,7 +6,7 @@
+
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..8f52ebb
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,43 @@
+version: '3.8'
+
+services:
+ web:
+ container_name: bookworm_web
+ image: mwcurtis20/bookworm:stable
+ build: .
+ ports:
+ - "8080:${FLASK_RUN_PORT}"
+ environment:
+ - FLASK_RUN_HOST=${FLASK_RUN_HOST}
+ - FLASK_RUN_PORT=${FLASK_RUN_PORT}
+ - SECRET_KEY=${SECRET_KEY}
+ - GOOGLE_GEMINI_API_KEY=${GOOGLE_GEMINI_API_KEY}
+ - ENABLE_GEMINI_API=${ENABLE_GEMINI_API}
+ - GEMINI_MODEL=${GEMINI_MODEL}
+ labels:
+ - "com.centurylinklabs.watchtower.scope=bookworm"
+ networks:
+ - internal_bookworm_net
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8080/healthcheck"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ watchtower:
+ image: containrrr/watchtower
+ container_name: bookworm_watchtower
+ environment:
+ - REPO_USER=${REPO_USER}
+ - REPO_PASS=${REPO_PASS}
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ labels:
+ - "com.centurylinklabs.watchtower.scope=bookworm"
+ networks:
+ - internal_bookworm_net
+ command: --debug --scope bookworm --cleanup --interval 300
+ restart: unless-stopped
+networks:
+ internal_bookworm_net:
+ external: false
\ No newline at end of file