fireproofsocks
While working through a Docker build/deployment, it hit me that seeds are weird. Apart from requiring some extra setup (e.g. some variant of Migrations - Distillery Documentation), you can wind up in trouble if you accidentally run the seeds when you didn’t expect.
In some cases, the problems with seeds could be solved if they were treated as a migration – I even saw some Ruby Gems that do this, so other people have thought of this.
What are the thoughts about putting seeds into a migration? I don’t think there needs to be any consideration to rolling back a migration like that… the table structure or the table itself would just get altered or deleted.
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
Other Trending Topics
ReqLLM v1.28.0 has been released.
Features:
add StepFun chat and audio providers (#1087) by mikehostetler
openai: honour image deta...
New
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #ai
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
tty
Do you have the same seeds for test/dev/prod ?
fireproofsocks
Good question – I usually have a basic set of seeds that I need for prod/dev. For other non-prod environments I can add regular seeds in addition to the migrations.
shanesveller
Personally, I also have to fight this attitude/approach at work and it’s a hill I’m willing to die on: this is an abuse of the migrations system. Just use a seeds file, or preferably a more robust vanilla-Elixir module that calls either raw Ecto or Context functions. Expend the modicum of effort to make sure they’re idempotent, and they’re just as safe to run and rerun as
mix ecto.migratecan be.Table/column/index definitions aren’t the same thing as prepopulated data and they shouldn’t be managed the same way. Data insertions in migrations should be minimal, and any data updates done in a migration should be as necessary due to column changes, and execute as quick as possible. More general data munging and sanitization are an operational task that can and should happen out of band.
The only benefit you get from using migrations for this is quick proof that they have been run in the past, and a shortcut to preventing them from running again. Proper idempotence is far more preferable.
You can’t really undo a single migration from history, without just creating an inverse migration, but you can easily clean up rows that are no longer necessary through normal means.
What happens as the data you seed evolves with the application? Do you really want a new migration every time a value changes or an attribute gets added? We should never be editing existing migration files that have been broadly applied. If you adhere to that, is there actual value being captured in all of the prior historical migrations, that aren’t already captured by your VCS data? It’s just cruft, as we often only care about the current/latest state of that info.
Eventually you’ll likely run into the scenario where not every environment gets all the same bits of prepopulated data, and the migrations system is going to be inflexible enough to make this feel pretty clunky.
fireproofsocks
I agree with some of that, but it’s so much more work to get seeds working in prod. That’s high risk, whereas migrations are shepherded. Why re-invent that particular wheel? For some of the tables (like a list of ISO country codes), the data is really static and importantly, the app won’t work without it. So it’s not the same as run-of-the-mill seed data: in some cases it’s critical to the app functionality. I’m not sure it’s worth dying on that hill one way or another, there are tradeoffs in the approaches.
shanesveller
What issues are you facing getting them to work in production? Let’s chat about that!
fireproofsocks
Re deployments: I can’t figure out any other way to get my migrations and seeds to run other than having a separate duplicated image for my app in docker-compose.
It just feels really smelly. And having to construct a separate app (e.g. as outlined by Migrations - Distillery Documentation) also feels like it needs improvement.
Ideally, I would love to have a simpler setup for deployments:
mix cmd mix ecto.migrateon startupI deal with docker-compose maybe once or twice per year, so my understanding is pretty fragile… I usually figure out how to deploy the app I’m working on and then forget about everything. I just know it was a lot simpler in the previous apps I built (PHP apps). Any feedback on this would be great!
shanesveller
Are you using Docker-Compose for your production deployments?
I’d probably use
docker-compose run --rm myapp migrateanddocker-compose run --rm myapp seedafter setting up theReleaseTasksmodule per the document you linked, plus the twomigrateandseedDistillery commands. Obviously, this doesn’t automate the execution of the migrations/seeds as you bring up the application if you’re only typingdocker-compose up [-d], but it’s a simple, documentable step that doesn’t leave you with the second container lingering.If you are running
docker-composeon your production deployment targets, hopefully you’re wrapping it with a Systemd unit or something, where you could add anExecStartPostor similar hook.I keep a skeleton repo to be a companion to blog posts and other open demonstrations, which has these implemented if you’d like to see a concrete example:
fireproofsocks
Cool, that’s helpful. Thank you for the references!
fireproofsocks
Thinking about this more… so the Dockerfile’s default CMD is “foreground” (from Distillery). So in order to get things started up and seeded, I think I can do one of the following:
docker-compose.ymlspecifies that our Elixir servicedepends_onthe database, then we can run it this way:That works but it always seems to kick off a few errors when the migrations are started:
and a few errors when the seeds are finished:
OR, if there is no
depends_onstipulation:and in another, fire up the temporary images + commands:
Which also works, but it gets the error upon conclusion of running the seeds.
And thirdly… the more I think about it, the more I think that there ARE cases where seeds should be included as migrations. I have a handful of behaviours that rely on dynamic dispatch, and the value that triggers the dispatch ultimately comes from the database. It’s not quite as on the nose as having a module name in the database (or some variant of polymorphism?), but we have situations where stuff like an order includes a unique string value representing say a vendor ID. And that vendor ID needs to trigger specific code to execute. So when we onboard a new vendor, we will have a new module (i.e. a new implementation of the order handling behaviour) and we’ll have a new row in the
vendorstable. Those two things need to go out together. I realize that may be an edge case, but it really feels like a migration is the proper way to handle that particular seed.Sorry – 3 things in that post, but I’d love to hear your thoughts.
axelson
Populating your vendors table sounds like it will work fine with a seeds file. Just create a new entry if the vendor_id doesn’t exist.