Access ftp service via other docker container - docker

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 ?

At least, you need 21/TCP for commands and 20/TCP for data on ftp-server:
ports:
- "21:21"
- "20:20"
- "30000-30009:30000-30009"
I changed your compose-file a little bit:
version: '2'
services:
myappgo:
image: alpine:3.8
tty: true
networks:
swarm_default:
ftpd-server:
container_name: ftpd-server
image: stilliard/pure-ftpd:hardened
ports:
- "21:21"
- "20:20"
- "30000-30009:30000-30009"
environment:
PUBLICHOST: "localhost"
FTP_USER_NAME: "test"
FTP_USER_PASS: "test"
FTP_USER_HOME: "/home/test"
restart: on-failure
networks:
swarm_default:
networks:
swarm_default:
Then I created on ftp-server file /home/test/1 and I can see it from mygoapp-container:
/ # lftp ftp://test:test#172.19.0.2
lftp test#172.19.0.2:/> dir
-rw-r--r-- 1 0 0 0 Jan 22 14:18 1

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

Related

docker host: use docker dns to resolve container name from host network

I need to resolve a container name to the IP Address from the docker host.
The reason for this is, i need a container to run on the host network, but it must be also able to resolve the container "backend" which it connects also to. (The container must be send & receive multicast packets)
docker-compose.yml
version: "3"
services:
database:
image: mongo
container_name: database
hostname: database
ports:
- "27017:27017"
backend:
image: "project/backend:latest"
container_name: backend
hostname: backend
environment:
- NODE_ENV=production
- DATABASE_HOST=database
- UUID=5025f846-7587-11ed-9ca7-8b992b5e7dd3
ports:
- "8080:8080"
depends_on:
- database
tty: true
frontend:
image: "project/frontend:latest"
container_name: frontend
hostname: frontend
ports:
- "80:80"
- "443:443"
depends_on:
- backend
environment:
- BACKEND_HOST=backend
connector:
image: "project/connector:latest"
container_name: connector
hostname: connector
ports:
- "1900:1900/udp"
#expose:
# - "1900/udp"
environment:
- NODE_ENV=production
- BACKEND_HOST=backend
- STARTUP_DELAY=1500
depends_on:
- backend
network_mode: host
tty: true
How can i resolve the hostname "backend" via docker from the docker host?
dig backend #127.0.0.11 & dig backend #172.17.0.1 did not work.
A test with a docker ubuntu image & socat proves, that i can receive ssdp multicast packets:
docker run --net host -it --rm ubuntu
socat UDP4-RECVFROM:1900,ip-add-membership=239.255.255.250:0.0.0.0,fork -
The only problem i now have is the DNS/Container name resolution from the host (network).
TL;DR
The container "connector" must be on the host network,but also be able to resolve the container name "backend" to the docker internal IP Address.
NOTE: Perhaps this is better suited on superuser or similar?

Could not create server TCP listening socket *:6383 bind: Cannot assign requested address in redis clustering on docker (in windows)

I'm trying to set up redis clustring on windows docker.
it works fine only in redis-cli -h 127.0.0.1 -p 6383 inside docker container CLI all nodes are fine and cluster has no problem. this is one of the redis.config file nodes
redis.config file
port 6383
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
The problem is with the above configuration, it's not possible to access the clustering with the application because it's not reachable for app (this app works fine in redis single mode)
when I change "bind" redis.conf file to my computer ip which is 192.168.3.205 i get this error
enter image description here
I have tried the following:
open the above port in the firewall roll
with telnet command it seems nobody listennign on this port
telnet 192.168.3.205 6383 and 127.0.0.1 6383
in netstat prot 6383 not used by anyone
and this is my .yml file
version: "3.8"
networks:
default:
name: amin-cluster
services:
redis0:
container_name: node-0
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6379\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-0
restart: always
redis1:
container_name: node-1
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6380\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-1
restart: always
redis2:
container_name: node-2
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6381\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-2
restart: always
redis3:
container_name: node-3
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6382\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-3
restart: always
redis4:
container_name: node-4
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6383\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-4
restart: always
redis5:
container_name: node-5
image: mnadeem/redis
network_mode: "host"
volumes:
- C:\Windows\System32\6384\redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
build:
context: .
dockerfile: Dockerfile
hostname: node-5
restart: always
In your docker compose yml, you need to publish the port, and set one up for each service you want accessible from the host.
redis0:
ports:
- "6383:6383"
...
redis1:
ports:
- "12345:6383"
The syntax is "hostport:containerport", since you have 6 redis instances, assuming you want each accessable each host port will need to be different.
You can obviously omit ports if you don't need it accessible from the host.
For more details on how to publish ports, read the docker compose yml docs https://docs.docker.com/compose/compose-file/compose-file-v3/#ports

access from docker stack mode to local network host

I need make ftp connection to 192.168... network host (local network), and connection to mongo container.
Docker in swarm mode blocks network_mode:host (and I can't see remote ftp host inside container)
Docker stack has docs about --publish mode=host,target=80,published=8080, but I can't find out how write it in docker-compose file.
My docker-compose.yml file
version: '3'
services:
node:
image: tgbot-test_node_1
build:
context: ..
env_file: .env.test
network_mode: host
links:
- mongo # works
depends_on:
- mongo
deploy:
mongo:
image: mongo
network_mode: "bridge"
restart: on-failure
ports:
- 8080:80 # not works, only expose 27017/tcp
# not works
# - mode: host
# target: 27019
# published: 27017
env_file:
- .env.test
volumes:
- db:/data/db
deploy:
limits:
cpus: '0.75'
volumes:
db:
I need swarm mode for limiting resourses.
How can I access ftp host?
Docker version 19.03.12, build 48a66213fe
docker-compose version 1.26.2, build eefe0d31
UPD
with Joel Magnuson answer I got PORTS: 27017/tcp of mongo container. It not forward ports with stack deploy, any - would it be "80:80" or "27017"
I set
ports:
- 27018:27017
and got
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab58c781fdb9 mongo:latest "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 27017/tcp tgbot-test_mongo.1.3i7yps3saqo3nk4xxyk0eka7h
43c0e3cfe960 tgbot-test_node_1:latest "docker-entrypoint.s…" 3 seconds ago Up 3 seconds tgbot-test_node.1.v23cufsrr683gdg2bicgf80q2
I think this is just a configuration issue. You mentioned "FTP host" but you didn't mention about running an FTP server. Hopefully the below helps with your mongo database.
mongodb will always run on port 27017 inside the container by default unless configured, so you must mount the container's port of 27017 to the host, not port 80.
version: '3'
services:
node:
image: tgbot-test_node_1
env_file: .env.test # configure with mongodb://mongo:27017/<db name>
networks:
- tgbot-test
mongo:
image: mongo
ports:
- 27017:27017 # only needed if you want to access it outside of the stack
# otherwise it's always visible within the stack network as 'mongo'
volumes:
- /home/$USER/db:/data/db # can mount to host instead
networks:
- tgbot-test
networks:
tgbot-test:
driver: overlay #suggest overlay network
#volumes:
# db: # this is not persistent by itself - can mount to host
You could also create an external volume.
docker volume create --name tgbot-db
...
volumes:
tgbot-db:
external: true
You should be able to connect to the mongodb instance from the host or remote with mongodb://192.160.X.X:27017/<db name> or inside a container in the same stack using docker swarm's DNS name of mongo(service name) with mongodb://mongo:27017/<db name>.

Docker-compose bridge network & host remote port forwarding at the same container

I'm trying to make service that can forward remote database port to container and at the same time can be accessible by alias hostname from other containers to work with them.
I am think that make all containers communicate by host network is bad practice, so i am trying to setup that configuration.
When i am triyng to add to php-fpm service network with driver: host, docker says
only one instance of "host" network is allowed
When i am trying to set php-fpm service with this
networks
- host
Docker says that he cant find out network with this name.
When i try to define network in docker-compose by id of built-in host, it just cant start this container.
This is my docker-compose:
version: '3.2'
networks:
backend-network:
driver: bridge
frontend-network:
driver: bridge
volumes:
redis-data:
home-dir:
services:
&app-service app: &app-service-template
build:
context: ./docker/app
dockerfile: Dockerfile
volumes:
- ./src:/app:rw
- home-dir:/home/user
hostname: *app-service
environment:
FPM_PORT: &php-fpm-port 9001
FPM_USER: "${USER_ID:-1000}"
FPM_GROUP: "${GROUP_ID:-1000}"
APP_ENV: local
HOME: /home/user
command: keep-alive.sh
networks:
- backend-network
&php-fpm-service php-fpm:
<<: *app-service-template
user: 'root:root'
restart: always
hostname: *php-fpm-service
ports: [*php-fpm-port]
environment:
FPM_PORT: *php-fpm-port
FPM_USER: "${USER_ID:-1000}"
FPM_GROUP: "${GROUP_ID:-1000}"
APP_ENV: local
HOME: /home/user
entrypoint: /fpm-entrypoint.sh
command: php-fpm --nodaemonize -R -d "opcache.enable=0" -d "display_startup_errors=On" -d "display_errors=On" -d "error_reporting=E_ALL"
networks:
- backend-network
- frontend-network
nginx:
build:
context: ./docker/nginx
dockerfile: Dockerfile
restart: always
working_dir: /usr/share/nginx/html
environment:
FPM_HOST: *php-fpm-service
FPM_PORT: *php-fpm-port
ROOT_DIR: '/app/public' # App path must equals with php-fpm container path
volumes:
- ./src:/app:ro
ports: ['9999:80']
depends_on:
- *php-fpm-service
networks:
- frontend-network
Network scheme (question about green line):
Host works on Debian 7 (updates prohibited) and conainer works with lastest Alpine

Mapping ports in docker-compose file doesn't work. Network unreachable

I'm trying to map a port from my container, to a port on the host following the docs but it doesn't appear to be working.
After I run docker-compose -f development.yml up --force-recreate I get no errors. But if I try to reach the frontend service using localhost:8081 the network is unreachable.
I used docker inspect to view the IP and tried to ping that and still nothing.
Here is the docker-compose file I am using. And I doing anything wrong?
development.yml
version: '3'
services:
frontend:
image: nginx:latest
ports:
- "8081:80"
volumes:
- ./frontend/public:/var/www/html
api:
image: richarvey/nginx-php-fpm:latest
ports:
- "8080:80"
restart: always
volumes:
- ./api:/var/www/html
environment:
APPLICATION_ENV: development
ERRORS: 1
REMOVE_FILES: 0
links:
- db
- mq
db:
image: mariadb
restart: always
volumes:
- ./data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: dEvE10pMeNtMoDeBr0
mq:
image: rabbitmq:latest
restart: always
environment:
RABBITMQ_DEFAULT_USER: developer
RABBITMQ_DEFAULT_PASS: dEvE10pMeNtMoDeBr0
You are using docker toolbox. Docker toolbox uses docker machine. In Windows with docker toolbox, you are running under a virtualbox with its own IP, so localhost is not where your containers live. You will need to go 192.168.99.100:8081 to find your frontend.
As per the documentation on docker machine(https://docs.docker.com/machine/get-started/#run-containers-and-experiment-with-machine-commands):
$ docker-machine ip default
192.168.99.100

Resources