diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
new file mode 100644
index 0000000..11fd28d
--- /dev/null
+++ b/.github/workflows/docker-build.yml
@@ -0,0 +1,146 @@
+name: Publish Docker image
+
+on:
+  schedule:
+    - cron: '24 0 * * 1'
+  workflow_dispatch:
+  push:
+    branches:
+      - 'master'
+    tags:
+      - 'v*'
+  pull_request:
+    branches:
+      - 'master'
+
+env:
+  IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+  build-and-push-image:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      packages: write
+      id-token: write # needed for signing the images with GitHub OIDC Token
+      attestations: write
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+        with:
+          fetch-depth: 1
+
+      # Install the cosign tool except on PR
+      # https://github.com/sigstore/cosign-installer
+      - name: Install Cosign
+        if: github.event_name != 'pull_request'
+        uses: sigstore/cosign-installer@v3.3.0
+        with:
+          cosign-release: 'v2.2.2'
+
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v2
+
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v2
+
+      - name: Login to GitHub Container Registry
+        if: github.event_name != 'pull_request'
+        uses: docker/login-action@v2
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      # Extract metadata (tags, labels) for Docker
+      # https://github.com/docker/metadata-action
+      - name: Extract Docker metadata app
+        id: meta-app
+        uses: docker/metadata-action@v4.4.0
+        with:
+          images: ghcr.io/${{ env.IMAGE_NAME }}-app
+          tags: |
+            type=ref,event=branch
+            type=ref,event=pr
+            type=semver,pattern={{version}}
+            type=semver,pattern={{major}}.{{minor}}
+            type=sha,format=long
+
+      - name: Extract Docker metadata backend
+        id: meta-backend
+        uses: docker/metadata-action@v4.4.0
+        with:
+          images: ghcr.io/${{ env.IMAGE_NAME }}-backend
+          tags: |
+            type=ref,event=branch
+            type=ref,event=pr
+            type=semver,pattern={{version}}
+            type=semver,pattern={{major}}.{{minor}}
+            type=sha,format=long
+
+      # Build and push Docker image with Buildx (don't push on PR)
+      # https://github.com/docker/build-push-action
+      - name: Build and Push App container images
+        uses: docker/build-push-action@v4
+        id: build-and-push-app
+        with:
+          context: .
+          platforms: linux/amd64,linux/arm64
+          push: ${{ github.event_name != 'pull_request' }}
+          tags: ${{ steps.meta-app.outputs.tags }}
+          labels: ${{ steps.meta-app.outputs.labels }}
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
+          file: ./app.dockerfile
+
+      - name: Build and Push Backend container images
+        uses: docker/build-push-action@v4
+        id: build-and-push-backend
+        with:
+          context: .
+          platforms: linux/amd64,linux/arm64
+          push: ${{ github.event_name != 'pull_request' }}
+          tags: ${{ steps.meta-backend.outputs.tags }}
+          labels: ${{ steps.meta-backend.outputs.labels }}
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
+          file: ./backend.dockerfile
+
+      - name: Sign the app images with GitHub OIDC Token
+        env:
+          DIGEST: ${{ steps.build-and-push-app.outputs.digest }}
+          TAGS: ${{ steps.meta-app.outputs.tags }}
+        run: |
+          images=""
+          for tag in ${TAGS}; do
+            images+="${tag}@${DIGEST} "
+          done
+          cosign sign --yes ${images}
+
+      - name: Sign the backend images with GitHub OIDC Token
+        env:
+          DIGEST: ${{ steps.build-and-push-backend.outputs.digest }}
+          TAGS: ${{ steps.meta-backend.outputs.tags }}
+        run: |
+          images=""
+          for tag in ${TAGS}; do
+            images+="${tag}@${DIGEST} "
+          done
+          cosign sign --yes ${images}
+
+      - name: Attest app
+        uses: actions/attest-build-provenance@v1
+        id: attest-app
+        with:
+          subject-name: ghcr.io/${{ env.IMAGE_NAME }}-app
+          subject-digest: ${{ steps.build-and-push-app.outputs.digest }}
+          push-to-registry: true
+
+      - name: Attest backend
+        uses: actions/attest-build-provenance@v1
+        id: attest-backend
+        with:
+          subject-name: ghcr.io/${{ env.IMAGE_NAME }}-backend
+          subject-digest: ${{ steps.build-and-push-backend.outputs.digest }}
+          push-to-registry: true
diff --git a/app.dockerfile b/app.dockerfile
index 105cf86..8337171 100644
--- a/app.dockerfile
+++ b/app.dockerfile
@@ -1,7 +1,7 @@
 FROM node:alpine
 
-ARG NEXT_PUBLIC_WS_URL
-ARG NEXT_PUBLIC_API_URL
+ARG NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
+ARG NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
 ENV NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL}
 ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
 
diff --git a/backend.dockerfile b/backend.dockerfile
index 4886573..66de9dc 100644
--- a/backend.dockerfile
+++ b/backend.dockerfile
@@ -1,18 +1,16 @@
 FROM node:slim
 
 ARG SEARXNG_API_URL
+ENV SEARXNG_API_URL=${SEARXNG_API_URL}
 
 WORKDIR /home/perplexica
 
 COPY src /home/perplexica/src
 COPY tsconfig.json /home/perplexica/
-COPY config.toml /home/perplexica/
 COPY drizzle.config.ts /home/perplexica/
 COPY package.json /home/perplexica/
 COPY yarn.lock /home/perplexica/
 
-RUN sed -i "s|SEARXNG = \".*\"|SEARXNG = \"${SEARXNG_API_URL}\"|g" /home/perplexica/config.toml
-
 RUN mkdir /home/perplexica/data
 
 RUN yarn install 
diff --git a/docker-compose.yaml b/docker-compose.yaml
index d6f9203..d3892e5 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -21,6 +21,7 @@ services:
       - 3001:3001
     volumes:
       - backend-dbstore:/home/perplexica/data
+      - ./config.toml:/home/perplexica/config.toml
     extra_hosts:
       - 'host.docker.internal:host-gateway'
     networks:
diff --git a/sample.config.toml b/sample.config.toml
index f6c6943..3a19b7e 100644
--- a/sample.config.toml
+++ b/sample.config.toml
@@ -8,5 +8,5 @@ GROQ = "" # Groq API key - gsk_1234567890abcdef1234567890abcdef
 ANTHROPIC = "" # Anthropic API key - sk-ant-1234567890abcdef1234567890abcdef
 
 [API_ENDPOINTS]
-SEARXNG = "http://localhost:32768" # SearxNG API URL
+SEARXNG = "" # SearxNG API URL - http://localhost:32768
 OLLAMA = "" # Ollama API URL - http://host.docker.internal:11434
\ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
index 9ebc182..6d829ed 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -40,7 +40,8 @@ export const getGroqApiKey = () => loadConfig().API_KEYS.GROQ;
 
 export const getAnthropicApiKey = () => loadConfig().API_KEYS.ANTHROPIC;
 
-export const getSearxngApiEndpoint = () => loadConfig().API_ENDPOINTS.SEARXNG;
+export const getSearxngApiEndpoint = () =>
+  loadConfig().API_ENDPOINTS.SEARXNG || process.env['SEARXNG_API_URL'];
 
 export const getOllamaApiEndpoint = () => loadConfig().API_ENDPOINTS.OLLAMA;