I want to perform a Drizzle Migration on Production on a VPS.
I can't run 2 commands pnpm db:migrate:prod & pnpm start in a Dockerfile.
Dockerfile
# Where & how do I run `db:migrate:prod`?
CMD ["npm", "run", "start"]
I want to create users.prod.sqlite on the production server that is persisted even if the container goes down.
Starter repo -> https://github.com/deadcoder0904/easypanel-nextjs-sqlite/tree/1fb34233283b1ff7b07b7f18e6973125ff96cbba
How would I do it?
Latest answer (USE THIS)
I had to create a new
package.jsonwith just Drizzle Migration dependencies.package.json
I also removed
node_modulesfrom the final image as it wasn't required anymore. This reduced the image size a lot down to just 175mb.I removed
prod-dependenciesFROM-block from Dockerfile so it simplified it a bit.And copied
scripts/package.jsonto install dependencies from it.Dockerfile
I install the only needed dependencies for migration here.
run.sh
New Answer
I removed the
pnpm installfromrun.shthat was slow to boot container (docker compose up) up. So the 1 minute wait went away. And I copiednode_moduleswith production dependencies in the final stage which made my image go from 198mb to 611mb but that's okay for me.Then I tried adding SQLite WAL mode which resulted in data loss due to networking issue. Idk why that doesn't work properly but its neither Docker's fault nor my Volume syntax was wrong. So I commented out WAL mode & everything works fine now.
The new solution uses security best practices in Node.js by using non-privileged users. And the solution is much cleaner & simpler to understand.
docker-compose.yml
Dockerfile
run.sh
Old Answer (DO NOT USE THIS)
So I figured it out myself. I used a
run.shscript to run both those scripts.run.shcontains bothpnpm db:migrate:prod&pnpm startbut I used directnode server.jsbecause its a best practice as it handles PID well.I also used anonymous volumes to maintain
node_modulescourtesy of https://michalzalecki.com/docker-compose-node/. I install dependencies inrun.shscript so it takes time to get container up. Like 1 minute. But its a one-time process so I don't mind however I'd like to optimize.Anyways, the full solution is at https://github.com/deadcoder0904/easypanel-nextjs-sqlite/
I also used permissions like chown as I learned its a Node.js best practice.
docker-compose.yml
Dockerfile
run.sh
The full working version is at https://github.com/deadcoder0904/easypanel-nextjs-sqlite/
The only caveat right now is when I start the container, it takes time because it is doing
pnpm install.I'd love to figure out how to make it so that it doesn't have to
pnpm installevery time I domake start-productionin my project. I useMakefilewhich you can check at the linked repo.