Vuoi configurare un server FTP in 2 min e con un unico comando? Ora puoi!

Configurazione server FTP con Pure-FTPd, MySQL, Traefik 2 e Docker

07-11-2020

Ho sempre installato e configurato un server FTP in maniera “tradizionale”, cioè con la classica installazione da terminale, lanciando manualmente i comandi apt.

La mia configurazione base è questa da un po': Pure-FTPd + MySQL. In MySQL (con l’ausilio di PhpMyAdmin) creo gli utenti virtuali con i vari permessi: banda, quota, visibilità, etc.

Ormai sto facendo largo uso (e abuso) di Docker, quindi mi sono chiesto: “e se provassi a configurarmi il server FTP utilizzando Docker?” e quindi ho iniziato a provarci.

Ho deciso di utilizzare Traefik come reverse proxy, ho avuto modo di guardarlo nel dettaglio ultimamente e lo trovo veramente comodo, le performance sono ottime! (Io al momento sto usando la versione 2.1.9) Se non sei pratico con Traefik puoi usare quello che ti è più familiare (nginx, apache, caddy, altro…).

Dopo tante prove, container creati e cancellati alla velocità della luce, sudore e sangue, ho raggiunto lo scopo. Ho creato anche un gist su GitHub, lo puoi trovare qui.

I file necessari sono fondamentalmente due:

  • backup.sql
  • docker-compose.yml

Iniziamo con il docker-compose.yml:

version: "3.3"

services:

  pureftp_db:
    container_name: pureftp_db
    image: mysql:5.7
    restart: "always"
    volumes:
      - ./mysql_data:/var/lib/mysql
      - ./backup.sql:/docker-entrypoint-initdb.d/backup.sql
    environment:
      MYSQL_ROOT_PASSWORD: '<strongpassword>'
      MYSQL_DATABASE: 'pureftpd'
      MYSQL_USER: 'pureftpd'
      MYSQL_PASSWORD: '<anotherstrongpassword>'

  pure_ftpd_mysql:
    container_name: pure_ftpd_mysql
    image: "humpedli/docker-pure-ftpd-mysql"
    ports:
      - "20-21:20-21"
      - "30000-30009:30000-30009"
    volumes:
      - "/<path>:/ftpdata"
      - "/etc/localtime:/etc/localtime:ro"
    environment:
      - "EXTERNAL_IP=<domain>"
      - "MYSQL_HOST=pureftpd"
      - "MYSQL_PORT=3306"
      - "MYSQL_USER=pureftpd"
      - "MYSQL_PASSWORD=<anotherstrongpassword>"
      - "MYSQL_DATABASE=pureftpd"
    depends_on:
      - pureftp_db
    restart: "always"

  pureftpadmin_phpmyadmin:
    container_name: pureftpadmin_phpmyadmin
    image: phpmyadmin/phpmyadmin:5.0.1
    restart: always
    depends_on:
      - pureftp_db
    environment:
      PMA_HOSTS: pureftp_db
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pureftpadmin_phpmyadmin.entrypoints=websecure"
      - "traefik.http.routers.pureftpadmin_phpmyadmin.rule=Host(`pureftpmysql.<domain>`)"
      - "traefik.http.routers.pureftpadmin_phpmyadmin.tls.certresolver=lets-encr"

volumes:
    mysql_data:
    data:

networks:
  default:
    external:
      name: traefik_net

Ricordati di sostituire al suo interno:

  • <strongpassword>: genera una password robusta e sostituiscila a questo segnaposto,
  • <anotherstrongpassword>: genera un’altra password robusta (diversa da quella precedente, mi raccomando!) e sostituiscila a questo segnaposto,
  • <path>: inserisci il path che vuoi mappare nel container,
  • <domain>: inserisci qui il dominio al quale deve rispondere il server FTP,
  • devi creare anche il seguente sottodominio: pureftpmysql.<domain>

Il file backup.sql deve trovarsi nella stessa cartella del docker-compose.yml.

CREATE TABLE `ftpd` (
  `User` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `status` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1',
  `Password` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `Uid` varchar(11) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'www-data',
  `Gid` varchar(11) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'www-data',
  `Dir` varchar(250) COLLATE utf8_unicode_ci NOT NULL DEFAULT '/ftpdata',
  `ULBandwidth` smallint(5) NOT NULL DEFAULT '0',
  `DLBandwidth` smallint(5) NOT NULL DEFAULT '0',
  `comment` tinytext COLLATE utf8_unicode_ci NOT NULL,
  `ipaccess` varchar(15) COLLATE utf8_unicode_ci NOT NULL DEFAULT '*',
  `QuotaSize` int(10) NOT NULL DEFAULT '0',
  `QuotaFiles` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `ftpd`
  ADD PRIMARY KEY (`User`),
  ADD UNIQUE KEY `User` (`User`);

Breve spiegazione del docker-compose

In sostanza ho definito 3 container

  • uno per il database MySQL, ho inserito nel docker-compose le password da impostare per i 2 utenti e, montando il volume: ./backup.sql:/docker-entrypoint-initdb.d/backup.sql gli ho detto di importare al primo avvio alcune tabelle,
  • un container per Pure-FTPd che espone le porte attive e passive di FTP,
  • un ultimo container con PhpMyAdmin che mi servirà per gestire gli utenti FTP.

Solo PhpMyAdmin ha le label per la configurazione di Traefik (che puoi eliminare se vuoi utilizzare un altro reverse proxy).

Se non usi Traefik puoi rimuovere anche il blocco relativo alle networks:

networks:
  default:
    external:
      name: traefik_net

Per avviare il tutto, come al solito:

docker-compose up -d

Ok, è fatta. Docker si occuperà di scaricare le relative immagini e di tirare su tutto l’ambiente.

Come faccio a creare gli username e le realtive password?

Apri una nuova tab del browser e recati all’indirizzo: pureftpmysql.<domain>, se tutto è andato a buon fine si aprirà PhpMyAdmin. Inserisci username: root e la password (il valore che hai sostituito al placeholder: <strongpassword>).

Troverai il database pureftpd e la tabella ftpd (inizialmente vuota ovviamente).

PhpMyAdmin tabella ftpd
PhpMyAdmin tabella ftpd (click per ingrandire)

Clicca su SQL nella barra in alto ed incolla la seguente query di insert (modificando i dati 😄):

INSERT INTO `ftpd`(`User`, `Password`, `Dir`, `comment`) VALUES ('nomeutente', MD5('password'), '/ftpdata/cartella', 'utente di prova')

Ed è fatta!

Sei riuscito a creare il tuo server FTP? Scrivimi nei commenti, ti aspetto.

AP

Antonio Porcelli @progressify

Antonio Porcelli

@progressify

Commenta l'articolo

Se non visualizzi il blocco dei commenti è perchè non hai accettato i cookies.
Cancella le preferenze del tuo browser per questo sito, aggiorna la pagina ed accetta i cookies.