{"id":34787938,"url":"https://github.com/serversideup/docker-proftpd","last_synced_at":"2026-05-21T12:09:58.897Z","repository":{"id":255269007,"uuid":"849065703","full_name":"serversideup/docker-proftpd","owner":"serversideup","description":"We were the poor souls who had to create a FTP docker image for a legacy integration, so we created this image incase you're a poor soul too.","archived":false,"fork":false,"pushed_at":"2024-08-29T20:39:51.000Z","size":62,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-30T00:36:38.047Z","etag":null,"topics":["docker","ftp","ftp-server","proftpd","proftpd-docker"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/serversideup/proftpd","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serversideup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"serversideup"}},"created_at":"2024-08-28T23:08:33.000Z","updated_at":"2024-08-29T20:39:55.000Z","dependencies_parsed_at":"2024-08-29T00:29:10.188Z","dependency_job_id":"86d309c7-9b85-419e-8a57-6d46490ecdb7","html_url":"https://github.com/serversideup/docker-proftpd","commit_stats":null,"previous_names":["serversideup/docker-proftpd"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/serversideup/docker-proftpd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serversideup%2Fdocker-proftpd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serversideup%2Fdocker-proftpd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serversideup%2Fdocker-proftpd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serversideup%2Fdocker-proftpd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serversideup","download_url":"https://codeload.github.com/serversideup/docker-proftpd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serversideup%2Fdocker-proftpd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28025635,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","ftp","ftp-server","proftpd","proftpd-docker"],"created_at":"2025-12-25T09:33:44.135Z","updated_at":"2025-12-25T09:33:49.128Z","avatar_url":"https://github.com/serversideup.png","language":"Dockerfile","funding_links":["https://github.com/sponsors/serversideup"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\t\t\u003cimg src=\"https://raw.githubusercontent.com/serversideup/docker-proftpd/main/.github/header.png\" width=\"1200\" alt=\"Docker Images Logo\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://github.com/serversideup/docker-proftpd/actions/workflows/publish_docker-images-production.yml\"\u003e\u003cimg alt=\"Build Status\" src=\"https://img.shields.io/github/actions/workflow/status/serversideup/docker-proftpd/.github%2Fworkflows%2Fpublish_docker-images-production.yml\" /\u003e\u003c/a\u003e\n\t\u003ca href=\"https://github.com/serversideup/docker-proftpd/blob/main/LICENSE\" target=\"_blank\"\u003e\u003cimg src=\"https://badgen.net/github/license/serversideup/docker-proftpd\" alt=\"License\"\u003e\u003c/a\u003e\n\t\u003ca href=\"https://github.com/sponsors/serversideup\"\u003e\u003cimg src=\"https://badgen.net/badge/icon/Support%20Us?label=GitHub%20Sponsors\u0026color=orange\" alt=\"Support us\"\u003e\u003c/a\u003e\n\t\u003ca href=\"https://community.serversideup.net\"\u003e\u003cimg alt=\"Discourse users\" src=\"https://img.shields.io/discourse/users?color=blue\u0026server=https%3A%2F%2Fcommunity.serversideup.net\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://serversideup.net/discord\"\u003e\u003cimg alt=\"Discord\" src=\"https://img.shields.io/discord/910287105714954251?color=blueviolet\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# ProFTPD Docker Image\n\n\u003e [!CAUTION]\n\u003e We created this image for a specific use case. We're not actively pursuing to expand features in this project. We just had a legacy integration to deal with on a customer project, so we created this image in case others might find it useful.\n\nThis Docker image provides a customizable ProFTPD server with MySQL authentication support and TLS encryption.\n\n| Docker Image | Size |\n|--------------|------|\n| [**serversideup/proftpd**](https://hub.docker.com/r/serversideup/proftpd) | [![Docker Image Size](https://img.shields.io/docker/image-size/serversideup/proftpd/latest?style=flat-square)](https://hub.docker.com/r/serversideup/proftpd) |\n\n## Base Image\nThe image is based on `ubuntu:24.04`, providing a stable and up-to-date environment for running ProFTPD.\n\n## Features\n- ProFTPD server with MySQL authentication\n- TLS encryption support\n- Customizable configuration via environment variables\n- Self-signed SSL certificate generation\n- IP address banning (bans IP addresses for 1 hour that fail authentication 5 times in 10 minutes)\n- Native Docker health checks to ensure the server is running\n\n## Environment Variables\n\nThe following environment variables can be used to customize the ProFTPD server:\n\n| Variable | Description | Default Value |\n|----------|-------------|---------------|\n| `FTP_DEBUG_LEVEL` | Sets the debug level for ProFTPD | 0 |\n| `FTP_LOG_LEVEL` | Sets the syslog level for ProFTPD | warn |\n| `FTP_MASQUERADE_ADDRESS` | IP address or hostname for passive mode connections | - |\n| `FTP_PASSIVE_PORT_RANGE_START` | Start of the passive port range | 60000 |\n| `FTP_PASSIVE_PORT_RANGE_END` | End of the passive port range | 60100 |\n| `FTP_SQL_USERS_TABLE` | MySQL table to authenticate users against | ftpusers |\n| `FTP_TLS_CERTIFICATE_FILE` | SSL certificate file | /etc/ssl/ftp/proftpd.crt |\n| `FTP_TLS_CERTIFICATE_KEY_FILE` | SSL certificate key file | /etc/ssl/ftp/proftpd.key |\n| `FTP_TLS_REQUIRED` | Require TLS | off |\n| `FTP_TLS_WAIT_FOR_CERTIFICATE` | Wait for the SSL certificate to be generated (helpful if you're using something like Let's Encrypt to generate the certificate) | false |\n| `FTP_TLS_WAIT_TIMEOUT` | Timeout for waiting for the SSL certificate to be generated | 60 |\n| `MYSQL_DATABASE` | MySQL database name | ftpdb |\n| `MYSQL_HOST` | MySQL host | mysql |\n| `MYSQL_PASSWORD` | MySQL password | ftppassword |\n| `MYSQL_PORT` | MySQL port | 3306 |\n| `MYSQL_USER` | MySQL user | ftpuser |\n\n## Build Defaults\n\nThe following build arguments are used during the image build process:\n\n| Build Argument | Description | Value |\n|----------------|-------------|---------------|\n| `FTP_USER` | The user under which ProFTPD will run | proftpd_user |\n| `FTP_GROUP` | The group under which ProFTPD will run | nogroup |\n| `FTP_SSL_CERTS_DIR` | Directory for SSL certificates | /etc/ssl/ftp |\n| `FTP_USERS_DIR` | Base directory for user homes | /var/ftp/users |\n\n## Usage\nIf you want to use Let's Encrypt with ProFTPD + CloudFlare + MySQL authentication, you can also include our other image [serversideup/certbot-dns-cloudflare](https://github.com/serversideup/docker-certbot-dns-cloudflare) to automatically generate the SSL certificates and share it with the ProFTPD container.\n\nHere is an a full example configuration of how to use the ProFTPD image with Let's Encrypt. Just set your the environment variables to match your set up and you're good to go:\n\n```yml\nservices:\n  certbot:\n    image: serversideup/certbot-dns-cloudflare:latest\n    volumes:\n      - certbot_data:/etc/letsencrypt\n    environment:\n      CLOUDFLARE_API_TOKEN: \"${CERTBOT_CLOUDFLARE_API_TOKEN}\"\n      CERTBOT_EMAIL: \"${CERTBOT_EMAIL}\"\n      CERTBOT_DOMAINS: \"${FTP_SERVER}\"\n      CERTBOT_KEY_TYPE: \"rsa\"\n      PUID: \"999\"\n      PGID: \"999\"\n  ftp:\n    volumes:\n      - ftp_data:/var/ftp/users\n      - ftp_logs:/var/log/proftpd\n      - certbot_data:/etc/letsencrypt\n    environment:\n      FTP_DEBUG_LEVEL: \"0\" # 0-10 (10 = most verbose)\n      FTP_LOG_LEVEL: \"info\" # debug, info, warn, error\n      FTP_MASQUERADE_ADDRESS: \"${FTP_SERVER}\"\n      FTP_PASSIVE_PORT_RANGE_START: \"60000\"\n      FTP_PASSIVE_PORT_RANGE_END: \"60049\"\n      FTP_SQL_USERS_TABLE: \"users\"\n      FTP_TLS_CERTIFICATE_FILE: \"/etc/letsencrypt/live/${FTP_SERVER}/fullchain.pem\"\n      FTP_TLS_CERTIFICATE_KEY_FILE: \"/etc/letsencrypt/live/${FTP_SERVER}/privkey.pem\"\n      FTP_TLS_REQUIRED: \"on\"\n      FTP_TLS_WAIT_FOR_CERTIFICATE: \"true\"\n      MYSQL_DATABASE: \"${FTPUSER_DATABASE}\"\n      MYSQL_HOST: \"${FTPUSER_HOST}\"\n      MYSQL_PASSWORD: \"${FTPUSER_PASSWORD}\"\n      MYSQL_PORT: \"${FTPUSER_PORT}\"\n      MYSQL_USER: \"${FTPUSER_USERNAME}\"\n    depends_on:\n      - certbot\n    ports:\n      - target: 21\n        published: 21\n        protocol: tcp\n        mode: host\n      - target: 990\n        published: 990\n        protocol: tcp\n        mode: host\n      - target: 60000\n        published: 60000\n        protocol: tcp\n        mode: host\n      - target: 60001\n        published: 60001\n        protocol: tcp\n        mode: host\n      - target: 60002\n        published: 60002\n        protocol: tcp\n        mode: host\nvolumes:\n  ftp_logs:\n  ftp_data:\n  certbot_data:\n```\n\nMake sure to replace the MySQL connection details with your own.\n\n## Configuration\n\nThe ProFTPD configuration file (`proftpd.conf`) is included in the image. It sets up the following:\n\n- FTP and FTPS (TLS) support\n- MySQL authentication\n- Passive port range: 60000-60100\n- TLS Protocol: TLSv1.2 and TLSv1.3\n- Logging configuration\n- Home directory creation for users\n- Anonymous access disabled\n- IP address banning (bans IP addresses for 1 hour that fail authentication 5 times in 10 minutes)\nYou can modify the `proftpd.conf` file to further customize the ProFTPD server according to your needs.\n\n## Security Considerations\n\n- The image generates a self-signed SSL certificate for FTPS. For production use, replace it with a valid SSL certificate.\n- Ensure to use strong passwords for MySQL authentication.\n- Review and adjust the `proftpd.conf` file to match your security requirements.\n- Consider using Docker secrets or a secure method to pass sensitive information like database credentials.\n\n## Ports\n\nThe following ports are exposed:\n\n| Port | Service |\n|------|---------|\n| 21 | FTP |\n| 990 | FTPS (FTP over TLS) |\n| 60000-60100 | Passive port range |\n\n### Special Note on orchestrators\nIf you are using an orchestrator like Kubernetes, you will need to ensure that the ports are opened on the container and the host.\n\nFor example, for Docker Swarm you need to use the long format for the `ports` directive in your docker compose file:\n\n```yml\nservices:\n  ftp:\n    image: serversideup/proftpd\n    ports:\n      - target: 21\n        published: 21\n        protocol: tcp\n        mode: host\n      - target: 990\n        published: 990\n        protocol: tcp\n        mode: host\n      - target: 60000\n        published: 60000\n        protocol: tcp\n        mode: host\n      - target: 60001\n        published: 60001\n        protocol: tcp\n        mode: host\n      - target: 60002\n        published: 60002\n        protocol: tcp\n        mode: host\n```\n\nUnfortunately, Docker Swarm does not support specifying ranges for published ports with the long format, so you need to specify each port individually. Just be sure to open all ports within the range that you define within the `FTP_PASSIVE_PORT_RANGE_START` and `FTP_PASSIVE_PORT_RANGE_END` environment variables.\n\n## MySQL Database\nYou can use either MySQL or MariaDB. Create a table in the database with the following SQL:\n\n```sql\nCREATE TABLE ftpusers (\n    id INT AUTO_INCREMENT PRIMARY KEY,  -- Auto-incrementing primary key\n    username VARCHAR(255) NOT NULL,     -- Username, max length 255 characters\n    password VARCHAR(255) NOT NULL,     -- Password, max length 255 characters\n    uid INT NOT NULL,                   -- User ID, integer type\n    gid INT NOT NULL,                   -- Group ID, integer type\n    homedir VARCHAR(255) NOT NULL,      -- Home directory path, max length 255 characters\n    shell VARCHAR(255) NOT NULL         -- Shell, max length 255 characters\n);\n```\n\nThen you can add users to the database with the following SQL:\n\n```sql\nINSERT INTO ftpusers (username, password, uid, gid, homedir, shell)\nVALUES (\n  'testuser',\n  CONCAT('{sha256}', TO_BASE64(UNHEX(SHA2('mypassword', 256)))),\n  2001,\n  2001,\n  '/var/ftp/users/testuser',\n  '/bin/false'\n);\n```\n\n## Resources\n- **[Discord](https://serversideup.net/discord)** for friendly support from the community and the team.\n- **[GitHub](https://github.com/serversideup/docker-proftpd)** for source code, bug reports, and project management.\n- **[Get Professional Help](https://serversideup.net/professional-support)** - Get video + screen-sharing help directly from the core contributors.\n\n## Contributing\nAs an open-source project, we strive for transparency and collaboration in our development process. We greatly appreciate any contributions members of our community can provide. Whether you're fixing bugs, proposing features, improving documentation, or spreading awareness - your involvement strengthens the project.\n\n- **Bug Report**: If you're experiencing an issue while using these images, please [create an issue](https://github.com/serversideup/docker-proftpd/issues/new/choose).\n- **Security Report**: Report critical security issues via [our responsible disclosure policy](https://www.notion.so/Responsible-Disclosure-Policy-421a6a3be1714d388ebbadba7eebbdc8).\n\nNeed help getting started? Join our Discord community and we'll help you out!\n\n\u003ca href=\"https://serversideup.net/discord\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/themes/serversideup/images/open-source/join-discord.svg\" title=\"Join Discord\"\u003e\u003c/a\u003e\n\n## Our Sponsors\nAll of our software is free an open to the world. None of this can be brought to you without the financial backing of our sponsors.\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/sponsors/serversideup\"\u003e\u003cimg src=\"https://521public.s3.amazonaws.com/serversideup/sponsors/sponsor-box.png\" alt=\"Sponsors\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n### Black Level Sponsors\n\u003ca href=\"https://sevalla.com\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/uploads/2024/10/sponsor-image.png\" alt=\"Sevalla\" width=\"546px\"\u003e\u003c/a\u003e\n\n#### Bronze Sponsors\n\u003c!-- bronze --\u003eNo bronze sponsors yet. \u003ca href=\"https://github.com/sponsors/serversideup\"\u003eBecome a sponsor →\u003c/a\u003e\u003c!-- bronze --\u003e\n\n#### Individual Supporters\n\u003c!-- supporters --\u003e\u003ca href=\"https://github.com/GeekDougle\"\u003e\u003cimg src=\"https://github.com/GeekDougle.png\" width=\"40px\" alt=\"GeekDougle\" /\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"https://github.com/JQuilty\"\u003e\u003cimg src=\"https://github.com/JQuilty.png\" width=\"40px\" alt=\"JQuilty\" /\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"https://github.com/MaltMethodDev\"\u003e\u003cimg src=\"https://github.com/MaltMethodDev.png\" width=\"40px\" alt=\"MaltMethodDev\" /\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"https://github.com/harrisonratcliffe\"\u003e\u003cimg src=\"https://github.com/harrisonratcliffe.png\" width=\"40px\" alt=\"harrisonratcliffe\" /\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u003c!-- supporters --\u003e\n\n## About Us\nWe're [Dan](https://twitter.com/danpastori) and [Jay](https://twitter.com/jaydrogers) - a two person team with a passion for open source products. We created [Server Side Up](https://serversideup.net) to help share what we learn.\n\n\u003cdiv align=\"center\"\u003e\n\n| \u003cdiv align=\"center\"\u003eDan Pastori\u003c/div\u003e                  | \u003cdiv align=\"center\"\u003eJay Rogers\u003c/div\u003e                                 |\n| ----------------------------- | ------------------------------------------ |\n| \u003cdiv align=\"center\"\u003e\u003ca href=\"https://twitter.com/danpastori\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/uploads/2023/08/dan.jpg\" title=\"Dan Pastori\" width=\"150px\"\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://twitter.com/danpastori\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/themes/serversideup/images/open-source/twitter.svg\" title=\"Twitter\" width=\"24px\"\u003e\u003c/a\u003e\u003ca href=\"https://github.com/danpastori\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/themes/serversideup/images/open-source/github.svg\" title=\"GitHub\" width=\"24px\"\u003e\u003c/a\u003e\u003c/div\u003e                        | \u003cdiv align=\"center\"\u003e\u003ca href=\"https://twitter.com/jaydrogers\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/uploads/2023/08/jay.jpg\" title=\"Jay Rogers\" width=\"150px\"\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://twitter.com/jaydrogers\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/themes/serversideup/images/open-source/twitter.svg\" title=\"Twitter\" width=\"24px\"\u003e\u003c/a\u003e\u003ca href=\"https://github.com/jaydrogers\"\u003e\u003cimg src=\"https://serversideup.net/wp-content/themes/serversideup/images/open-source/github.svg\" title=\"GitHub\" width=\"24px\"\u003e\u003c/a\u003e\u003c/div\u003e                                       |\n\n\u003c/div\u003e\n\n### Find us at:\n\n* **📖 [Blog](https://serversideup.net)** - Get the latest guides and free courses on all things web/mobile development.\n* **🙋 [Community](https://community.serversideup.net)** - Get friendly help from our community members.\n* **🤵‍♂️ [Get Professional Help](https://serversideup.net/professional-support)** - Get video + screen-sharing support from the core contributors.\n* **💻 [GitHub](https://github.com/serversideup)** - Check out our other open source projects.\n* **📫 [Newsletter](https://serversideup.net/subscribe)** - Skip the algorithms and get quality content right to your inbox.\n* **🐥 [Twitter](https://twitter.com/serversideup)** - You can also follow [Dan](https://twitter.com/danpastori) and [Jay](https://twitter.com/jaydrogers).\n* **❤️ [Sponsor Us](https://github.com/sponsors/serversideup)** - Please consider sponsoring us so we can create more helpful resources.\n\n## Our products\nIf you appreciate this project, be sure to check out our other projects.\n\n### 📚 Books\n- **[The Ultimate Guide to Building APIs \u0026 SPAs](https://serversideup.net/ultimate-guide-to-building-apis-and-spas-with-laravel-and-nuxt3/)**: Build web \u0026 mobile apps from the same codebase.\n- **[Building Multi-Platform Browser Extensions](https://serversideup.net/building-multi-platform-browser-extensions/)**: Ship extensions to all browsers from the same codebase.\n\n### 🛠️ Software-as-a-Service\n- **[Bugflow](https://bugflow.io/)**: Get visual bug reports directly in GitHub, GitLab, and more.\n- **[SelfHost Pro](https://selfhostpro.com/)**: Connect Stripe or Lemonsqueezy to a private docker registry for self-hosted apps.\n\n### 🌍 Open Source\n- **[AmplitudeJS](https://521dimensions.com/open-source/amplitudejs)**: Open-source HTML5 \u0026 JavaScript Web Audio Library.\n- **[Spin](https://serversideup.net/open-source/spin/)**: Laravel Sail alternative for running Docker from development → production.\n- **[Financial Freedom](https://github.com/serversideup/financial-freedom)**: Open source alternative to Mint, YNAB, \u0026 Monarch Money.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserversideup%2Fdocker-proftpd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserversideup%2Fdocker-proftpd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserversideup%2Fdocker-proftpd/lists"}