Conteúdo

PostgreSQL com Docker: instalação, conexão, backup e atualização

Mudança importante no PostgreSQL 18: a partir de postgres:18, o diretório de dados da imagem oficial passou a ser /var/lib/postgresql/18/docker, e o Volume deve ser montado em /var/lib/postgresql. A maioria dos tutoriais disponíveis na internet indica /var/lib/postgresql/data, que era o caminho usado até a versão 17. Na versão 18, esse caminho faz o contêiner falhar ao iniciar. Veja o teste abaixo.

Inicie com um comando

$ docker run -d --name pg -e POSTGRES_PASSWORD=secret -p 127.0.0.1:5432:5432 -v pgdata:/var/lib/postgresql --restart unless-stopped postgres:18
1b34d05a195f347c86e431441162b760167a5c04016a528e10342d0199be016d

$ docker logs pg 2>&1 | tail -n 3
2026-10-13 00:53:32.071 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-10-13 00:53:32.075 UTC [72] LOG:  database system was shut down at 2026-10-13 00:53:31 UTC
2026-10-13 00:53:32.080 UTC [1] LOG:  database system is ready to accept connections

$ docker exec pg psql -U postgres -c "SHOW data_directory;"
        data_directory
-------------------------------
 /var/lib/postgresql/18/docker
(1 row)
ParâmetroDescrição
POSTGRES_PASSWORDSenha do superusuário (obrigatória)
-p 127.0.0.1:5432:5432Disponibiliza a porta apenas localmente
-v pgdata:/var/lib/postgresqlOs dados ficam no Volume pgdata. Na versão 18, monte este caminho

SHOW data_directory confirma que o diretório de dados efetivo é /var/lib/postgresql/18/docker, dentro de /var/lib/postgresql, que montamos. O nome do diretório inclui o número da versão principal, então os dados das versões nova e antiga podem coexistir no mesmo Volume durante uma futura atualização.

Outras variáveis de ambiente comuns:

Variável de ambienteDescriçãoValor padrão
POSTGRES_USERNome do superusuáriopostgres
POSTGRES_DBBanco de dados padrãoIgual a POSTGRES_USER
PGDATADiretório de dados/var/lib/postgresql/18/docker (versão 18)
TZFuso horárioUTC

Assim como no MySQL, essas variáveis só têm efeito quando o diretório de dados está vazio. Alterar POSTGRES_PASSWORD depois não muda a senha existente. Para isso, use ALTER USER ... PASSWORD '...'.

Teste: montar o caminho antigo na versão 18 falha

Se você seguir tutoriais antigos e montar o Volume em /var/lib/postgresql/data:

$ docker run -d --name pgold -e POSTGRES_PASSWORD=secret -v pgold:/var/lib/postgresql/data postgres:18
b480eb9c72b29fa99f1ed8df17972e2bfc2d6da4b86c058a36cf21fd63579bfa

$ docker ps -a --filter name=pgold --format "{{.Status}}"
Exited (1) 5 seconds ago

$ docker logs pgold 2>&1 | head -n 12
Error: in 18+, these Docker images are configured to store database data in a
       format which is compatible with "pg_ctlcluster" (specifically, using
       major-version-specific directory names).  This better reflects how
       PostgreSQL itself works, and how upgrades are to be performed.

       See also https://github.com/docker-library/postgres/pull/1259

       Counter to that, there appears to be PostgreSQL data in:
         /var/lib/postgresql/data (unused mount/volume)

       This is usually the result of upgrading the Docker image without
       upgrading the underlying database using "pg_upgrade" (which requires both

O contêiner termina com Exited (1) em poucos segundos. A mensagem de erro explica que a versão 18 usa diretórios nomeados conforme a versão principal e encontrou uma “montagem não utilizada” em /var/lib/postgresql/data. Essa verificação evita que você pense que os dados foram salvos quando, na verdade, foram gravados dentro do contêiner e desaparecerão quando ele for removido. Basta mudar o caminho de montagem para /var/lib/postgresql.

Gerencie com Compose

Em projetos reais, recomendamos usar Compose. Crie a pasta pg-demo:

pg-demo/
├── compose.yaml
├── .env
└── initdb/
    └── 01-init.sql

.env:

DB_PASSWORD=change-this-password

initdb/01-init.sql (executado na primeira inicialização para criar extensões, tabelas e dados de exemplo; o pg_sleep(8) final simula intencionalmente uma inicialização demorada, como a importação de muitos dados, para observar a verificação de integridade):

CREATE EXTENSION IF NOT EXISTS pg_trgm;

CREATE TABLE products (
  id serial PRIMARY KEY,
  name text NOT NULL,
  price integer NOT NULL
);

INSERT INTO products (name, price) VALUES ('珍珠奶茶', 65), ('鳳梨酥', 45), ('牛肉麵', 180);

-- Simula uma inicialização demorada (por exemplo, a importação de muitos dados)
SELECT pg_sleep(8);

compose.yaml:

services:
  db:
    image: postgres:18
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
      TZ: Asia/Taipei
    command: ["postgres", "-c", "max_connections=200", "-c", "shared_buffers=256MB"]
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql
      - ./initdb:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U app -d app"]
      interval: 2s
      timeout: 3s
      retries: 30
    shm_size: 256mb
    restart: unless-stopped

volumes:
  pgdata:
ConfiguraçãoDescrição
POSTGRES_USER: appRenomeia o superusuário para app; não haverá mais um usuário chamado postgres
command: ["postgres", "-c", ...]Passa configurações do PostgreSQL com -c, sem precisar preparar um arquivo de configuração separado
pg_isready -h 127.0.0.1Ferramenta de verificação integrada do PostgreSQL. É essencial adicionar -h 127.0.0.1; veja o teste abaixo para saber o motivo
shm_size: 256mbA memória compartilhada padrão do Docker em /dev/shm tem apenas 64 MB; consultas mais complexas podem gerar o erro could not resize shared memory segment
$ docker compose up -d --wait
[+] up 3/3
 ✔ Network pg-demo_default Created                                                                                                                0.0s
 ✔ Volume pg-demo_pgdata   Created                                                                                                                0.0s
 ✔ Container pg-demo-db-1  Healthy                                                                                                               11.3s

$ docker compose exec db psql -U app -h 127.0.0.1 -c "SELECT * FROM products;"
 id |   name   | price
----+----------+-------
  1 | 珍珠奶茶 |    65
  2 | 鳳梨酥   |    45
  3 | 牛肉麵   |   180
(3 rows)


$ docker compose logs db 2>&1 | grep -E "running /docker-entrypoint-initdb.d|init process complete|listening on IPv4"
db-1  | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/01-init.sql
db-1  | PostgreSQL init process complete; ready for start up.
db-1  | 2026-10-13 08:52:58.663 CST [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432

$ docker compose exec db psql -U app -c "SHOW max_connections;" -c "SHOW shared_buffers;" -c "SELECT now();"
 max_connections
-----------------
 200
(1 row)

 shared_buffers
----------------
 256MB
(1 row)

              now
-------------------------------
 2026-10-13 08:53:01.293902+08
(1 row)


$ docker compose exec db df -h /dev/shm
Filesystem      Size  Used Avail Use% Mounted on
shm             256M  1.1M  255M   1% /dev/shm

$ docker compose exec db psql -U app -c "\dx"
                                             List of installed extensions
  Name   | Version | Default version |   Schema   |                            Description
---------+---------+-----------------+------------+-------------------------------------------------------------------
 pg_trgm | 1.6     | 1.6             | public     | text similarity measurement and index searching based on trigrams
 plpgsql | 1.0     | 1.0             | pg_catalog | PL/pgSQL procedural language
(2 rows)
  • Healthy levou 11,3 segundos, exatamente o tempo da inicialização mais o pg_sleep(8). Assim que ficou saudável, conectamos por TCP; os dados estavam todos lá e os caracteres chineses foram exibidos corretamente.
  • Os logs mostram que o script de inicialização foi executado e que o servidor começou a escutar em 0.0.0.0:5432 somente depois de concluir a inicialização.
  • max_connections é 200 e shared_buffers é 256MB; os parâmetros de command foram aplicados. now() mostra o fuso horário +08.
  • /dev/shm tem 256M; shm_size foi aplicado.
  • \dx lista as extensões instaladas; pg_trgm foi criada pelo script de inicialização.

Armadilha da verificação de integridade: sem -h, pg_isready informa healthy cedo demais

Uma forma comum de escrever isso na internet é pg_isready -U app -d app (sem -h). Testamos alterando para essa forma:

$ docker compose up -d --wait
[+] up 3/3
 ✔ Network pg-demo_default Created                                                                                                                0.0s
 ✔ Volume pg-demo_pgdata   Created                                                                                                                0.0s
 ✔ Container pg-demo-db-1  Healthy                                                                                                                3.2s

$ docker compose exec db psql -U app -h 127.0.0.1 -c "SELECT count(*) FROM products;"
psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

$ docker compose logs db 2>&1 | grep -E "pg_sleep|init process complete|listening on IPv4"

Após apenas 3,2 segundos, o status passou a Healthy, mas a conexão por TCP retornou Connection refused.

O motivo é o mesmo do MySQL: durante a inicialização, o script de inicialização abre primeiro um servidor temporário que aceita somente conexões por Unix socket para executar os scripts de initdb. Sem -h, pg_isready usa o socket e informa que é possível conectar antes de a inicialização terminar. Aplicações que dependem dele (depends_on com condition: service_healthy) iniciam nesse momento, e a conexão por TCP falha. Adicione -h 127.0.0.1 para forçar o uso de TCP e aguardar até que o servidor definitivo seja iniciado.

Conexão e psql

Usando o psql

O contêiner inclui o cliente psql. Para usá-lo de forma interativa, execute docker compose exec db psql -U app (em um contêiner separado, use docker exec -it pg psql -U postgres), entre no prompt app=# e digite SQL ou os comandos abaixo. Você também pode executar um comando diretamente com -c:

$ docker compose exec db psql -U app -c "SELECT version();"
                                                      version
--------------------------------------------------------------------------------------------------------------------
 PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
(1 row)


$ docker compose exec db psql -U app -c "\l"
                                                 List of databases
   Name    | Owner | Encoding | Locale Provider |  Collate   |   Ctype    | Locale | ICU Rules | Access privileges
-----------+-------+----------+-----------------+------------+------------+--------+-----------+-------------------
 app       | app   | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 postgres  | app   | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           |
 template0 | app   | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/app           +
           |       |          |                 |            |            |        |           | app=CTc/app
 template1 | app   | UTF8     | libc            | en_US.utf8 | en_US.utf8 |        |           | =c/app           +
           |       |          |                 |            |            |        |           | app=CTc/app
(4 rows)


$ docker compose exec db psql -U app -c "\dt"
          List of tables
 Schema |   Name   | Type  | Owner
--------+----------+-------+-------
 public | products | table | app
(1 row)


$ docker compose exec db psql -U app -c "\d products"
                            Table "public.products"
 Column |  Type   | Collation | Nullable |               Default
--------+---------+-----------+----------+--------------------------------------
 id     | integer |           | not null | nextval('products_id_seq'::regclass)
 name   | text    |           | not null |
 price  | integer |           | not null |
Indexes:
    "products_pkey" PRIMARY KEY, btree (id)


$ docker compose exec db psql -U app -c "\du"
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 app       | Superuser, Create role, Create DB, Replication, Bypass RLS
ComandoFunção
\lLista os bancos de dados
\c nomeAlterna o banco de dados
\dtLista as tabelas
\d tabelaMostra a estrutura da tabela
\duLista os usuários (funções)
\dxLista as extensões instaladas
\qSai

O comando \du mostra que app é Superuser, e o Owner de todos os bancos de dados em \l também é app: depois que você define POSTGRES_USER, ele substitui o usuário padrão postgres.

Por que não é preciso digitar a senha dentro do contêiner

Nos exemplos acima, o psql não pediu senha. Confira o arquivo pg_hba.conf no diretório de dados (as regras de autenticação de conexão do PostgreSQL):

$ docker compose exec db grep -v "^#" /var/lib/postgresql/18/docker/pg_hba.conf | grep -v "^$"
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
host all all all scram-sha-256

$ docker run --rm --network pg-demo_default -e PGPASSWORD=wrong postgres:18 psql -h db -U app -c "SELECT 1;"
psql: error: connection to server at "db" (172.19.0.2), port 5432 failed: FATAL:  password authentication failed for user "app"

$ docker run --rm --network pg-demo_default -e PGPASSWORD=change-this-password postgres:18 psql -h db -U app -c "SELECT current_user, inet_server_addr();"
 current_user | inet_server_addr
--------------+------------------
 app          | 172.19.0.2
(1 row)
  • Configuração da imagem oficial: conexões dentro do contêiner (Unix socket, 127.0.0.1, ::1) usam trust e não verificam a senha.
  • Conexões de outras origens (a última linha, host all all all) usam autenticação por senha scram-sha-256.
  • Ao conectar a db a partir de outro contêiner na mesma rede Compose, uma senha incorreta resulta em password authentication failed; com a senha correta, a conexão é estabelecida.

Assim, quem consegue entrar no contêiner pode operar o banco de dados diretamente. Por isso, proteja as permissões do Docker (consulte Segurança do Docker). Ao conectar do host pela porta mapeada com -p, o IP de origem é o gateway da rede Docker, e também é preciso informar a senha.

Conectando do host e de outros contêineres

postgres://app:senha@127.0.0.1:5432/app   # Do host (ferramenta GUI, aplicativo)
postgres://app:senha@db:5432/app          # De outro serviço do mesmo projeto Compose

Erros comuns de conexão

$ docker compose exec db psql -c "SELECT 1;"
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "root" does not exist

$ docker compose exec db psql -U postgres -c "SELECT 1;"
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "postgres" does not exist

$ docker compose exec db psql -U app -d shop -c "SELECT 1;"
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  database "shop" does not exist

$ docker compose exec -e PGPASSWORD=wrong db psql -h 127.0.0.1 -U app -c "SELECT 1;"
 ?column?
----------
        1
(1 row)


$ docker compose exec db psql -U app -h 127.0.0.1 -p 5433 -c "SELECT 1;"
psql: error: connection to server at "127.0.0.1", port 5433 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?
ErroCausa
role "root" does not existVocê não incluiu -U no psql, então ele usa por padrão o nome do usuário atual do sistema (dentro do contêiner, root)
role "postgres" does not existVocê definiu POSTGRES_USER, então o usuário padrão postgres não existe
database "shop" does not existPOSTGRES_DB só cria o banco durante a inicialização; você precisa executar CREATE DATABASE para os demais bancos
Connection refusedA porta está incorreta, o banco ainda não terminou de iniciar ou você se conectou ao host errado
password authentication failedA senha está incorreta ou o Volume foi inicializado com outra senha

Observe o quarto comando: dentro do contêiner, a conexão a 127.0.0.1 funciona mesmo com uma senha incorreta. Essa é a regra trust mencionada acima.

Backup e restauração

$ docker compose exec -T db pg_dump -U app app > app.sql

$ ls -lh app.sql && grep -E "^CREATE (TABLE|EXTENSION)" app.sql
-rw-r--r--    1 root     root        2.3K Oct 13 00:53 app.sql
CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;
CREATE TABLE public.products (

$ docker compose exec -T db pg_dump -U app -Fc app > app.dump

$ ls -lh app.dump
-rw-r--r--    1 root     root        3.1K Oct 13 00:53 app.dump

$ docker compose exec db psql -U app -c "DROP TABLE products;"
DROP TABLE

$ docker compose exec -T db pg_restore -U app -d app --clean --if-exists < app.dump

$ docker compose exec db psql -U app -c "SELECT count(*) FROM products;"
 count
-------
     3
(1 row)


$ rm app.sql app.dump
ComandoDescrição
pg_dump app > app.sqlExporta em texto SQL puro, que você pode ler diretamente e importar com psql
pg_dump -Fc app > app.dumpFormato customizado, já compactado; restaure com pg_restore e escolha restaurar apenas algumas tabelas
pg_restore --clean --if-existsExclui os objetos existentes antes da restauração para evitar duplicatas
exec -TO exec do Compose aloca um TTY por padrão. Ao usar redirecionamento, adicione -T para desativá-lo

O backup inclui CREATE EXTENSION; ao restaurá-lo em um banco de dados novo, a extensão também será criada. Como este exemplo tem poucos dados, o formato customizado (3.1K) acaba sendo maior que o texto puro (2.3K). Com um volume maior de dados, o formato customizado fica bem menor.

Outros comandos comuns:

# Fazer backup de todos os bancos de dados e papéis (usuários e senhas)
docker compose exec -T db pg_dumpall -U app > all.sql

# Restaurar SQL em texto puro
docker compose exec -T db psql -U app -d app < app.sql

Você pode usar o cron com os comandos acima para fazer backups periódicos e copiar os arquivos para outra máquina ou para um armazenamento na nuvem.

Backup e restauração no Windows

O PowerShell não oferece suporte a <, e o > do Windows PowerShell 5.1 altera a codificação do arquivo. O backup binário de -Fc pode até ser corrompido diretamente. Em vez disso, use pg_dump -f para gerar o arquivo dentro do contêiner e depois copie-o com docker compose cp. Essa forma funciona em todos os sistemas:

# Backup
docker compose exec db pg_dump -U app -Fc -f /tmp/app.dump app
docker compose cp db:/tmp/app.dump app.dump

# Restauração
docker compose cp app.dump db:/tmp/restore.dump
docker compose exec db pg_restore -U app -d app --clean --if-exists /tmp/restore.dump

Esses comandos não usam $(pwd), < nem >, e funcionam diretamente no bash, PowerShell e CMD. Teste prático (criar uma tabela, fazer backup, excluí-la e restaurá-la):

$ docker compose exec db psql -U app -c 'CREATE TABLE t (id int); INSERT INTO t VALUES (1),(2);'
CREATE TABLE
INSERT 0 2

$ docker compose exec db pg_dump -U app -Fc -f /tmp/app.dump app

$ docker compose cp db:/tmp/app.dump app.dump
 pgwin-db-1 Copying pgwin-db-1:/tmp/app.dump to app.dump
 pgwin-db-1 Copied pgwin-db-1:/tmp/app.dump to app.dump

$ ls -l app.dump
-rw-rw-rw-    1 root     root          1251 Oct 13 05:30 app.dump

$ docker compose exec db psql -U app -c 'DROP TABLE t;'
DROP TABLE

$ docker compose cp app.dump db:/tmp/restore.dump
 pgwin-db-1 Copying app.dump to pgwin-db-1:/tmp/restore.dump
 pgwin-db-1 Copied app.dump to pgwin-db-1:/tmp/restore.dump

$ docker compose exec db pg_restore -U app -d app /tmp/restore.dump

$ docker compose exec db psql -U app -c 'SELECT count(*) FROM t;'
 count
-------
     2
(1 row)

Atualização de versão principal (por exemplo, 16 → 18)

Para uma atualização de versão secundária (por exemplo, 18.5 → 18.6), basta baixar a nova imagem e recriar o contêiner. Nas versões principais, é diferente: os formatos dos arquivos de dados não são compatíveis entre versões principais diferentes do PostgreSQL.

Primeiro, crie alguns dados usando a versão 16:

$ docker run -d --name pg16 -e POSTGRES_PASSWORD=secret -v pg16data:/var/lib/postgresql/data postgres:16
20691764a98828d24c958eaaa71e83c08ebff29b984350ff7f6782ba8d74b4ca

$ docker exec pg16 psql -U postgres -c "CREATE TABLE notes (id serial PRIMARY KEY, body text); INSERT INTO notes (body) VALUES ('written by 16');"
CREATE TABLE
INSERT 0 1

$ docker stop pg16
pg16

Trocar a imagem diretamente falha

Abra os dados da versão 16 com postgres:18 (aqui, PGDATA especifica o caminho antigo para simular a troca direta da tag de 16 para 18):

$ docker run --name pg18 -e POSTGRES_PASSWORD=secret -e PGDATA=/var/lib/postgresql/data -v pg16data:/var/lib/postgresql/data postgres:18 2>&1 | tail -n 3

2026-10-13 00:54:09.740 UTC [1] FATAL:  database files are incompatible with server
2026-10-13 00:54:09.740 UTC [1] DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 18.6 (Debian 18.6-1.pgdg13+2).

$ docker rm pg18
pg18

database files are incompatible with server: o diretório de dados foi inicializado pela versão 16, e a versão 18.6 não pode usá-lo.

Exportar e importar

O método mais simples e seguro é exportar todos os dados com o pg_dumpall da versão antiga e importá-los em um novo Volume da versão nova.

$ docker start pg16
pg16

$ docker exec pg16 pg_dumpall -U postgres > upgrade.sql && ls -lh upgrade.sql
-rw-r--r--    1 root     root        3.4K Oct 13 00:54 upgrade.sql

$ docker run -d --name pg18 -e POSTGRES_PASSWORD=secret -v pg18data:/var/lib/postgresql postgres:18
ec651837b76a0c9cc8b2468ec5a2ff4002334dcf015514ef94490a6c38cfe73d

$ docker exec -i pg18 psql -U postgres -q < upgrade.sql
ERROR:  role "postgres" already exists
 set_config
------------

(1 row)

 set_config
------------

(1 row)

 setval
--------
      1
(1 row)


$ docker exec pg18 psql -U postgres -c "SHOW server_version;" -c "SELECT * FROM notes;"
        server_version
-------------------------------
 18.6 (Debian 18.6-1.pgdg13+2)
(1 row)

 id |     body
----+---------------
  1 | written by 16
(1 row)


$ rm upgrade.sql
  • Você pode ignorar o ERROR: role "postgres" already exists durante a importação: o novo contêiner da versão 18 já criou o usuário postgres, e a saída do pg_dumpall tenta criá-lo novamente.
  • Por fim, confirme que a versão é 18.6 e que os dados gravados pela versão 16, como written by 16, estão presentes.
  • Observe que o Volume do novo contêiner está montado em /var/lib/postgresql (o novo caminho da versão 18).

Depois de confirmar que os dados e o aplicativo estão funcionando, exclua o contêiner e o Volume antigos. Se o volume de dados for muito grande e você não puder aceitar um longo período de inatividade, considere usar pg_upgrade ou replicação lógica (logical replication), mas as etapas são bem mais complexas. Faça um ensaio em um ambiente de testes primeiro.

Resumo

  • O Volume do PostgreSQL 18 é montado em /var/lib/postgresql.
  • A verificação de integridade usa pg_isready -h 127.0.0.1.
  • As conexões dentro do contêiner usam trust; as conexões externas precisam de senha.
  • Para atualizar a versão principal: exporte com o pg_dumpall da versão antiga e importe em um novo Volume da versão nova.

Exercícios

Exercício 1: Use o psql para criar uma tabela notes no banco de dados app e, em seguida, confirme com \dt.

Resposta
docker compose exec db psql -U app -c "CREATE TABLE notes (id serial PRIMARY KEY, body text);"
docker compose exec db psql -U app -c "\dt"

Exercício 2: Qual é a diferença entre fazer um backup no formato personalizado (-Fc) e em SQL de texto simples?

Resposta

O formato personalizado é compactado e precisa ser restaurado com pg_restore; você pode optar por restaurar apenas algumas tabelas. O formato de texto simples pode ser lido diretamente e importado com psql.

Perguntas frequentes

postgres:18 inicia e encerra logo em seguida?

Na versão 18, monte /var/lib/postgresql. Se montar o caminho antigo /var/lib/postgresql/data, o contêiner encerra ao detectar um diretório incompatível. Veja o teste neste capítulo.

Como atualizar uma versão menor (18.5 → 18.6)?

Basta baixar a nova imagem e recriar o contêiner: docker compose pull db && docker compose up -d db. Só é preciso exportar e importar ao atualizar uma versão principal.

pg_restore falha no Windows?

O PowerShell não oferece suporte a <, e o > da versão 5.1 corrompe backups binários. Gere o arquivo dentro do contêiner com pg_dump -f e copie-o com docker compose cp. Este capítulo inclui os comandos.

Atualizado 14 de outubro de 2026