Some OCI images declare volumes for data directories that should persist independently from the container. sdme detects these declarations and automatically creates host-side directories that are bind-mounted into the container.
This tutorial demonstrates OCI auto-volumes using PostgreSQL, which declares /var/lib/postgresql as a volume.
Import PostgreSQL
Make sure you have a base rootfs imported (see the different rootfs tutorial). Then import PostgreSQL as an OCI application:
sudo sdme fs import docker.io/postgres --base-fs ubuntu
Verify that sdme detected the volume declaration:
sudo cat /var/lib/sdme/fs/postgres/oci/apps/postgres/volumes
You should see /var/lib/postgresql.
Create and start the container
PostgreSQL requires a password to be set via the POSTGRES_PASSWORD environment variable. Use --oci-env to pass it:
sudo sdme create --name mydb -r postgres --network-zone=services --hardened --oci-env POSTGRES_PASSWORD=secret --started
sdme automatically creates a host directory at /var/lib/sdme/volumes/mydb/var-lib-postgresql and bind-mounts it into the container at /oci/apps/postgres/root/var/lib/postgresql.
You can verify the volume is mounted:
sudo ls -la /var/lib/sdme/volumes/mydb/
Check the logs
sudo sdme logs mydb --oci
PostgreSQL should be running and ready to accept connections.
Connect to the database
sudo sdme exec mydb --oci -- psql -U postgres -c 'SELECT version();'
Data persistence
The key benefit of OCI volumes is that data persists even when the container is removed.
Create a test table:
sudo sdme exec mydb --oci -- psql -U postgres -c 'CREATE TABLE test (id int, name text);'
sudo sdme exec mydb --oci -- psql -U postgres -c "INSERT INTO test VALUES (1, 'hello');"
Remove the container:
sudo sdme stop mydb
sudo sdme rm mydb
The volume data is still on the host:
sudo ls -la /var/lib/sdme/volumes/mydb/
Create a new container from the same rootfs:
sudo sdme create --name mydb -r postgres --network-zone=services --hardened --oci-env POSTGRES_PASSWORD=secret --started
Verify the data survived:
sudo sdme exec mydb --oci -- psql -U postgres -c 'SELECT * FROM test;'
Where volumes live on the host
OCI volume data is stored under /var/lib/sdme/volumes/{container}/. The volume path from the OCI image is sanitized (slashes replaced with dashes) to create the directory name:
/var/lib/postgresql -> /var/lib/sdme/volumes/mydb/var-lib-postgresql
Suppressing auto-volumes
If you don't want sdme to auto-mount the declared volumes, use --no-oci-volumes:
sudo sdme create --name mydb -r postgres --no-oci-volumes
You can also use --bind to override a specific volume path with your own host directory. User --bind flags take priority over auto-volumes for the same container path.
Other images with volumes
Many database and stateful images declare volumes in their OCI config:
- mysql:
/var/lib/mysql - mariadb:
/var/lib/mysql - postgres:
/var/lib/postgresql - mongo:
/data/db,/data/configdb
Not all images declare volumes. For example, redis and nginx do not. Use --bind to manage data directories for those images manually. See the bind mounts tutorial for details.