diff --git a/.dockerignore b/.dockerignore
index 8d91ebee..e229553b 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,5 +1,8 @@
 .vscode
+.git
+.woodpecker
 .dockerignore
 Dockerfile
+compose.yaml
 ui
-db.sqlite3
\ No newline at end of file
+db.sqlite3
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
new file mode 100644
index 00000000..9a14121a
--- /dev/null
+++ b/.github/workflows/main.yaml
@@ -0,0 +1,64 @@
+name: build
+
+on:
+  push:
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  build-frontend:
+    runs-on: [self-hosted]
+    steps:
+      - uses: actions/checkout@v3
+      - name: Login to Docker Hub
+        uses: docker/login-action@v3
+        if: github.event_name != 'pull_request'
+        with:
+          username: ${{ vars.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3
+      - name: Testerino
+        run: |
+          env
+          exit 1
+      - name: Build and push
+        uses: docker/build-push-action@v6
+        with:
+          context: ./ui
+          push: github.event_name != 'pull_request'
+          pull: true
+          tags: |
+            ksetcomp/brucifer-karte-2022:latest
+            ksetcomp/brucifer-karte-2022:${{ github.ref }}
+
+  build-backend:
+    runs-on: [self-hosted]
+    steps:
+      - uses: actions/checkout@v3
+      - name: Login to Docker Hub
+        uses: docker/login-action@v3
+        if: github.event_name != 'pull_request'
+        with:
+          username: ${{ vars.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3
+      - name: Build backend container
+        run: |
+          pwd;
+          env;
+          ls -allah
+
+  notify-watchtower:
+    runs-on: [self-hosted]
+    needs: [build-frontend, build-backend]
+    steps:
+      - name: Notify Watchtower
+        run: |
+          curl -sL -v \
+            --header 'Authorization: Bearer ${{ secrets.WATCHTOWER_TOKEN }}' \
+            "${{ vars.WATCHTOWER_URL }}/v1/update"
+
diff --git a/.woodpecker/.env.yaml b/.woodpecker/.env.yaml
new file mode 100644
index 00000000..37f252d9
--- /dev/null
+++ b/.woodpecker/.env.yaml
@@ -0,0 +1,10 @@
+---
+when:
+  - event: push
+    # branch: ${CI_REPO_DEFAULT_BRANCH}
+
+steps:
+  - name: env
+    image: alpine
+    commands:
+      - env
diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml
new file mode 100644
index 00000000..90a9120f
--- /dev/null
+++ b/.woodpecker/build.yaml
@@ -0,0 +1,38 @@
+depends_on:
+  - env
+
+when:
+  - event: push
+    # branch: ${CI_REPO_DEFAULT_BRANCH}
+
+steps:
+  - name: build
+    image: docker
+    environment:
+      _DOCKER_BUILD_IMAGE: "index.docker.io/ksetcomp/brucifer-karte-2022"
+      _DOCKER_USERNAME:
+        from_secret: DOCKER_HUB_USERNAME
+      _DOCKER_PASSWORD:
+        from_secret: DOCKER_HUB_PASSWORD
+    commands:
+      - echo "Building '$_DOCKER_BUILD_IMAGE:${CI_COMMIT_SHA}' on '${CI_MACHINE}'"
+      - exit 1
+      - docker build --label 'org.kset.tag=kset-org-2023' -t "$_DOCKER_BUILD_IMAGE":latest -t "$_DOCKER_BUILD_IMAGE":"${CI_COMMIT_SHA}" .
+      - echo "Logging into docker registry"
+      - docker login -u "$_DOCKER_USERNAME" -p "$_DOCKER_PASSWORD"
+      - echo "Pushing '$_DOCKER_BUILD_IMAGE:${CI_COMMIT_SHA}'"
+      - docker push --all-tags "$_DOCKER_BUILD_IMAGE"
+      - docker image rm "$_DOCKER_BUILD_IMAGE:${CI_COMMIT_SHA}"
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+
+  - name: notify-watchtower
+    # failure: ignore
+    image: curlimages/curl
+    environment:
+      _WATCHTOWER_URL:
+        from_secret: WATCHTOWER_URL
+      _WATCHTOWER_TOKEN:
+        from_secret: WATCHTOWER_TOKEN
+    commands:
+        - 'curl -sL -H "Authorization: Bearer $_WATCHTOWER_TOKEN" "$_WATCHTOWER_URL/v1/update"'
diff --git a/docker-compose.yml b/compose.yaml
similarity index 87%
rename from docker-compose.yml
rename to compose.yaml
index d7542a58..7d4ffae5 100644
--- a/docker-compose.yml
+++ b/compose.yaml
@@ -1,5 +1,3 @@
-version: '3.3'
-
 services:
   django:
     build:
@@ -13,4 +11,4 @@ services:
       context: ./ui
       dockerfile: Dockerfile
     depends_on:
-      - django
\ No newline at end of file
+      - django