I'm just starting with docker and I'm a bit confused with the volumes. Suppose I have create a container with a volume, a folder from my computer and a folder from the container. Later in my pc folder I create a new sqlite database (so it is also created in the container, right?). When the container dies and you create a new container FROM THE SAME IMAGE, the database will still be there. Am I ok so far? But the image has been updated with this new database or what has happened? If not, is it better in these cases to rebuild the image and build a container? (or when should i rebuild the image? when i change environment variables?) Thank you very much, I hope you can help me!
CodePudding user response:
Perhaps a simpler case is if the database is in a separate container. Consider this docker-compose.yml
file:
version: '3.8'
services:
app:
build: .
ports: ['8000:80']
environment: { PGHOST: db, ... }
db:
image: 'postgres:15.1'
environment: { ... }
volumes:
- 'dbdata:/var/lib/postgresql/data'
volumes:
dbdata:
First, notice that nothing at all is mounted on the app
container. If the code changes, you must rebuild the image, and if the image changes you must recreate the container. (Compare to compiled languages like C , Go, Rust, Java, or Elixir: if you change your code you generally must recompile the executable and then launch a new process.)
Hopefully the basic lifecycle of the db
container and dbdata
named volume are clear.
Now assume that a PostgreSQL 15.2 is released, and you change the image:
accordingly. The official image build can't know about your specific data, and it can't be included in the image. Instead, the existing volume will get mounted into a new container running the new image.
[I'd recommend a setup like this if possible, with data stored in a database separate from your application container. This is helpful if you ever want to run multiple replicas of your application, or if you're considering running the database on dedicated hardware or a hosted public-cloud offering.]
You should be able to generalize this to the setup you describe in the question. If you have more like:
version: '3.8'
services:
app:
build: .
ports: ['8000:80']
volumes:
- ./data:/app/data # containing the SQLite file
The bind-mounted /app/data
directory actually has its storage outside the container. If the container is deleted and recreated, the data is still there. You do need to rebuild the image if the code changes, but the data is not stored in the image at all (and while it's accessible from the container, it's not stored in the container filesystem as such).