Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker networking and accessories #41

Closed
tbuehlmann opened this issue Feb 6, 2023 · 7 comments
Closed

Docker networking and accessories #41

tbuehlmann opened this issue Feb 6, 2023 · 7 comments

Comments

@tbuehlmann
Copy link
Contributor

tbuehlmann commented Feb 6, 2023

When having an accessory (like redis or mysql), I'd like to access that from within my app using its docker name (like "my-app-redis"), similar to how it works with docker-compose.

This doesn't work right now as the service and the accessory are both using the default docker network and this kind of hostname resolution/dns only seem to work for user-defined networks. Creating a docker network and using that for services and accessories works, but then traefik won't be able to route traffic to the service without further configuration or connecting traefik to the same network.

Is the idea of creating a shared default docker network for traefik, the service and accessories something we want to pursue in the gem or is this something the user should take care of? A simple network: <network> deploy.yml option for service, traefik and accessories would suffice to generate the required --network docker args I guess.

@dhh
Copy link
Member

dhh commented Feb 6, 2023

MRSK is designed for multi-server operation, so the internal network idea breaks down pretty quick with that. You'd have to unstrip all of that when you go to scale it. So I think we're better off keeping the network host transparent.

@dhh dhh closed this as completed Feb 6, 2023
@meceo
Copy link

meceo commented Mar 25, 2023

@tbuehlmann I think I had a similar issue to yours. I try to run mrsk on Synology NAS that has docker installed. Next to web service, I have docker with postgres and redis on the same host. In order to connect web service with the database and Redis one has to add --add-host=host.docker.internal:host-gateway to docker run command to let the container access the host.
If you look at the current source code you will notice guys take *role.option_args to add to docker run command. So configuration like this:

servers:
  web:
    hosts:
      - 10.0.0.155
    options:
      "add-host": host.docker.internal:host-gateway

does the trick. If you run docker with --add-host the host.docker.internal will resolve to the container's host IP. From there you can already access the database, Redis, and any other service that is run on the host.

One remark! Currently, mrsk version 0.9.1 is available in RubyGems (gem install mrsk gives you that version). However, this version doesn't have *web.option_args added to the healthcheck's docker run command. It is only available in master branch, so make sure you use the master version. Otherwise, the mrsk deploy will still fail.

@tbuehlmann
Copy link
Contributor Author

Right, I thought a networking was a thing with mrsk, but it wasn't. Right now I just use the host's IP address from inside the container and that works well.

@mike1o1
Copy link

mike1o1 commented Apr 25, 2023

Another option here is to create the docker network yourself by sshing into the machine, and then specify the network name in your deploy.yml. From there, you can refer to your db server by "app-db" or whatever instead of by the public ip address. For example:

servers:
  web:
    hosts:
      - 10.0.1.183
    options:
      "network": "my-network"

traefik:
  options:
    network: "my-network"

accessories:
  db:
    image: postgres:14
    host: 10.0.1.183
    ... etc
    options:
      network: "my-network"

@tikal
Copy link

tikal commented Nov 1, 2023

Had the same "issue" while trying to set up a dev/staging server which would self contain its accessories to reduce server cost.
I ended up leveraging hooks to apply the network automatically, building upon the previous suggestion from @mike1o1

.kamal/hooks/pre-deploy

#!/usr/bin/env bash

REMOTE_HOST="user@host"
NETWORK_NAME="my-network"

# SSH into the remote host and execute Docker commands
ssh "$REMOTE_HOST" << EOF
    # Check if the Docker network already exists
    if ! docker network inspect "$NETWORK_NAME" &>/dev/null; then
        # If it doesn't exist, create it
        docker network create "$NETWORK_NAME"
        echo "Created Docker network: $NETWORK_NAME"
    else
        echo "Docker network $NETWORK_NAME already exists, skipping creation."
    fi
EOF

Also to bear in mind, accessories might still have ports mapped to the host ports despite it not being necessary since using the docker bridge network. You might want to deny trafic on those (if using ufw, see https://www.howtogeek.com/devops/how-to-use-docker-with-a-ufw-firewall/).

But overall, it feels like this dev/staging custom setup should be very minimal and ideally non-existent. Would be great to have this type of setup best practice documented somehow, along with notions like role, destination, etc. Happy to help once I understand it properly.

@tumes
Copy link

tumes commented Feb 10, 2024

@tbuehlmann I think I had a similar issue to yours. I try to run mrsk on Synology NAS that has docker installed. Next to web service, I have docker with postgres and redis on the same host. In order to connect web service with the database and Redis one has to add --add-host=host.docker.internal:host-gateway to docker run command to let the container access the host. If you look at the current source code you will notice guys take *role.option_args to add to docker run command. So configuration like this:

servers:
  web:
    hosts:
      - 10.0.0.155
    options:
      "add-host": host.docker.internal:host-gateway

does the trick. If you run docker with --add-host the host.docker.internal will resolve to the container's host IP. From there you can already access the database, Redis, and any other service that is run on the host.

One remark! Currently, mrsk version 0.9.1 is available in RubyGems (gem install mrsk gives you that version). However, this version doesn't have *web.option_args added to the healthcheck's docker run command. It is only available in master branch, so make sure you use the master version. Otherwise, the mrsk deploy will still fail.

This is a very old thread at this point but did you need to do anything special to deploy to your Synology NAS? I've been trying over and over and in spite of absolutely having docker installed and accessible both for root and an admin user, it keeps failing to detect docker (docker -v fails so it tries to reinstall it).

@meceo
Copy link

meceo commented Feb 11, 2024

I don't remember to be honest.
Are you saying that when kamal opens a ssh connection with an admin user the docker command isn't available in terminal session PATH?

try with kamal if you get similar responses to the following commands:
xxx@zzz:~$ docker -v
Docker version 20.10.23, build 876964a
xxx@zzz:~$ which docker
/usr/local/bin/docker
xxx@zzz:~$ echo $PATH
/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin:/usr/local/bin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants