├── .dockerignore ├── .gitignore ├── .my.cnf ├── .psqlrc ├── Dockerfile ├── README.md ├── docker-compose.yml ├── fetch-chinook-data.sh └── fetch-f1db-data.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .git 3 | .gitignore 4 | docker-compose.yml 5 | Dockerfile 6 | README.md 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data 2 | !data/.gitkeep 3 | f1db.sql.gz 4 | -------------------------------------------------------------------------------- /.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | skip-networking=0 3 | skip-bind-address 4 | -------------------------------------------------------------------------------- /.psqlrc: -------------------------------------------------------------------------------- 1 | -- Recommended psql config from Chapter 6: The SQL REPL — An Interactive Setup 2 | 3 | -- These set commands are noisy; let's shush 'em. 4 | \set QUIET ON 5 | 6 | \set PROMPT1 '%~%x%# ' 7 | \x auto 8 | \set ON_ERROR_STOP on 9 | \set ON_ERROR_ROLLBACK interactive 10 | 11 | \pset null '¤' 12 | \pset linestyle 'unicode' 13 | \pset unicode_border_linestyle single 14 | \pset unicode_column_linestyle single 15 | \pset unicode_header_linestyle double 16 | \set intervalstyle to 'postgres_verbose'; 17 | 18 | \setenv LESS '-iMFXSx4R' 19 | -- Take your pick: emacs, nano, vim, or install another 20 | \setenv EDITOR 'vim' 21 | 22 | \set QUIET OFF 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:9 2 | 3 | RUN apt-get update 4 | # General dependencies 5 | RUN apt-get install -y emacs nano vim wget sudo pgloader 6 | 7 | # Give postgres user sudo privileges 8 | RUN usermod -a -G sudo postgres; \ 9 | echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers 10 | 11 | USER postgres 12 | 13 | WORKDIR /var/lib/postgresql 14 | 15 | VOLUME [ "/var/lib/postgresql" ] 16 | 17 | # PostgreSQL's port 18 | EXPOSE 5432 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker for TAOP 2 | A basic postgres Docker setup for going through [The Art of PostgreSQL](https://tapoueh.org/) 3 | by Dimitri Fontaine. It uses the official PostgreSQL 9 (what the book uses) 4 | Docker image and comes with `pgloader`. Data is stored in `pgdata` as a mounted 5 | volume mapped to `/var/lib/postgresql/data` in the container for persistence. 6 | 7 | A `.psqlrc` file is included, along with three text editors: emacs, nano and 8 | vim. You can choose your favorite and set it in the `.psqlrc` file (the default 9 | is `nano` for the broadest accessibility). 10 | 11 | # Using 12 | First, build the image and bring the container up. 13 | 14 | ```shell 15 | docker-compose up --build 16 | ``` 17 | 18 | Next, connect using your postgresql client of choice. 19 | 20 | ## `psql` 21 | ```shell 22 | $ docker exec -it artofpostgres bash 23 | > psql 24 | ``` 25 | 26 | ## GUI 27 | Point your graphical client to `postgresql://postgres@127.0.0.1:5440`. 28 | 29 | # Seeding data 30 | 31 | ## Chinook music database 32 | You can seed the Chinook database used in TAOP using the provided 33 | `fetch-chinook-data.sh` script. 34 | 35 | ```shell 36 | $ docker exec -it artofpostgres fetch-chinook-data.sh 37 | ``` 38 | 39 | ## F1DB data 40 | Since the PostgreSQL F1DB dump doesn't work without modification, we keep the 41 | import compatible with future versions by importing into MySQL first and then 42 | moving the data over to PostgreSQL using `pgloader`. 43 | 44 | ```bash 45 | $ docker exec -it artofpostgres ./fetch-f1db-data.sh 46 | 47 | # PostgreSQL database 48 | $ docker exec -it artofpostgres ./fetch-f1db-data.sh --recreate 49 | ``` 50 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | services: 3 | db: 4 | build: . 5 | container_name: artofpostgres 6 | environment: 7 | HOST_IP: host.docker.internal 8 | ports: 9 | - 5440:5432 10 | restart: always 11 | volumes: 12 | - .:/var/lib/postgresql 13 | -------------------------------------------------------------------------------- /fetch-chinook-data.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Pull the Chinook music SQLite database and load it into PostgreSQL. 3 | # From The Art of Postgres: Chapter 5, A Small Application 4 | 5 | CHINOOK_POSTGRESQL_DB_NAME=chinook 6 | CHINOOK_SQLITE_DATASOURCE=https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite_AutoIncrementPKs.sqlite 7 | 8 | until pg_isready 2>/dev/null; do 9 | echo "Waiting for postgres to start" 10 | sleep 1 11 | done 12 | 13 | if psql -lqt | cut -d \| -f 1 | grep -qw $CHINOOK_POSTGRESQL_DB_NAME; then 14 | if [[ $1 == "--recreate" ]]; then 15 | echo "--recreate flag was given, dropping database $CHINOOK_POSTGRESQL_DB_NAME" 16 | dropdb $CHINOOK_POSTGRESQL_DB_NAME 17 | else 18 | echo "Chinook PostgreSQL database already exists, skipping" 19 | echo "Include the --recreate flag if you want to drop and reseed the database" 20 | exit 1 21 | fi 22 | fi 23 | 24 | # echo "Creating PostgreSQL database" 25 | createdb $CHINOOK_POSTGRESQL_DB_NAME 26 | 27 | # echo "Fetching Chinook data and loading into local database" 28 | pgloader $CHINOOK_SQLITE_DATASOURCE pgsql://postgres@127.0.0.1:5432/$CHINOOK_POSTGRESQL_DB_NAME 29 | -------------------------------------------------------------------------------- /fetch-f1db-data.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Pull the f1db racing database and load it into PostgreSQL. 4 | # From The Art of Postgres: Chapter X, YYYYYYYYYY 5 | 6 | set -e 7 | 8 | NC='\033[0m' # No color (reset) 9 | RED='\033[0;31m' 10 | GREEN='\033[0;32m' 11 | YELLOW='\033[0;33m' 12 | 13 | F1DB_DB_NAME=f1db 14 | F1DB_SQLITE_DATASOURCE=http://ergast.com/downloads/f1db.sql.gz 15 | 16 | echo -e "${GREEN}Fetching latest version of f1db...${NC}" 17 | wget $F1DB_SQLITE_DATASOURCE -Nq 18 | gunzip -kf f1db.sql.gz 19 | 20 | echo -e "${GREEN}Installing and starting MariaDB...${NC}" 21 | sudo apt-get update > /dev/null 22 | sudo apt-get install -y mariadb-server mariadb-client > /dev/null 23 | sudo /etc/init.d/mysql start > /dev/null 24 | 25 | until pg_isready > /dev/null && pgrep mysql | wc -l > /dev/null; do 26 | echo -e "${YELLOW}Waiting for PostgreSQL and MySQL to start${NC}" 27 | sleep 1 28 | done 29 | 30 | echo -e "${GREEN}Creating intermediary MariaDB database and importing f1db data...${NC}" 31 | sudo mysql -u root -e "DROP DATABASE IF EXISTS $F1DB_DB_NAME;" 32 | sudo mysql -u root -e "CREATE DATABASE $F1DB_DB_NAME;" 33 | sudo mysql -u root -e "USE $F1DB_DB_NAME; SOURCE f1db.sql;" 34 | 35 | sudo mysql -e "CREATE USER IF NOT EXISTS 'postgres'@'localhost';" 36 | sudo mysql -e "CREATE USER IF NOT EXISTS 'postgres'@'$HOST_IP';" 37 | sudo mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'postgres'@'localhost';" 38 | sudo mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'postgres'@'$HOST_IP';" 39 | 40 | if psql -lqt | cut -d \| -f 1 | grep -qw $F1DB_DB_NAME; then 41 | if [[ $1 == "--recreate" ]]; then 42 | echo -e "${YELLOW}--recreate flag was given, dropping database $F1DB_DB_NAME${NC}" 43 | dropdb $F1DB_DB_NAME 44 | else 45 | echo -e "${RED}$F1DB_DB_NAME PostgreSQL database already exists, skipping${NC}" 46 | echo -e "${RED}Include the --recreate flag if you want to drop and reseed the database${NC}" 47 | exit 1 48 | fi 49 | fi 50 | 51 | echo -e "${GREEN}Creating PostgreSQL database...${NC}" 52 | createdb $F1DB_DB_NAME 53 | 54 | echo -e "${GREEN}Migrating f1db data from MySQL to PostgreSQL${NC}" 55 | pgloader \ 56 | mysql://postgres@localhost/$F1DB_DB_NAME \ 57 | pgsql://postgres@localhost/$F1DB_DB_NAME \ 58 | > /dev/null 59 | 60 | echo -e "${GREEN}Cleaning up...${NC}" 61 | sudo mysql -u root -e "DROP DATABASE IF EXISTS $F1DB_DB_NAME;" 62 | sudo /etc/init.d/mysql stop > /dev/null 63 | yes | sudo apt-get autoremove --purge mariadb-server mariadb-client > /dev/null 64 | rm f1db.sql 65 | 66 | echo -e "${GREEN}Done! 🎉${NC}" 67 | --------------------------------------------------------------------------------