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..785497dfb1bde2a1e796e98361bed919ef611758
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,12 @@
+---
+include:
+  - project: shore/ci-templates
+    file: templates/docker-compose.yml
+
+build:
+  extends: .compose-build
+  tags: [kodi.shore.co.il]
+
+run:
+  extends: .compose-run
+  tags: [kodi.shore.co.il]
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ab3fadd5542bcef089a09af78c7cb3a427ea804f
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,54 @@
+---
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks.git
+    rev: v3.4.0
+    hooks:
+      - id: check-added-large-files
+      - id: check-executables-have-shebangs
+      - id: check-json
+      - id: check-merge-conflict
+      - id: check-symlinks
+      - id: trailing-whitespace
+
+  - repo: https://github.com/Yelp/detect-secrets
+    rev: v0.14.3
+    hooks:
+      - id: detect-secrets
+        exclude: settings\.json
+
+  - repo: https://github.com/adrienverge/yamllint
+    rev: v1.25.0
+    hooks:
+      - id: yamllint
+      - id: yamllint
+        alias: transmission-rss.conf
+        files: rss/transmission-rss.conf
+        types: [text]
+
+  - repo: https://github.com/amperser/proselint/
+    rev: 0.10.2
+    hooks:
+      - id: proselint
+        types: [plain-text]
+        exclude: LICENSE
+
+  - repo: https://github.com/executablebooks/mdformat.git
+    rev: 0.5.3
+    hooks:
+      - id: mdformat
+
+  - repo: https://git.shore.co.il/nimrod/shell-pre-commit.git
+    rev: v0.6.0
+    hooks:
+      - id: shell-lint
+
+  - repo: https://github.com/shellcheck-py/shellcheck-py.git
+    rev: v0.7.1.1
+    hooks:
+      - id: shellcheck
+
+  - repo: https://git.shore.co.il/nimrod/docker-pre-commit.git/
+    rev: v0.3.0
+    hooks:
+      - id: hadolint
+      - id: docker-compose
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8f9fac4592132f4a7cdc5482bfc7baef1ba9dd12
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 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..794c14c89ae3fd87fd36c4aafff8ed8df07a4376
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# Transmission Docker
+
+[![pipeline status](https://git.shore.co.il/nimrod/transmission-docker/badges/master/pipeline.svg)](https://git.shore.co.il/nimrod/transmission-docker/-/commits/master)
+
+> A dockerized Transmission daemon, RSS watcher and annonymous FTP server.
+
+## Requirements
+
+- Docker
+- Docker Compose
+
+## 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://git.shore.co.il/expore/>.
diff --git a/daemon/Dockerfile b/daemon/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..a79cca395c206f332e4a01efaf3b4f71526bdae3
--- /dev/null
+++ b/daemon/Dockerfile
@@ -0,0 +1,22 @@
+FROM alpine:3.12
+# hadolint ignore=DL3018
+RUN apk add --update --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ \
+        gosu \
+    && \
+    apk add --update --no-cache \
+        transmission-daemon \
+        shadow \
+    && \
+    groupmod -g 1000 transmission && \
+    usermod -u 1000 transmission && \
+    apk del --no-cache --rdepends shadow && \
+    mkdir -p /var/run/transmission /etc/transmission/ && \
+    chown -R transmission:transmission /var/run/transmission
+COPY --chown=root:root entrypoint /
+COPY --chown=1000:1000 settings.json /etc/transmission/
+VOLUME /var/lib/transmission/
+WORKDIR /var/lib/transmission
+EXPOSE 9091 51413/tcp 51413/udp
+ENTRYPOINT [ "/entrypoint" ]
+CMD [ "transmission-daemon", "--foreground" ]
+HEALTHCHECK CMD wget --spider http://localhost:9091/transmission || exit 1
diff --git a/daemon/entrypoint b/daemon/entrypoint
new file mode 100755
index 0000000000000000000000000000000000000000..959de5f951c842768d42401101546e8535f11781
--- /dev/null
+++ b/daemon/entrypoint
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -eux
+
+install -d -o 1000 -g 1000 -m 750 /var/lib/transmission/.config/transmission-daemon/
+install -d -o 1000 -g 1000 -m 755 /var/lib/transmission/downloads
+install -o 1000 -g 1000 -m 640 /etc/transmission/settings.json /var/lib/transmission/.config/transmission-daemon/settings.json
+
+eval exec gosu "1000:1000" "$@"
diff --git a/daemon/settings.json b/daemon/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..59ddac8818744bc1836299d1b72a477bebf004e8
--- /dev/null
+++ b/daemon/settings.json
@@ -0,0 +1,73 @@
+{
+    "alt-speed-down": 50,
+    "alt-speed-enabled": false,
+    "alt-speed-time-begin": 540,
+    "alt-speed-time-day": 127,
+    "alt-speed-time-enabled": false,
+    "alt-speed-time-end": 1020,
+    "alt-speed-up": 50,
+    "bind-address-ipv4": "0.0.0.0",
+    "bind-address-ipv6": "::",
+    "blocklist-enabled": false,
+    "blocklist-url": "http://www.bluetack.co.uk/config/level1.gz",
+    "cache-size-mb": 4,
+    "dht-enabled": true,
+    "download-dir": "/var/lib/transmission/downloads",
+    "download-limit": 100,
+    "download-limit-enabled": 0,
+    "download-queue-enabled": true,
+    "download-queue-size": 5,
+    "encryption": 1,
+    "idle-seeding-limit": 30,
+    "idle-seeding-limit-enabled": false,
+    "incomplete-dir": "/var/lib/transmission/incomplete",
+    "incomplete-dir-enabled": false,
+    "lpd-enabled": true,
+    "max-peers-global": 200,
+    "message-level": 1,
+    "peer-congestion-algorithm": "",
+    "peer-id-ttl-hours": 6,
+    "peer-limit-global": 200,
+    "peer-limit-per-torrent": 50,
+    "peer-port": 51413,
+    "peer-port-random-high": 65535,
+    "peer-port-random-low": 49152,
+    "peer-port-random-on-start": false,
+    "peer-socket-tos": "default",
+    "pex-enabled": true,
+    "port-forwarding-enabled": false,
+    "preallocation": 1,
+    "prefetch-enabled": true,
+    "queue-stalled-enabled": true,
+    "queue-stalled-minutes": 30,
+    "ratio-limit": 2,
+    "ratio-limit-enabled": true,
+    "rename-partial-files": true,
+    "rpc-authentication-required": false,
+    "rpc-bind-address": "0.0.0.0",
+    "rpc-enabled": true,
+    "rpc-host-whitelist": "*.shore.co.il,transmission-rss",
+    "rpc-host-whitelist-enabled": false,
+    "rpc-password": "transmission",
+    "rpc-port": 9091,
+    "rpc-url": "/transmission/",
+    "rpc-username": "transmission",
+    "rpc-whitelist": "127.0.0.*,192.168.*.*,10.*.*.*,172.16.*.*,172.17.*.*,172.18.*.*,172.19.*.*,172.2?.*.*,172.30.*.*,172.31.*.*",
+    "rpc-whitelist-enabled": true,
+    "scrape-paused-torrents-enabled": true,
+    "script-torrent-done-enabled": false,
+    "script-torrent-done-filename": "",
+    "seed-queue-enabled": false,
+    "seed-queue-size": 10,
+    "speed-limit-down": 100,
+    "speed-limit-down-enabled": false,
+    "speed-limit-up": 100,
+    "speed-limit-up-enabled": false,
+    "start-added-torrents": true,
+    "trash-original-torrent-files": false,
+    "umask": 18,
+    "upload-limit": 100,
+    "upload-limit-enabled": 0,
+    "upload-slots-per-torrent": 14,
+    "utp-enabled": true
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e00cd7f8658d7a6997611b67a4c01a58bd8f4dbd
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,43 @@
+# vim:ff=unix:ts=2:sw=2:ai:expandtab
+---
+version: '3.7'
+services:
+  daemon:
+    build:
+      context: daemon/
+    ports:
+      - 9091:9091
+      - 51413:51413/tcp
+      - 51413:51413/udp
+    volumes:
+      - daemon:/var/lib/transmission/
+    restart: always
+    networks:
+      default:
+        aliases:
+          - transmission-daemon
+
+  rss:
+    build:
+      context: rss/
+    volumes:
+      - rss:/var/lib/transmission-rss/
+    restart: always
+
+  ftp:
+    build:
+      context: vsftpd/
+    volumes:
+      - daemon:/var/lib/transmission/
+    ports:
+      - '21:21'
+      - 4559-4564:4559-4564
+    restart: always
+
+volumes:
+  daemon:
+  rss:
+
+networks:
+  default:
+    name: shore
diff --git a/rss/Dockerfile b/rss/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..953982f30f727e259321e2f4f78bfcc53313b65c
--- /dev/null
+++ b/rss/Dockerfile
@@ -0,0 +1,21 @@
+FROM ruby:alpine
+# hadolint ignore=DL3018
+RUN apk add --update --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ \
+        gosu \
+    && \
+    apk add --update --no-cache \
+        build-base \
+    && \
+    gem install \
+        transmission-rss:1.0.0 \
+    && \
+    apk del --rdepends --no-cache build-base && \
+    addgroup -g 1000 transmission-rss && \
+    adduser -h /var/lib/transmission-rss -G transmission-rss -D -u 1000 transmission-rss
+COPY --chown=root:root entrypoint /usr/local/sbin/
+COPY --chown=root:root transmission-rss.conf /etc/
+ENTRYPOINT [ "entrypoint" ]
+WORKDIR /var/lib/transmission-rss
+VOLUME /var/lib/transmission-rss
+CMD [ "/usr/local/bundle/bin/transmission-rss" ]
+HEALTHCHECK CMD pgrep ruby || exit 1
diff --git a/rss/entrypoint b/rss/entrypoint
new file mode 100755
index 0000000000000000000000000000000000000000..2d93b81f382d08dc08f9d3ea1909fea9c75ff2ee
--- /dev/null
+++ b/rss/entrypoint
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -eux
+
+install -d -o 1000 -g 1000 -m 755 /var/lib/transmission-rss/
+
+eval exec gosu "1000:1000" "$@"
diff --git a/rss/transmission-rss.conf b/rss/transmission-rss.conf
new file mode 100644
index 0000000000000000000000000000000000000000..858eea954460affee69a89a170afe630ffd42f99
--- /dev/null
+++ b/rss/transmission-rss.conf
@@ -0,0 +1,185 @@
+# vim:ff=unix:ts=2:sw=2:ai:expandtab:ft=yaml
+# yamllint disable rule:line-length
+---
+server:
+  host: transmission-daemon
+fork: false
+update_interval: 1800
+feeds:
+  - url: https://showrss.info/show/270.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Archer 2009/
+    regexp: 720p
+  - url: https://showrss.info/show/126.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Fargo/
+    regexp: 720p
+  - url: https://showrss.info/show/214.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Bob's Burgers/
+    regexp: 720p
+  - url: https://showrss.info/show/101.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Bojack Horseman/
+    regexp: 720p
+  - url: https://showrss.info/show/58.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Brooklyn Nine-Nine/
+    regexp: 720p
+  - url: https://showrss.info/show/262.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Game of Thrones/
+    regexp: 720p
+  - url: https://showrss.info/show/274.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/House Of Cards 2013/
+    regexp: 720p
+  - url: https://showrss.info/show/278.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Orange Is The New Black/
+    regexp: 720p
+  - url: https://showrss.info/show/44.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Rick and Morty/
+    regexp: 720p
+  - url: https://showrss.info/show/275.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Silicon Valley/
+    regexp: 720p
+  - url: https://showrss.info/show/623.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Son of Zorn/
+    regexp: 720p
+  - url: https://showrss.info/show/707.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Grand Tour/
+    regexp: 720p
+  - url: https://showrss.info/show/479.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Vinyl/
+    regexp: 720p
+  - url: https://showrss.info/show/522.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Unbreakable Kimmy Schmidt/
+    regexp: 720p
+  - url: http://horriblesubs.info/rss.php?res=1080
+    download_path: /var/lib/transmission/downloads/TV Shows/Dragon Ball Super/
+    regexp: Dragon Ball Super
+  - url: https://showrss.info/show/820.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Twin Peaks/
+    regexp: 720p
+  - url: https://showrss.info/show/811.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Handmaid's Tale/
+    regexp: 720p
+  - url: http://horriblesubs.info/rss.php?res=1080
+    download_path: /var/lib/transmission/downloads/TV Shows/One-Punch Man/
+    regexp: One-Punch Man
+  - url: https://showrss.info/show/262.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Game of Thrones/
+    regexp: 720p
+  - url: https://showrss.info/show/314.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Top Chef/
+    regexp: 720p
+  - url: https://showrss.info/show/583.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Stranger Things/
+    regexp: 720p
+  - url: https://showrss.info/show/865.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's The Defenders/
+    regexp: 720p
+  - url: https://showrss.info/show/863.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Top of the Lake/
+    regexp: 720p
+  - url: https://showrss.info/show/871.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Deuce/
+    regexp: 720p
+  - url: https://showrss.info/show/843.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Ozark/
+    regexp: 720p
+  - url: https://showrss.info/show/876.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Philip K. Dick's Electric Dreams/
+    regexp: 720p
+  - url: https://showrss.info/show/630.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Good Place/
+    regexp: 720p
+  - url: https://showrss.info/show/889.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's Inhumans/
+    regexp: 720p
+  - url: https://showrss.info/show/893.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Curb Your Enthusiasm/
+    regexp: 720p
+  - url: https://showrss.info/show/612.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Jean-Claude Van Johnson/
+    regexp: 720p
+  - url: https://showrss.info/show/921.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's The Punisher/
+    regexp: 720p
+  - url: https://showrss.info/show/923.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's Runaways/
+    regexp: 720p
+  - url: https://showrss.info/show/877.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Great British Bake Off/
+    regexp: 720p
+  - url: https://showrss.info/show/590.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Comedians in Cars Getting Coffee/
+    regexp: 720p
+  - url: https://showrss.info/show/951.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Altered Carbon/
+    regexp: 720p
+  - url: https://showrss.info/show/337.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Red Dwarf/
+    regexp: 720p
+  - url: https://showrss.info/show/982.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Roseanne/
+    regexp: 720p
+  - url: https://showrss.info/show/996.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Cobra Kai/
+    regexp: 720p
+  - url: https://showrss.info/show/1003.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's Cloak and Dagger/
+    regexp: 720p
+  - url: https://showrss.info/show/346.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Arrested Development/
+    regexp: 720p
+  - url: https://showrss.info/show/639.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Marvel's Luke Cage/
+    regexp: 720p
+  - url: https://showrss.info/show/365.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Jessica Jones/
+    regexp: 720p
+  - url: https://showrss.info/show/1023.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Who Is America?/
+    regexp: 720p
+  - url: https://showrss.info/show/834.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/GLOW/
+    regexp: 720p
+  - url: https://showrss.info/show/1112.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Hanna/
+    regexp: 720p
+  - url: https://showrss.info/show/1120.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Doom Patrol/
+    regexp: 720p
+  - url: https://showrss.info/show/1121.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Umbrella Academy/
+    regexp: 720p
+  - url: https://showrss.info/show/1135.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Love, Death & Robots/
+    regexp: 720p
+  - url: https://showrss.info/show/1158.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Catch-22/
+    regexp: 720p
+  - url: https://showrss.info/show/1161.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Rain/
+    regexp: 720p
+  - url: https://showrss.info/show/1168.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Your Pretty Face Is Going To Hell/
+    regexp: 720p
+  - url: https://showrss.info/show/1183.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/The Boys/
+    regexp: 720p
+  - url: https://showrss.info/show/1185.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Veronica Mars/
+    regexp: 720p
+  - url: https://showrss.info/show/1196.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/On Becoming a God in Central Florida/
+    regexp: 720p
+  - url: https://showrss.info/show/442.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Mike Tyson Mysteries/
+    regexp: 720p
+  - url: https://showrss.info/show/1066.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Titans/
+    regexp: 720p
+  - url: https://showrss.info/show/1238.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Harley Quinn/
+    regexp: 720p
+  - url: https://showrss.info/show/1264.rss
+    download_path: '/var/lib/transmission/downloads/TV Shows/Star Trek: Picard/'
+    regexp: 720p
+  - url: https://showrss.info/show/1311.rss
+    download_path: /var/lib/transmission/downloads/TV Shows/Stargirl/
+    regexp: 720p
diff --git a/vsftpd/Dockerfile b/vsftpd/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..26c530d644da29af52a5114cf497d3ead7bbee2b
--- /dev/null
+++ b/vsftpd/Dockerfile
@@ -0,0 +1,18 @@
+FROM debian:buster-slim
+# hadolint ignore=DL3008
+RUN apt-get update && \
+    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+        ftp \
+        gosu \
+        netcat-openbsd \
+        vsftpd \
+    && \
+    mkdir -p /var/run/vsftpd/empty && \
+    rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*
+COPY --chown=root:root entrypoint /usr/local/sbin/
+COPY --chown=root:root healthcheck /usr/local/bin
+COPY --chown=root:root vsftpd.conf /etc/vsftpd.conf
+EXPOSE 21 4559 4560 4561 4562 4563 4564
+ENTRYPOINT [ "/usr/local/sbin/entrypoint" ]
+CMD [ "vsftpd" ]
+HEALTHCHECK CMD healthcheck || exit 1
diff --git a/vsftpd/entrypoint b/vsftpd/entrypoint
new file mode 100755
index 0000000000000000000000000000000000000000..f46ba78fd2a4edfbae925247f51b2dc0827c9baa
--- /dev/null
+++ b/vsftpd/entrypoint
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -eux
+
+install -d -o 1000 -g 1000 -m 755 /var/lib/transmission/downloads
+touch /var/log/vsftpd.log
+tail -f /var/log/vsftpd.log &
+eval exec "$@"
diff --git a/vsftpd/healthcheck b/vsftpd/healthcheck
new file mode 100755
index 0000000000000000000000000000000000000000..99e47ce3bcbc0bf3bb140e669e671daa1fcc0598
--- /dev/null
+++ b/vsftpd/healthcheck
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -eux
+
+ftp -inv<<EOF
+open localhost
+user anonymous healthcheck
+ls
+bye
+EOF
diff --git a/vsftpd/vsftpd.conf b/vsftpd/vsftpd.conf
new file mode 100644
index 0000000000000000000000000000000000000000..964fd03a4a22cee7e754374e0cea5c1452b59834
--- /dev/null
+++ b/vsftpd/vsftpd.conf
@@ -0,0 +1,11 @@
+listen=YES
+local_enable=NO
+anonymous_enable=YES
+write_enable=NO
+anon_root=/var/lib/transmission/downloads
+listen_address=0.0.0.0
+xferlog_enable=YES
+pasv_min_port=4559
+pasv_max_port=4564
+connect_from_port_20=YES
+secure_chroot_dir=/var/run/vsftpd/empty