I published elxsy as my first phoenix project and put it in production already. I like to live dangerously and learn from trial error, mistakes, what can I say It is very early and if I am doing something wrong, I can pivot very easily.
Let me tell you about my setup.
I run on a VM that I look after and maintain. I build with the following setup on the production VM as my dev machine is completely different and not using any build machines, services as of now. From farm to the table!
0 to release - build.sh
git pull
# Initial setup
mix deps.get --only prod
MIX_ENV=prod mix compile
# Compile assets
npm install --prefix ./assets
npm run deploy --prefix ./assets
mix phx.digest
# Run migrations
MIX_ENV=prod mix ecto.migrate
# Build the release and overwrite the existing release directory
MIX_ENV=prod mix release --overwrite
patch.sh
git pull
# Initial setup
MIX_ENV=prod mix compile
# Build the release and overwrite the existing release directory
MIX_ENV=prod mix release --overwrite
service .... stop
service ... start
I run the service on a port and NGINX at the front as a reverse proxy.
Questions:
I have had a bug and received many internal server errors but the syslogs were all OK! Just the request and session logs. I was monitoring the logs and triggering the error to spot the bug but I couldn’t. Is there something wrong with my setup that errors didn’t log?
I would like to push non breaking, db free updates in blue-green deployment manner without downtimme. patch.sh is a workaround for this but still involves service stop and start. Ideally bring the new version up and then take down the old.
I would like to push db breaking changes actively ideally if not minimum downtime with active, passive where possible.
I have some ideas, I know a bit about the nodes but my lack of experience and knowledge is bigger than what I know about running phoenix apps.
I wanted to check if I am reinventing the wheel here, solving an already solved problem and make use of your experiences before I attempt the work.
Your setup is normal; however I don’t understand your questions. There is nothing in your setup about logs, so I’d assume you intent to log to stdout and capture those with systemd and redirected to syslog? Was it not happening? If so, you need to consult systemd’s manual.
For continuous deployment you have 2 choices: hot code update or just restart. Hot code update is quite tricky and I have no idea; my service restart in seconds so that’s what I do.
For blue/green I like to have the app as stateless as possible, and put two instances of a release on different ports behind nginx. Since all state is in the DB, I start the second release, switch the exposed release with nginx, and stop the first release. Of course this is scripted to minimize manual work. A friend made a whole ansible configuration for that. A CI/CD system could also do that.
This setup made my life easier, but again my apps do not contain state that isn’t backed by the DB. I have some Agents, some GenServers, but they’re writing to the DB and reading from it in the background. We also run postgres, nginx and elixir on the same machine, it’d be a bit more setup if it spanned multiple machines.
This way, my virtual servers are almost disposable and only need nginx/postgres.
I reckon I see where you’re coming from on the introduce CI/CD way later, but, I’ll throw this here regardless (so you can keep it at the back of your mind).