Run an ssh server

Newly published guide: Run an ssh server. A somewhat belated response to questions such as this one. Being able to run your own ssh server is a common requirement as a building block for higher level services. I’ve been using it for quite a while to enable rsync to/from volumes in my application.

The current topic that triggered this for me is that I was looking into Kamal. This exploration has expanded into other tools such as docker compose, and ansible. The guide linkeda above is a longer explanation, but collapsing it down, the following will produce something that could be used as a starting point for ansible or Kamal:

FROM cruizba/ubuntu-dind

# install and configure sshd, python3
RUN apt-get update \
 && apt-get install -y openssh-server python3 \
 && cp /etc/ssh/sshd_config /etc/ssh/sshd_config-original \
 && sed -i 's/^#\s*Port.*/Port 2222/' /etc/ssh/sshd_config \
 && sed -i 's/^#\s*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config \
 && mkdir -p /root/.ssh \
 && chmod 700 /root/.ssh \
 && mkdir /var/run/sshd \
 && chmod 755 /var/run/sshd \
 && sed -i "/# Execute/i # Start sshd\necho \$AUTHORIZED_KEYS > /root/.ssh/authorized_keys\n/usr/sbin/sshd\n" /usr/local/bin/entrypoint.sh \
 && rm -rf /var/lib/apt/lists /var/cache/apt/archives

ENTRYPOINT ["entrypoint.sh"]
CMD ["sleep", "infinity"]

The corresponding fly.toml updates would look like:

[[services]]
  internal_port = 2222
  protocol = "tcp"
  auto_stop_machines = true
  auto_start_machines = true
  [[services.ports]]
    port = 22

To complete this picture, set a single secret:

fly secrets set "AUTHORIZED_KEYS=$(cat ~/.ssh/id_rsa.pub)"

While that’s a starting point, it actually is a bare machine that wouldn’t pass a health check if one were defined. Either deploying the full app and then later updating it via ansible/kamal/whatever, or deploying a stub that is replaced gets us further.

There is lots more to be explored. It would be really nice if Kamal could use our builders and registry directly, there might be unfortunate interactions between Traefik and our load balancer, and there undoubtedly are other unknowns.

docker compose turns out to be a different beast entirely. The technical problems with running multiple docker images in a single vm are all solvable; the biggest issue is that having CMD docker compose up leads to a rather poor user experience: fly deploy assimes that a new machine can start in milliseconds. Inserting the start of an entire build process into that flow leads to bad things.

In any case, the published guide is useful immediately. And should it spark a larger discussion, that would be a wonderful bonus.

6 Likes

Hi there! Thanks a bunch for publishing this guide. Would love to get a better understanding of how using Kamal would interact with existing Fly services such as certificates etc. I haven’t deployed with Kamal before but am interested in giving it a whirl on some existing Fly projects. From my understanding, Kamal (at the time of writing) supports building Docker containers, pushing to a registry, orchestrating spinning up corresponding images on the target deployment server, and automatically issuing Let’s Encrypt certificates.

On Fly, I’ve only really used the Fly CLI for deploying and issuing SSL certificates. Is only using Kamal feasible on Fly? Or is it still necessary to use Fly-specific commands?

I can give you a long answer, but I’ll give a short one for now: it looks like it indeed would be possible though I haven’t tried it myself, but it would be difficult and would result in a lousy experience.

A better solution than building on ssh would involve adapters or hooks to enable Kamal to transparently call out to either fly’s CLI or API where appropriate.

Can you describe what problem you are trying to solve?

Understood, thanks for such a prompt reply! I’m not trying to solve a problem per say. I was really just curious in giving Kamal a whirl to get in the habit of using it since I could see a future where Kamal is the deployment strategy used across all Rails projects I work on.

If only using Kamal on Fly would result in a lousy experience, I’m happy to continue using the Fly CLI.