Hi folks! I'm deploying a dummy project just to figure out what would be the best method for it. I decided to use docker of course, and the only thing I have no clear is the part of the postgres db creation (ecto.setup). I red that the database must be previously and independently prepared, and others programmers have created a release function or script to run the ecto.setup while the dockers are initialising.
#Deployment tips
59 messages · Page 1 of 1 (latest)
My Dockerfile:
ARG MIX_ENV="prod"
# build stage
FROM hexpm/elixir:1.13.4-erlang-25.1-debian-buster-20220801 AS build
# install build dependencies
RUN apt update && export DEBIAN_FRONTEND=noninteractive \
&& apt install -y erlang-base rustc build-essential curl git
# sets work dir
WORKDIR /app
# install hex + rebar
RUN mix local.hex --force && \
mix local.rebar --force
ARG MIX_ENV
ENV MIX_ENV="${MIX_ENV}"
# install mix dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only $MIX_ENV
# copy compile configuration files
RUN mkdir config
COPY config/config.exs config/
COPY config/$MIX_ENV.exs config/
COPY config/$MIX_ENV.secret.exs config/
ENV DATABASE_URL="ecto://user:password@localhost/database"
ENV SECRET_KEY_BASE="xxxxxxxxxx"
# compile dependencies
RUN mix deps.compile
# copy assets
COPY priv priv
COPY assets assets
# Compile assets
RUN mix assets.deploy
# compile project
COPY lib lib
RUN mix compile
# copy runtime configuration file
COPY config/runtime.exs config/
# assemble release
RUN mix release
# app stage
FROM debian:buster-slim AS app
ARG MIX_ENV
# install runtime dependencies
RUN apt update && apt install -y apt-transport-https libstdc++6 openssl libncursesw6 net-tools curl telnet && apt clean
ENV USER="elixir"
WORKDIR "/home/${USER}/app"
# Create unprivileged user to run the release
RUN groupadd "${USER}" && useradd -m -d "/home/${USER}" -g "${USER}" "${USER}" && su "${USER}"
# run as user
USER "${USER}"
# copy release executables
COPY --from=build --chown="${USER}":"${USER}" /app/_build/"${MIX_ENV}"/rel/myapp ./
ENTRYPOINT ["bin/myapp"]
CMD ["start"]
My docker-compose.yml
version: "3"
services:
postgres:
container_name: postgres
image: postgis/postgis:12-3.2
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 1s
timeout: 1s
retries: 120
networks:
- myapp
ports:
- 5432:5432
myapp:
container_name: myapp
image: elixir/myapp
environment:
DATABASE_URL: ecto://postgres:postgres@postgres/myapp_prod
SECRET_KEY_BASE: "tt0h95VJaD3Bw2xQiVsL7lB1hW4F4HHb2SXbT860phB0hB7dkbDk18z1Q66DChtyz"
depends_on:
- postgres
networks:
- myapp
ports:
- 4000:4000
networks:
myapp:
volumes:
postgres-data: {}
shall I use destilery to manage the ecto creation? It is better to prepare the DB independently? what are your recommendations?
had a question, whats rust doing in DEBIAN_FRONTEND? can i get some more info on that
it instructs apt on debian that it should never require any interaction ever (similar to -y, but the inverse except for "do you want to install?")
personal preference would be that the app itself keeps its migrations up to date. tho that depends on your usecase. if you require that the db changes can be traced / are controlled you might need to couple them together differently
in general statefull data like a database always requires carefull consideration with changes to shemas and such
also unrelated nitpick: i honestly would use a mix release, and assemble it in a builder stage beforehand. gonna make shit a bit smaller and you know what version you got..
i wonder whats the diff between having app and db in seperate servers? Does it really affect anything consierably compared to keeping it in same db?
its worse keeping a db and an app running in the same container. as most containers are designed to be "just" torn down and rebuilt and still retain their state via volumes
it seperates concerns without any kind of "large" overhead
say if i dont wanna use a container? i can just normally roll upgrades ???
also @midnight warren maybe dont hijack this post
sorry my bad, dint realise
I'm using a plugin with rustler "bcrypt_elixir"
I need rust to compile it
I think KECCAK-256 was not programmed yer on elixir...
i think its already present in phx.gen.auth?
So if I understood you you would move the line
RUN mix release```
to the builder stage?
idk... we should ask to https://hex.pm/users/riverrun I gues...
seems like ex_keccak is the dutty
in my own experience I saw rust crushing elixir on some operations performances, that could be the reason they preferred use rustler for this complex cryptographic functions.
ofc it will. data processing and number crunching is more befitting a language that has mutability an stuff in it. But idk if using a nif with the overhead associated with it is more performant than raw elixir (without nif overhead but with degraded perf), ig benchmarks r the only way to find out, or if some1 has already tested then its fine go ahead, becoz re-inventing the wheel is something id avoid personally. But if a nif is faster then ofc its better
I agree with you, I don't personally measure this case, I didn't get the time for it, but could be a good experiment. We made some tests using nifs with @prisma pine on the past and nif won the battles.
just in case you are interested:
https://medium.com/elixir-labs/text-search-algorithms-and-elixir-a-study-case-b0f70af13dd
ofc i am very much interested. i guessed nifs wud have an upper hand in the long run. ofc its overhead is nowhere compared to perf that differs on order of magnitudes or even if its 2x times faster, its gotten the better of nifs overhead ig
Nifs don’t have much overhead. They’re c ffi
I was able to get decent perf with pure elixir
in text search understandable, but what about bycrypt?
Doesn’t erlang have that built in?
yes, ik phx.gen.auth has it, but ryuk has done it in rust via a nif
The erlang impl is likely a bif. And bcrypt is supposed to be slow
oh, they released argon which is better in terms of security and recommended too but THAT is slow and resource-intensive, thats why people use bcrypt. but well, ig rust is better then
Being slow is the point though
That’s a bad reason to reject a kdf
Fun anecdote. I reduced unit test runs by 90% by reducing the number of rounds in argon
Went from minutes to seconds
but being slow means ur security is better right. becoz 3 hash fncs will be slower than 1, i get that. but ryuk used a plugin with rustler bcrypt_elixir, so thats what it was about, as in its inbuilt in phx.gen.auth so is it necessary to use rust? he already has the code so ofc itll be more performant, but if u wu b given an option to code it rn, or use a bif, in that case....
number of rounds as in?
I actually doubt bcrypt will perform better in rust than erlang
The number of hash rounds in argon. It’s tuneable
so how does that effect the no. of test runs? do u mean time taken to perform the entire test in total?
Yes, the time taken
Creating a user took a second
honestly, id just like to use passwordless auth, db-less. No headaches
Yeah, passwords suck
Me too, for this project I'm using Metamask and OTP via email. BCrypt is for smartcontract interaction. I will ask to Raz why he used Rust... you infected me with doubt.
so, for keccak, it was going to be, I think, sha3 but when the made the standard, they changed the implementation slightly, but ethereum adopted keccak directly and they're now incompatible.
no go for it becoz nifs overhead r not that great. if u can on paper calculate/estimate that using rust will be 2x faster or more, nifs overhead r beaten. i was talking about edge cases where perf doesnt change that much or time invested isnt proportional to the little amount of gain
I was investigating, and the problem is that SHA3 supported by Erlang is not the same as KECCAK. SHA3 is NIST, and KECCAK pre-NIST (the original variant of SHA3-256) where the delimiter byte is 0x1 rather than 0x6. So I'm working on a PR to add KECCAK support to Erlang OTP.
that is the reason why rust is being used
We could talk about optimisation once Erlang has it implemented...
go fr it, all the best
🙌 tks
I can’t imagine that erlang will implement keccak