diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..3e66e1d5821e755498f864e372ae1dbe23c29414
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+~*
+*~
+*.sw[op]
+*.py[cod]
+.DS_Store
+__pycache__/
+.vagrant/
+vendor/
+Thumbs.db
+*.retry
+.svn/
+.sass-cache/
+*.log
+*.out
+*.so
+node_modules/
+.npm/
+nbproject/
+*.ipynb
+.idea/
+*.egg-info/
+*.[ao]
+.classpath
+.cache/
+bower_components/
+*.class
+*.[ewj]ar
+secring.*
+.*.kate-swp
+.swp.*
+.directory
+.Trash-*
+build/
+_build/
+dist/
+.tox/
+*.pdf
+*.exe
+*.dll
+*.gz
+*.tgz
+*.tar
+*.rar
+*.zip
+*.pid
+*.lock
+*.env
+.bundle/
+!Pipfile.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cadb99836011a4ee40ce5d21f0d3c4237e51893a
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,46 @@
+---
+image: adarnimrod/ci-images:docker
+
+stages:
+  - test
+  - build
+  - run
+
+pre-commit:
+  stage: test
+  image: adarnimrod/ci-images:pre-commit
+  variables:
+    XDG_CACHE_HOME: "$CI_PROJECT_DIR/.cache"
+    # Disabled until https://github.com/pre-commit/pre-commit/issues/1387 is
+    # resolved.
+    SKIP: "hadolint,docker-compose"
+  script:
+    - pre-commit run --all-files
+  cache:
+    paths:
+      - .cache/
+
+build:
+  stage: build
+  tags: ["ns4.shore.co.il"]
+  variables:
+    COMPOSE_DOCKER_CLI_BUILD: "1"
+    DOCKER_BUILDKIT: "1"
+  script:
+    - docker-compose build --no-cache --pull
+    - docker-compose pull --quiet
+
+run:
+  stage: run
+  tags: ["ns4.shore.co.il"]
+  when: manual
+  script:
+    - docker-compose up --detach --remove-orphans
+    # yamllint disable rule:line-length
+    - |
+        for i in $(seq 12)
+        do
+            docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$' || break
+            sleep 10
+        done
+        ! docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$'
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7e1749c21f327a3687ecfbf2cd47411dbf494f39
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,34 @@
+# vim:ff=unix ts=2 sw=2 ai expandtab
+---
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.3.0
+    hooks:
+      - id: check-added-large-files
+      - id: check-merge-conflict
+      - id: detect-private-key
+      - id: trailing-whitespace
+  - repo: https://github.com/adrienverge/yamllint
+    rev: v1.17.0
+    hooks:
+      - id: yamllint
+  - repo: https://github.com/amperser/proselint/
+    rev: 0.10.2
+    hooks:
+      - id: proselint
+        types: [plain-text]
+        exclude: LICENSE
+  - repo: https://github.com/Yelp/detect-secrets
+    rev: v0.13.0
+    hooks:
+      - id: detect-secrets
+  - repo: https://git.shore.co.il/nimrod/docker-pre-commit.git/
+    rev: v0.3.0
+    hooks:
+      - id: docker-compose
+      - id: hadolint
+  - repo: https://git.shore.co.il/nimrod/shell-pre-commit.git/
+    rev: v0.6.0
+    hooks:
+      - id: shell-lint
+      - id: shellcheck
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..4f8b66360fa477afd0097f48504804fbe38e0135
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,14 @@
+# hadolint ignore=DL3007
+FROM registry.hub.docker.com/cznic/knot:latest
+# hadolint ignore=DL3008
+RUN apt-get update && \
+    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+        gettext-base \
+    && \
+    rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*
+COPY --chown=root:root entrypoint /usr/local/bin/
+COPY --chown=root:root knot.conf /etc/knot/
+EXPOSE 53/tcp 53/udp
+ENTRYPOINT ["entrypoint"]
+CMD ["knotd", "-vc", "/etc/knot/knot.conf"]
+HEALTHCHECK CMD knotc status
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..37cee3fd12e0bd031862606e91eff18af10f37c4
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Adar Nimrod
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..039ae65b88e84222c7ca0f2ee8320ce8be8d4f19
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+# Secondary DNS server
+
+> Secondary DNS server Docker image.
+
+## License
+
+This software is licensed under the MIT license (see `LICENSE.txt`).
+
+## Author Information
+
+Nimrod Adar, [contact me](mailto:nimrod@shore.co.il) or visit my [website](
+https://www.shore.co.il/). Patches are welcome via [`git send-email`](
+http://git-scm.com/book/en/v2/Git-Commands-Email). The repository is located
+at: <https://www.shore.co.il/git/>.
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..645be2b094f65b85fb84d7b645fcdad81962fbea
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,16 @@
+# vim:ff=unix:ts=2:sw=2:ai:expandtab
+---
+version: '3.5'
+services:
+  dns:
+    build:
+      context: .
+    # image: adarnimrod/secondary_dns
+    ports:
+      - 163.172.74.36:53:53/udp
+      - 163.172.74.36:53:53/tcp
+    restart: always
+
+networks:
+  default:
+    name: shore
diff --git a/entrypoint b/entrypoint
new file mode 100755
index 0000000000000000000000000000000000000000..23bcf3fdb63a37858d8233811e1265e13fc5d3fc
--- /dev/null
+++ b/entrypoint
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -eu
+
+eval exec "$@"
diff --git a/knot.conf b/knot.conf
new file mode 100644
index 0000000000000000000000000000000000000000..aa6017f01a026cff51db95c4a38490be5f6f6319
--- /dev/null
+++ b/knot.conf
@@ -0,0 +1,18 @@
+# vim:ft=yaml
+server:
+    listen: 0.0.0.0@53
+
+remote:
+  - id: master
+    address: 62.219.131.121
+
+acl:
+  - id: notify_from_master
+    address: 62.219.131.121
+    action: notify
+
+zone:
+  - domain: shore.co.il
+    storage: /rundir/slave
+    master: master
+    acl: notify_from_master