Search code examples
dockerftpdocker-composedocker-network

Access ftp service via other docker container


I have a Golang app, and it is supposed to connect to a FTP Server.

Now, both Golang app and FTP Server is dockerized, but I don't know how to connect to FTP server from Golang app

Here is my docker-compose.yml

version: '2'

services:
  myappgo:
    image: myappgo:exp
    volumes:
      - ./volume:/go
    networks:
      myappgo_network:
    env_file:
      - test.env

  ftpd-server:
    container_name: ftpd-server
    image: stilliard/pure-ftpd:hardened
    ports:
      - "21:21"
      - "30000-30009:30000-30000"
    environment:
      PUBLICHOST: "localhost"
      FTP_USER_NAME: "test"
      FTP_USER_PASS: "test"
      FTP_USER_HOME: "/home/test"
    restart: on-failure
    networks:
      myappgo_network:

networks:
  myappgo_network:

When I run docker compose, all services are up.

I could get IP of ftp container with:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ftpd-server

And then, I installed a ftp client for alpine in my golang container, lftp:

docker exec -it my_app_go sh
apk add lftp
lftp -d ftp://test:test@172.19.0.2 # -d for debug
lftp test@172.19.0.2:~> ls
---- Connecting to 172.19.0.2 (172.19.0.2) port 21
`ls' at 0 [Connecting...]

What am I missing ?


Solution

  • First simplify your dockerfile

    version: '3'  # i assume you can migrate to version 3, yes?
    services:
      myappgo:
        image: myappgo:exp
        volumes:
          - ./volume:/go
        env_file:
          - test.env
      ftpd-server:
        image: stilliard/pure-ftpd:hardened
        environment:
          PUBLICHOST: "0.0.0.0"
          FTP_USER_NAME: "test"
          FTP_USER_PASS: "test"
          FTP_USER_HOME: "/home/test"
        restart: on-failure
    

    Second, default network is created by docker-compose; no need to do it explicitly. All services get connected to it under their names, so you access them not by ip but by name like ftpd-server

    Third, you dont need to expose your ports if you access them from inside. If you need to access them from outside, then you expose.

    Next, launch ftp with binding to 0.0.0.0 - binding any tcp service to localhost or 127.0.0.1 makes it accessable only locally.

    Last, use service names to connect. Forget about ip addresses and docker inspect. You connection from myappgo to ftp will look like ftp://ftpd-server/foo/bar