Okay, I was able to get it all working, not entirely sure on if it’s the best way or any implications however. This is for a silly couple day project so I don’t think it will affect me very much, but if you know of a better way so other’s with more production use cases come by they can know of other avenues.
Note: I am modifying the Dockerfile that Fly creates for you when you deploy a basic Phoenix project.
I use ubuntu as the release image instead of debian, this is how I was able to install the latest version of git.
ARG ELIXIR_VERSION=1.14.2
ARG OTP_VERSION=25.1.2
ARG DEBIAN_VERSION=jammy-20220428
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-ubuntu-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="ubuntu:${DEBIAN_VERSION}"
Then
- I make sure that openssh-server is installed
- add a git user
- write the port override to the sshd_config
- use git as the user instead of nobody (not sure the implications of this)
- start the server
FROM ${RUNNER_IMAGE}
RUN apt-get update -y && apt-get install -y software-properties-common gpg && add-apt-repository ppa:git-core/ppa && apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales git openssh-server vim \
&& apt-get clean && rm -f /var/lib/apt/lists/*_*
# Set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN useradd -U git
RUN echo "Port 2022" > /etc/ssh/sshd_config.d/git.conf
WORKDIR "/app"
RUN chown git /app
# set runner ENV
ENV MIX_ENV="prod"
# Only copy the final release from the build stage
COPY --from=builder --chown=git:root /app/_build/${MIX_ENV}/rel/twit ./
CMD ["/app/bin/server"]
# Appended by flyctl
ENV ECTO_IPV6 true
ENV ERL_AFLAGS "-proto_dist inet6_tcp"
Then I also modify the script overlay that is generate that actually invokes the mix release
- start the ssh service
- change the ownership of the mounted volume at /home/git. this basically uses the volume as the git users home dir
- switch to the git user
- echo the authorized keys into the git users ssh config (these are stored as a fly secret right now)
- start the server as the git user (for something it wasn’t starting it as the git user before so i added this and then it worked, not sure if i missed something though, so i left it as is).
#!/bin/sh
service ssh start
chown git /home/git
su - git
mkdir -p ~/.ssh
echo "$KEYS" > ~/.ssh/authorized_keys
cd -P -- "$(dirname -- "$0")"
su -c 'PHX_SERVER=true exec ./twit start' git
Now, with all of that, I have the following in my fly.toml for forwarding the correct ports. The alternative port is required because Fly takes control of port 22 to enable fly ssh console
.
[[services]]
internal_port = 2022
protocol = "tcp"
[[services.ports]]
port = 2022
Now, I have my user (currently… me ) add this to their own SSH config. This tells their ssh client to use port 2022 instead.
Host *fly.dev
Hostname myflydomain.fly.dev
Port 2022
Finally, I can do (assuming you have created a bare git repo at /home/git/mhanberg/somerepo.git
on your volume.
$ git remote add origin git@myflydomain.fly.dev:mhanberg/somerepo.git
$ git push origin main
And voila!
So, if anyone more knowledgeable in linux/ops things sees anything overtly wrong with this approach, please let me know!