Skip to content

Commit 7fd0852

Browse files
committed
Modified the volume section
1 parent e4e4555 commit 7fd0852

File tree

1 file changed

+39
-134
lines changed

1 file changed

+39
-134
lines changed

content/guides/use-case/pre-seeding.md

Lines changed: 39 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ In this guide, you will learn how to:
1111

1212
- Use Docker to launch up a Postgres container
1313
- Pre-seed Postgres using a SQL script
14-
- Pre-seed Postgres by using volumes to mount SQL files
14+
- Pre-seed Postgres by copying SQL files into Docker image
1515
- Pre-seed Postgres using JavaScript code
1616

1717
## Using Postgres with Docker
@@ -81,7 +81,7 @@ Assuming that you have an existing Postgres database instance up and running, fo
8181
INSERT INTO users (name, email) VALUES
8282
('Alpha', '[email protected]'),
8383
('Beta', '[email protected]'),
84-
('Gamma', '[email protected]');
84+
('Gamma', '[email protected]');
8585
```
8686

8787
The SQL script creates a new database called `sampledb`, connects to it, and creates a `users` table. The table includes an auto-incrementing `id` as the primary key, a `name` field with a maximum length of 50 characters, and a unique `email` field with up to 100 characters.
@@ -151,162 +151,76 @@ Now that you have learned how to launch Postgres and pre-seed the database using
151151

152152
Make sure you stop any running Postgres containers (along with volumes) to prevent port conflicts before you follow the steps:
153153

154-
1. Create a named volume.
154+
1. Modify the `seed.sql` with the following entries:
155155

156-
Use the `docker volume create` command to create a named volume.
157-
158-
```console
159-
$ docker volume create data_sql
160-
```
156+
```sql
157+
CREATE TABLE IF NOT EXISTS users (
158+
id SERIAL PRIMARY KEY,
159+
name VARCHAR(50),
160+
email VARCHAR(100) UNIQUE
161+
);
161162

163+
INSERT INTO users (name, email) VALUES
164+
('Alpha', '[email protected]'),
165+
('Beta', '[email protected]'),
166+
('Gamma', '[email protected]')
167+
ON CONFLICT (email) DO NOTHING;
168+
```
169+
162170
2. Create a text file named `Dockerfile` and copy the following content.
163171

164172
```plaintext
173+
# syntax=docker/dockerfile:1
165174
FROM postgres:latest
166-
VOLUME /docker-entrypoint-initdb.d
175+
COPY seed.sql /docker-entrypoint-initdb.d/
167176
```
168177

169-
3. Build the custom Docker image called `mynewpostgres`.
170-
171-
```console
172-
$ docker build -t mynewpostgres .
173-
```
174-
175-
4. Run the following command to successfully mount the volume and run the Postgres container.
176-
177-
Assuming that the existing `seed.sql` (used in previous steps) is placed under the same directory, run the following command:
178-
179-
```console
180-
$ docker run --rm \
181-
-v $(pwd)/seed.sql:/sql-files/seed.sql \
182-
-v data_sql:/docker-entrypoint-initdb.d \
183-
mynewpostgres cp /sql-files/seed.sql /docker-entrypoint-initdb.d/
184-
```
185-
186-
This command mounts your `seed.sql` file from the current directory (`$(pwd)/seed.sql`) into the temporary container at `/sql-files`, and then copies it into the `data_sql` named volume.
187-
188-
> [!TIP] Running on Windows
189-
> When running this command on Windows, use `${PWD}` (in uppercase and with curly brackets) instead of `$(pwd)`, and make sure to execute the command in PowerShell:
178+
This Dockerfile copies the `seed.sql` script directly into the PostgreSQL container's initialization directory.
190179

191-
192-
```console
193-
$ docker run --rm \
194-
-v ${PWD}/seed.sql:/sql-files/seed.sql \
195-
-v data_sql:/docker-entrypoint-initdb.d \
196-
mynewpostgres cp /sql-files/seed.sql /docker-entrypoint-initdb.d/
197-
```
198-
199-
This ensures that the volume is mounted correctly on the Windows systems.
200-
201-
5. Now that your `seed.sql` file is in the `data_sql` volume, you can run your `mynewpostgres` image and mount the named volume:
202-
203-
```console
204-
$ docker run --name mynewpostgres \
205-
-p 5432:5432 \
206-
-e POSTGRES_PASSWORD=mysecretpassword \
207-
-v data_sql:/docker-entrypoint-initdb.d \
208-
mynewpostgres
209-
```
210-
211-
Open a new terminal and run the following command to verify the database and tables seeded into the database.
212-
```console
213-
psql -h localhost -U postgres sampledb
214-
```
215-
216-
Enter `mysecretpassword` when prompted for the password. Run the following command to verify if the table named users is populated in the database `sampledb` or not.
217-
218-
```console
219-
sampledb=# select * from users;
220-
id | name | email
221-
----+-------+-------------------
222-
1 | Alpha | [email protected]
223-
2 | Beta | [email protected]
224-
3 | Gamma | [email protected]
225-
3 rows)
226-
```
227-
228-
Now that you’ve been shown how to pre-seed a database by using volumes, let’s see how you can simplify the whole process of seeding by using a single Docker Compose file.
229-
230-
> [!TIP]
231-
> Make sure you stop any running Postgres containers(along with volumes) to prevent port conflicts before you follow the next steps.
232-
233-
First, you will need to create the following project directory structure:
234-
235-
```console
236-
$ tree
237-
.
238-
├── compose.yml
239-
└── sql_files
240-
└── seed.sql
241-
```
242180

243-
1. Start by writing the compose file
244-
245-
This compose.yml file defines a Postgres service named `db` using the latest Postgres image, which sets up a database with the name `sampledb`, along with a user `postgres` and a password `mysecretpassword`.
181+
3. Use Docker Compose.
182+
183+
Using Docker Compose makes it even easier to manage and deploy the PostgreSQL container with the seeded database. This compose.yml file defines a Postgres service named `db` using the latest Postgres image, which sets up a database with the name `sampledb`, along with a user `postgres` and a password `mysecretpassword`.
246184

247185
```yaml
248186
services:
249-
db:
250-
image: postgres:latest
251-
container_name: my_postgres_db
252-
environment:
253-
POSTGRES_USER: postgres
254-
POSTGRES_PASSWORD: mysecretpassword
255-
POSTGRES_DB: sampledb
187+
db:
188+
build:
189+
context: .
190+
dockerfile: Dockerfile
191+
container_name: my_postgres_db
192+
environment:
193+
POSTGRES_USER: postgres
194+
POSTGRES_PASSWORD: mysecretpassword
195+
POSTGRES_DB: sampledb
256196
ports:
257197
- "5432:5432"
258198
volumes:
259199
- data_sql:/var/lib/postgresql/data # Persistent data storage
260-
- ./sql_files:/docker-entrypoint-initdb.d # Mount local sql file to seed the database
261200

262-
volumes:
263-
data_sql:
201+
volumes:
202+
data_sql:
264203
```
265204
266-
It maps port `5432` on the host to the container's `5432`, let you access to the Postgres database from outside the container. It also defines two volumes: one (`data_sql`) for persisting the database data, ensuring that data is not lost when the container is stopped, and another volume that mounts the local `sql_files` directory into `/docker-entrypoint-initdb.d` within the container. This mounted directory contains a SQL file that is automatically executed when the Postgres container is initialized, allowing pre-seeding of the database.
205+
It maps port `5432` on the host to the container's `5432`, let you access to the Postgres database from outside the container. It also define `data_sql` for persisting the database data, ensuring that data is not lost when the container is stopped.
267206

268-
2. Create a new directory `sql_files/` and copy the following `seed.sql` to this new directory:
269207

270-
```plaintext
271-
-- Ensure the users table is created in the sampledb database
272-
273-
CREATE TABLE IF NOT EXISTS users (
274-
id SERIAL PRIMARY KEY,
275-
name VARCHAR(50),
276-
email VARCHAR(100) UNIQUE
277-
);
278-
279-
-- Insert sample data into the users table
280-
INSERT INTO users (name, email) VALUES
281-
('Alpha', '[email protected]'),
282-
('Beta', '[email protected]'),
283-
('Gamma', '[email protected]')
284-
ON CONFLICT (email) DO NOTHING;
285-
```
286-
287-
This SQL script ensures that the users table is created in the `sampledb` database if it doesn't already exist. The table includes three columns: id, which is a serial primary key, name (a VARCHAR of 50 characters), and email (a VARCHAR of 100 characters that must be unique). The script also inserts three user records into the users table, but if a conflict occurs on the email field (i.e., if the email already exists), the insertion is skipped, ensuring no duplicate emails are added.
288208

289209
3. Bring up the Compose service.
290210

211+
Assuming that you've placed the `seed.sql` file in the same directory as the Dockerfile, execute the following command:
212+
291213
```console
292-
$ docker compose up -d
214+
$ docker compose up -d --build
293215
```
294216

295217
4. It’s time to verify if the table `users` get populated with the data.
296218

297219
```console
298-
psql -h localhost -U postgres sampledb
220+
$ docker exec -it my_postgres_db psql -h localhost -U postgres sampledb
299221
```
300222

301-
Enter `mysecretpassword` when prompted for the password.
302-
303-
```plaintext
304-
Password for user postgres:
305-
psql (15.8 (Homebrew), server 16.4 (Debian 16.4-1.pgdg120+1))
306-
WARNING: psql major version 15, server major version 16.
307-
Some psql features might not work.
308-
Type "help" for help.
309-
223+
```
310224
sampledb=# select * from users;
311225
id | name | email
312226
----+-------+-------------------
@@ -318,15 +232,6 @@ $ tree
318232
sampledb=#
319233
```
320234

321-
> [!TIP]
322-
> If you're encountering the error 'more' is not recognized as an internal or external command when running queries in `psql` on a Windows system, this is likely due to an issue with the pager setting, which uses external programs like more or less to paginate query results. You can resolve this by turning off pagination within `psql` using the following command:
323-
324-
```console
325-
\pset pager off
326-
```
327-
328-
To avoid running this command every time, you can permanently disable the pager by adding \pset pager off to your psqlrc.conf file, which is located in the `%APPDATA%\postgresql\` directory on Windows. This will ensure that query results are always displayed without invoking an external pager program.
329-
330235

331236
## Pre-seeding the database using JavaScript code
332237

0 commit comments

Comments
 (0)