diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..37f63f90
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,21 @@
+# Exclude everything from the Docker context by default.
+# The backend image is built from the repository root because uv keeps the
+# workspace lockfile at the root level.
+*
+
+# Workspace dependency files
+!pyproject.toml
+!uv.lock
+
+# Backend source and config
+!backend/
+!backend/pyproject.toml
+!backend/alembic.ini
+!backend/alembic/
+!backend/alembic/**
+!backend/app/
+!backend/app/**
+!backend/entrypoint.sh
+
+# Do not ship test code in the image
+backend/tests/
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 083f2e9b..b33aa92c 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -75,7 +75,7 @@ jobs:
- name: backend
image: librislog-api
dockerfile: ./backend/Dockerfile
- context: ./backend
+ context: .
arch: [amd64, arm64]
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 6c078b5f..e52af498 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -112,7 +112,8 @@ jobs:
- name: Build backend image
uses: docker/build-push-action@v7
with:
- context: ./backend
+ context: .
+ file: ./backend/Dockerfile
tags: librislog-e2e-backend
load: true
build-args: |
diff --git a/.gitignore b/.gitignore
index edabd7dd..87c957de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -216,8 +216,6 @@ __marimo__/
# Streamlit
.streamlit/secrets.toml
-/.memsearch
-/.playwright-mcp
/ideas.txt
/backend/data/
@@ -227,7 +225,14 @@ __marimo__/
!frontend/src/lib
cookies.txt
profile-snapshot
-.plan/
+
node_modules/
/*.png
-*-snapshot.md
\ No newline at end of file
+*-snapshot.md
+
+# AI tools
+/.memsearch
+/.playwright-mcp
+/.sverklo
+.plan/
+/.opencode
\ No newline at end of file
diff --git a/README.md b/README.md
index 5ef60260..52f90e6c 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
-
+