diff --git a/.env b/.env deleted file mode 100644 index d2fb8ce..0000000 --- a/.env +++ /dev/null @@ -1,8 +0,0 @@ -# Backend -DEBUG=0 -MAX_UPLOAD_SIZE_MB=500 -TEMP_DIR=/tmp/audio_splitter_web -CLEANUP_AFTER_SECONDS=3600 - -# Frontend (development) -VITE_BACKEND_URL=http://localhost:8000 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..95739ea --- /dev/null +++ b/.env.example @@ -0,0 +1,26 @@ +# ------------------------------------------------------------------------------ +# Production Environment Variables +# ------------------------------------------------------------------------------ + +# Backend +DEBUG=0 +MAX_UPLOAD_SIZE_MB=500 +CLEANUP_AFTER_SECONDS=3600 + +# Backend data directory (bind mount) +# This directory will store all temporary files during splitting. +# It can get large (audio files), so place it on a partition with enough space. +BACKEND_DATA_DIR=/var/lib/audio_splitter_data + +# Ports +BACKEND_PORT=8000 +FRONTEND_PORT=5173 + +# ------------------------------------------------------------------------------ +# Development Overrides (docker-compose.override.yaml) +# ------------------------------------------------------------------------------ +# These are only used when docker-compose.override.yaml is present. +# They override the production settings for local development. + +# Frontend (development) +VITE_BACKEND_URL=http://localhost:8000 diff --git a/.gitea/workflows/build_image.yaml b/.gitea/workflows/build_image.yaml new file mode 100644 index 0000000..7e9c660 --- /dev/null +++ b/.gitea/workflows/build_image.yaml @@ -0,0 +1,63 @@ +name: Build and Push Docker Image + +on: + pull_request: + types: [closed] + branches: [ main ] + +env: + REGISTRY: git.vmn.su + OWNER: max + REPO: audio_splitter + +jobs: + build-and-push-backend: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Log in to Gitea Container Registry + run: | + echo "${{ secrets.CI_PUSHER_GITEA_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin + + - name: Build backend image + run: | + docker build -t ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_backend:${{ github.sha }} -f ./web/backend/Dockerfile . + docker tag ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_backend:${{ github.sha }} ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_backend:latest + + - name: Push backend image + run: | + docker push ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_backend:${{ github.sha }} + docker push ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_backend:latest + + + build-and-push-frontend: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Log in to Gitea Container Registry + run: | + echo "${{ secrets.CI_PUSHER_GITEA_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin + + - name: Build frontend image + run: | + docker build -t ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_frontend:${{ github.sha }} -f ./web/frontend/Dockerfile ./web/frontend + docker tag ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_frontend:${{ github.sha }} ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_frontend:latest + + - name: Push frontend image + run: | + docker push ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_frontend:${{ github.sha }} + docker push ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}_frontend:latest + + + notify-deployment-server: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Trigger the webhook on the deployment server to start pulling the images + run: curl "https://webhook.vmn.su/hooks/pull-audio-splitter" diff --git a/.gitignore b/.gitignore index fdf025f..12cd3a5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ test_data/ venv/ web/frontend/node_modules TODO.md +.env diff --git a/docker-compose.override.yaml b/docker-compose.override.yaml new file mode 100644 index 0000000..4c9b1fa --- /dev/null +++ b/docker-compose.override.yaml @@ -0,0 +1,37 @@ +services: + backend: + build: + context: . + dockerfile: web/backend/Dockerfile + volumes: + # Bind mount for source code (hot-reload for Python) + - ./web/backend:/app/backend + - ./audio_splitter:/app/audio_splitter + - ./setup.py:/app/setup.py + - ./pyproject.toml:/app/pyproject.toml + # Development data directory (overrides production) + - "./dev_data:/tmp/audio_splitter_web" + environment: + - DEBUG=1 + - PYTHONUNBUFFERED=1 + ports: + - "8000:8000" + + frontend: + build: + context: ./web/frontend + # Use the same Dockerfile, but override CMD for development + dockerfile: Dockerfile + command: ["npm", "run", "dev", "--", "--host", "0.0.0.0"] + volumes: + # Bind mount for source code (hot-reload for Vite) + - ./web/frontend:/app + - node_modules:/app/node_modules + environment: + - BACKEND_URL=http://backend:8000 + - VITE_BACKEND_URL=http://backend:8000 + ports: + - "5173:5173" + +volumes: + node_modules: diff --git a/docker-compose.yaml b/docker-compose.yaml index bd7a218..48151a8 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,29 +1,21 @@ services: backend: - build: - context: . - dockerfile: web/backend/Dockerfile + image: git.vmn.su/max/audio_splitter_backend:latest ports: - - "8000:8000" + - "${BACKEND_PORT:-8000}:8000" volumes: - - /tmp/audio_splitter_web:/tmp/audio_splitter_web # Bind mount + # Bind mount for persistent data storage. + # Set BACKEND_DATA_DIR in .env to point to your data directory. + - "${BACKEND_DATA_DIR:-/var/lib/audio_splitter_data}:/tmp/audio_splitter_web" environment: - PYTHONUNBUFFERED=1 - - DEBUG=1 + - DEBUG=${DEBUG:-0} restart: unless-stopped frontend: - build: - context: ./web/frontend - dockerfile: Dockerfile + image: git.vmn.su/max/audio_splitter_frontend:latest ports: - - "5173:80" - volumes: - - ./web/frontend:/app - - /app/node_modules - environment: - - BACKEND_URL=http://backend:8000 - - VITE_BACKEND_URL=http://backend:8000 + - "${FRONTEND_PORT:-5173}:80" depends_on: - backend restart: unless-stopped