重启容器为何需始终执行db:create?Docker Compose Rails场景疑问
db:create Every Time I Restart My Rails Docker Containers? Great question—this is a super common gotcha when you’re getting started with Docker Compose and Rails, and it all comes down to data persistence and how Docker handles volumes by default. Let’s break this down clearly:
Root Causes
- No Persistent Volume for the Database: The default setup from the Docker docs doesn’t configure a named volume for your PostgreSQL/MySQL container. When you run
docker-compose down, Docker deletes unnamed temporary volumes along with the containers. That means all your database data gets wiped every time you tear down the environment—so you have to re-create the database from scratch. docker-compose downvs.docker-compose stop: Thedowncommand isn’t just stopping containers—it removes them, plus networks and unmounted volumes. If you usestopinstead, containers are halted but not deleted, and your data stays intact. But even then, without a persistent volume, deleting the container later will still lose your data.- Fresh Environment Bias: The Docker guide is built for quick, disposable setups to help new users get up and running fast. It doesn’t prioritize long-term data retention out of the box.
Fixes to Avoid Re-running db:create Every Time
1. Add a Persistent Volume to Your Database Service
Update your docker-compose.yml to include a named volume for the database. This stores your database data on your host machine, so it survives container deletions. Here’s how to adjust your config:
version: '3.8' services: web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/app ports: - "3000:3000" depends_on: - db db: image: postgres:15-alpine environment: POSTGRES_PASSWORD: password # Add this line to persist database data volumes: - postgres_data:/var/lib/postgresql/data/ # Define the named volume at the top level of the file volumes: postgres_data:
With this setup, docker-compose down won’t delete the postgres_data volume—your database will stay intact through restarts.
2. Run db:create Only Once
After setting up the persistent volume:
- Run
docker-compose run web rake db:createone time to initialize your database. - For future restarts, just use
docker-compose up(ordocker-compose startif you usedstopearlier). - When you have new migrations, run
docker-compose run web rake db:migrate—no need to re-create the database ever again.
3. Use docker-compose stop for Temporary Halts
If you just need to pause your app temporarily (not tear down the entire environment), use:
docker-compose stop
To start it back up later:
docker-compose start
This preserves containers, volumes, and all your data—so you won’t need to touch db:create at all.
内容的提问来源于stack exchange,提问作者norman.lol

