TITLE=FTP server ROUTE=/infrastructure/ftp-server LOCALE=en MODIFIED=1792417593 URL=https://wiki.teletypegames.org/infrastructure/ftp-server L=1 https://git.teletypegames.org/infra/ftp-server L=2 #16 L=3 #18 L=4 #15 L=5 #49 L=6 #22 L=7 https://github.com/giampaolo/pyftpdlib q│ The DOS and Windows 9x tools cannot speak HTTPS, so they read FTP. One q│ server shares everything they need: anonymous, read-only, passive mode only, q│ on port 21. It also shares the WarpEngine game files of the portal, for any q│ FTP client. It runs alone as its own stack. The programs that write into it q│ run elsewhere. • bRepository:0 1git.teletypegames.org/infra/ftp-server • bAddress:0 cftp://ftp.teletypegames.org0 (port 21, passive data 30000–30019) 1The folders 1═══════════ p / p APPS/ the DOSINST program store: a folder per program, each with» p an INFO.INI p WARP/ the WarpEngine files of teletypegames.org: every build of » p every game p WIKI/ the TTGWIKI export: WIKI.INI, FILES.LST, EN/, HU/ t┌────────┬─────────────────────────────────┬─────────────────────────────────┐ t│h Folder t│h Read by t│h Written by t│ t├────────┼─────────────────────────────────┼─────────────────────────────────┤ t│0 cAPPS0 t│0 2DOSINST (cPATH=/APPS0) t│0 the cstore0 step of the tag t│ t│0 t│0 t│0 pipelines of DOSINST, 3GMENU, t│ t│0 t│0 t│0 4BMAGIC and 5TTGWIKI t│ t├────────┼─────────────────────────────────┼─────────────────────────────────┤ t│0 cWARP0 t│0 any FTP client (the names are t│0 every 6WarpEngine build that t│ t│0 t│0 not DOS 8.3 names) t│0 reaches teletypegames.org: the t│ t│0 t│0 t│0 same files as t│ t│0 t│0 t│0 chttps://teletypegames.org/file/0 t│ t│0 t│0 t│0 c...0 t│ t├────────┼─────────────────────────────────┼─────────────────────────────────┤ t│0 cWIKI0 t│0 5TTGWIKI (cPATH=/WIKI0) t│0 the exporter of the cttgwiki0 t│ t│0 t│0 t│0 stack, every 15 minutes t│ t└────────┴─────────────────────────────────┴─────────────────────────────────┘ cWARPb is not a copy.0 It is the storage folder of the portal (c/srv/stacks/teletype-games/data/softwares0), mounted read-only, so a new build is there at once. It also has the old versions, and the files of software deleted from the catalog while they stay in that folder. bThe root has these three folders and nothing else.0 A DOSINST older than 0.6.0 has cPATH=/0 in its cDOSINST.CFG0, and an update never changes that file: it finds no program at the root, so set cPATH=/APPS0 in it by hand. Until 2026-10-15 the server showed the folders of cAPPS0 at the root too for such a DOSINST. 1The server 1══════════ c/srv/stacks/ftp-server0 on vps.teletype.hu. The server is one container: 7pyftpdlib 2.2.0, without root and with a read-only file system. • Active mode (cPORT0/cEPRT0) gets a 502, so the container opens no outgoing connection. • Uploads and deletes get a 550. • At most 50 connections in all, and 5 from one IP. • The PASV replies announce cFTP_MASQUERADE0 from c.env0. The DOS clients ignore it and connect to the server's own address. The stack folder is not a git checkout. A push to master that changes the server deploys it from the pipeline, which only asks the server to do it: the cdeploy0 step calls the server's cdeploy0 user over SSH (cdeploy-ssh0 image, referenced by digest), whose key is bound to one fixed command, cci-deploy cftp-server0 (cinfra/host-config0). The server clones master from Gitea itself, checks ccompose.yaml0 against a policy (no privileged mode, no extra capabilities or host namespaces, no docker socket, bind mounts only in the stack and the read-only WarpEngine folder, public ports 21 and 30000–30019 only), copies ccompose.yaml0 and cserver/0 in, then runs cdocker compose up -d c--build0; no trusted volumes are needed. The test step runs in the cpyftpdlib image of the Gitea registry (cgit.teletypegames.org/build/pyftpdlib:3.130, the server's Python with pyftpdlib 2.2.0), and installs pyftpdlib only when the image has another version. croot/APPS0, croot/WIKI0 and c.env0 stay as they are. Until 2026-10-14 DOSINST (port 21, the cdosinst0 stack) and TTGWIKI (port 2121) each had their own FTP server.