I’ve finally automated DB migration in Ruby on Rails and ECS. This is the note for what I did.
Background
I worked on a Ruby on Rails project in ECS for the last 2 years and executed db:migrate
command manually every time I changed the database schema. I always thought I should make it automated but I’m the only engineer to maintain the Ruby on Rails project and always had a lot of things to do. So I put off the automation for later someday. Then finally I’ve done it this week while I refactored the database tables.
What I did
When I decided to do this, I remembered that the latest Ruby on Rails started to provide the official Dockerfile.
The release says “These Dockerfiles are tuned for production use” so I stopped thinking by myself and decided to ride on the rails way.
Then I checked the official Dockerfile. There are several things to be done like caching. I copied the necessary code lines below.
# Run and own only the runtime files as a non-root user for security
RUN useradd rails - create-home - shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER rails:rails
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
Kindly there is a comment and I found something in the entrypoint
easily. The code lines are the entrypint
file.
#!/bin/bash -e
# If running the rails server then create or migrate existing database
if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then
./bin/rails db:prepare
fi
exec "${@}"
When I saw the file, I was like “OK Super easy”. So All I had to do was copy the entrypoint
file to my project and change the if-condition in the bash script. I’m using puma
command directly for production in the ECS task definition so that the following code lines are my entrypoint
file.
#!/bin/bash -e
# If running the rails server then create or migrate existing database
if [ "${1}" == "bundle" ] && [ "${2}" == "exec" ] && [ "${3}" == "puma" ] && [ "${4}" == "-C" ] && [ "${5}" == "config/puma.rb" ]; then
./bin/rails db:prepare
fi
exec "${@}"
At last, I added ENTRYPOINT [“/rails/bin/docker-entrypoint”]
to my Dockerfile. Then my automation was done.
That’s it!