Docker postgresql volume windows

Docker for Windows: Mounting volumes not working with dockerized postgresql

I’m running Docker on a Windows 10 machine. I’m trying to run a dockerized postgresql database, whose data can be mounted on my Windows 10 machine. I then want to be able to push this database data on a GitLab repository. If any other user wants to use the newest version of the database after that, he just needs to pull the changes and then mount the data on a dockerized postgresql.

Why do I want to do that?

We’ll, there will be a lot of changes in this database. People are also working simultaneous on different version of our program. With a persistent database I would need to manage different versions of the database for every single feature branch, develop branch and master/release branch. That’s just too much to handle. So ideally any changes made of the database for a specific feature branch can only be found in this specific feature branch. There would be no conflicts. It also allows to experiment with the database, without destroying it for any other user.

Well, what is the problem then?

TL;DR: Right now it’s not possible to mount volumes from Windows to Linux containers. There are workarounds for that, as it’s said in the link, but no to get those data from the database, to actively push/share it etc., but just to have a database persistent on a local system.

Well, I tried almost anything my mind came up with:

Did a docker-compose, used named volumes and I also tried to use

but it didn’t help either.

I also used, as said before, named volumes in a docker-compose file:

But guess what: It still failed.

I know I can create dump of my database and push that, but the problem here is: I dont want to do that manually all the time. I would rather prefer a smooth solution, without creating and loading a dump every single time. I just want to start a docker-compose file that mounts the data of the database and that’s it: Very easy and nice solution.

Docker контейнер с данными на Postgres для интеграционного тестирования и лёгким расширением

Про использование Docker и Docker-compose последнее время написано очень много, например рекомендую недавнюю статью на Хабре, если вы до сих пор не прониклись. Это действительно очень удобно, а в связке в ansible особенно. И я его использую везде. От разработки, до автоматического интеграционного тестирования на CI . Про использование в тестировании, тоже писали. Это здорово и удобно. Однако, для локальной разработки, для траблешутинга данных «как в продакшене» или тестирование производительности, на «объёмах близких в продакшену», хочется иметь под рукой образ, содержащий базу, «как в продакшене»!

Читайте также:  Прекращена работа хост процесс для задач windows

Соответственно, хочется, чтобы каждый разработчик, приступая к работе над проектом, мог запустить его одной командой, например:

и приложение поднялось бы сразу со всеми необходимыми связанными контейнерами? А главное чтобы в нём уже были бы данные для большинства кейсов разработки и багфиксинга, стандартные пользователи и большинство работающих сервисов, над которыми сразу можно было бы приступить работать, не тратя времени на экспорт-импорт каких-то там образов или демоданных!

Как приятный бонус, ну разве не здорово иметь базу данных в несколько гигабайт и возможность откатиться к её исходному (или любому другому коммиту) состоянию в течении пары секунд?

Разумеется мы поговорим о написании Dockerfile для такого образа с данными, и некоторых подводных камнях этого процесса.

Вот на этом и сосредоточимся. В нашем приложении мы активно используем Postgres , поэтому повествование и примеры будут о контейнере именно с ним, но это касается лишь примеров, суть изложения применима к любой другой реляционной или модной NoSQL базе данных.

Чего хочется

Для начала определим проблему подробнее. Мы готовим образ, с данными, с которыми сможет работать каждый, кто работает с нашим приложением:

  • Некоторые данные нуждаются в обфускации (например почтовые ящики или личные данные пользователей) — то есть нельзя просто восстановить дамп, требуется его обработка
    • Однако мы хотим общий механизм накатывания предоставленных для сборки SQL скриптов, без дальнейшей модификации механизма сборки! Например это может использовать для семплинга (уменьшения количества данных) и уменьшения размера образа
  • Хочется удобно включать в образ дополнительные настройки, не передавая их опциями во время запуска и не модифицируя каждый раз конфиг сложными регулярными выражениями
    • Мы хотим включить в образ некоторые расширения конфигурации, чтобы не писать огромные мануалы как его запускать (передавая обязательные для старта опции в момент запуска)
    • Данных много, поэтому хочется также включить оптимизационные настройки для увеличения производительности
    • Вообще, для многих настроек, вы можете это сделать через стандартные пути расширения, выполнив ALTER SYSTEM команды. Но это только для тех настроек, которые не требуют определения только в конфигурацонном файле или параметрах запуска.
  • Данные одинаковые, для разработчиков и CI

Приступаем

Я не буду начинать с того что такое Dockerfile , надеюсь вы уже знакомы с этим. Тех же, кто хочет получить представление, отсылаю к статье, ну или официальной документации.

Стоит отметить что официальный docker образ postgres уже имеет несколько точек расширения:

  • POSTGRES_* переменные
  • И директорию внутри образа /docker-entrypoint-initdb.d куда можно положить sh скрипты или sql файлы, которые будут выполнены на старте. Это очень удобно, если вы скажем хотите создать дополнительных пользователей или базы данных, установить права, проинициализировать расширения.

Однако, для наших целей этого мало:

  • Мы не можем включать некоторые данные, затирая их на старте:
    • Во-первых это может привести к огромному размеру БД (мы хотим удалить некоторые логи или историю)
    • Во вторых, пользователь может запустить образ переопределив entrypoint , и увидеть приватные данные, которые видеть не должен
  • Дополнительно, мы можем передавать практически любые параметры в командной строке при запуске, вроде —max_prepared_transactions=110 , но мы не можем легко положить их в образ, и сделать стандартными
    • Так, например, раз мы строим образ для тестирования и имеем быстрый откат, я хочу включить в него агрессивные настройки оптимизации производительности, нежели надёжности (включая полное отключение fsync )
Читайте также:  Shareit для компьютера для windows 10

Я наверное сразу покажу прототип файла (вырезаны лишь некоторые незначащие части чтобы он стал меньше, например много места занимает включение расширения pg_hint_plan , которое ставится на Debian из RPM , потому что отсутствует в Deb и официальных репозиториях):

Как видите, я постарался добавить комментарии прямо в файл, возможно они даже более чем исчерпывающие, но всё-таки остановимся на паре моментов подробнее.

Стоит обратить внимание

Готовому образу остаётся только присвоить тэг и запушить в репозиторий. Чаще всего, конечно, это будет приватный репозиторий, если вы не работает над каким-то публичным сэмплом данных.

Я буду очень рад, если это поможет кому-то сделать его процесс подготовки создания тестовых образов с данными хоть чуточку проще.

PostgreSQL docker container on Windows

I’ve been trying to run a PostgresSQL Docker container on my Windows machine and mounting the data volume, using the following command:

However I keep getting a list of permission denied errors when the container tries to spin up:

Can someone point out what I’m doing wrong?

Thanks in advance.

3 Answers 3

This is known limitation in Docker for Windows. The Linux Windows filesystem mapping semantics from your Windows dir to the Linux dir are imperfect because the mount is done with CIFS/SMB. One of the things that won’t work is chown (changing the owner) because that cannot be mapped to your Windows filesystem.

I posted a partial solution to one of the related git issue links. A partial workaround can be done by using Postgres tablespaces to store the database object files on the windows host system. It is not a perfect solution because the core data directory (represented by PGDATA ) still resides on the LinuxVM. But at least you can manage subsequent database creation and file storage on the Windows host and outside the Linux VM.

This sets the default data storage to a (persistent) directory on the Linux VM ( /var/lib/docker/basedata ). It also tells docker to mount your windows D:\data\largedb as a volume that is visible to the Postgres container as /mnt/largedb . (The windows directory need not exist yet.) Log into postgres and using psql or whatever tool, execute the following DDL:

Go ahead and create tables and data in my_large_db . Stop the containter. Navigate to D:\data\largedb in Windows Explorer and you will see data files. Restart the container and you will see the data from the previous session.

(Note: Docker Desktop for Windows (2.2) on Win 10 which uses the DockerDesktopVM and not MobyLinux or docker-machine.)

How to use volume in docker compose for postgres?

Here is the image I am using.

I named it posgres_test

If I run the image individually

I can access it with

Or I can access it with my golang app

However if I use docker compose

I get the following

I know for sure test_db exist in test_volume since

Читайте также:  Все лайфхаки windows 10

will show the table I created

But it seems like my app in docker compose cannot find it

Can someone help me out?

3 Answers 3

About your docker-compose file

Firstly I thought it’s because you don’t use ‘links’ option to link your postgres container to web container — it’s good practice if you don’t expand ports — but you expand postgres port.

If you want use inheritance from the image you posted Instead of using this line:

and create path docker/postgres and there place Dockerfile with inharitance from container you want.

I always use sharing volumes in docker-compose.yml like this:

where . is my project path where I place my code files.

Image I created to test this case

I don’t have your all docker files structure to reproduce this error and fix it, so I created docker-compose which should match your needs or help to fix your issue:

I will recommend use official postgres image

I left comments next to the lines.

How I made connection:

Because my web container know host dbpostgres(image name and domain name) now — I link them using links.

If you need database from existing container

If you need database from your existing container just use option docker cp to copy database localy:

where /private/var/lib/postgresql is path on your localhost. You need also change credentials to db in docker-compose to your old credentials. You have to do it before run docker-compose because if db doesn’t exist, will be crated.

PostgreSQL in Docker & Docker Volume Mounting

Dear reader, In this article I will teach how to use postgres in docker. We will also keep the data of the database using docker volume mount. Now we dont need to install any database to our development systems.

Docker is a containerization platform that packages your app and all its dependencies together in the form called a docker container to ensure that your application works seamlessly in any environment. This environment might be a production or staging server. Docker pulls the dependencies needed for your application to run from the cloud and configures them automatically. You don’t need to do any extra work.

You can install docker from the docker hub website. https://docs.docker.com/docker-for-mac/install/

Pull the docker postgresql volume

Create a Directory to Serve as the Local Host Mount Point for Postgres Data Files

we want to persist data generated by the Postgres instance running inside a docker container beyond the container’s lifecycle. We need to map a local mount point as a data volume to a path inside the container.

I create a volumes folder (we can give the folder any name we like) in my home directory and then create subfolders for each of the applications I need to create data volume mount points for.

It will create a directory in Home folder series (for mac and linux).

Run the PostgreSQL container

Starting the Postgres container is as simple as running the docker run command

Go to PG admin I created a new server instance Password: postgres

Оцените статью