개요
Postgres 데이터베이스를 Docker 컨테이너로 구축하는 과정을 기록합니다.
SSL 적용 과정의 오류에 대한 해결 과정도 포함하고 있습니다.
컨테이너 폴더 및 인증서 생성
인증서 폴더(ca) 와 데이터 폴더(pgdata) 를 생성한 다음 인증서를 생성합니다.
폴더 구조는 다음과 같습니다.
폴더를 생성하는 스크립트 입니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker$ mkdir postgres
kkomzi@KKOMZI_HPN54L:/volume1/docker$ cd postgres/
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ mkdir ca
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ mkdir pgdata
인증서를 생성하는 스크립트 입니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ openssl req -new -text -passout pass:abcd -subj /CN=localhost -out ./ca/server.req -keyout ./ca/privkey.pem
Generating a RSA private key
........+++++
.....................+++++
writing new private key to './ca/privkey.pem'
-----
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ openssl rsa -in ./ca/privkey.pem -passin pass:abcd -out ./ca/server.key
writing RSA key
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ openssl req -x509 -in ./ca/server.req -text -key ./ca/server.key -out ./ca/server.crt
docker-compose.yaml 파일 작성
PGDATA 환경 변수에 데이터 폴더의 경로를 지정하고 호스트 폴더와 마운트 시켜 줍니다.
인증서 경로와 인증서를 적용하기 위한 command 도 포함되어 있습니다.
services:
postgres:
image: postgres:latest
container_name: postgres
restart: always
command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_DB: kkomzi
POSTGRES_PASSWORD: {{비밀번호}}
POSTGRES_USER: kkomzi
volumes:
- ./ca/server.crt:/var/lib/postgresql/server.crt
- ./ca/server.key:/var/lib/postgresql/server.key
- ./pgdata:/var/lib/postgresql/data/pgdata
ports:
- 5432:5432
컨테이너 실행
컨테이너를 실행합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker-compose up -d
Creating network "postgres_default" with the default driver
Pulling postgres (postgres:latest)...
latest: Pulling from library/postgres
2d429b9e73a6: Already exists
3234e936b543: Pull complete
b5b68d2b7dfa: Pull complete
2bc4b686b410: Pull complete
0e741c16b01d: Pull complete
febd2e801cbc: Pull complete
abad6e2f102b: Pull complete
fc0ed0630c16: Pull complete
15ea73ccc174: Pull complete
bc241f8dfdda: Pull complete
e6b9724cd240: Pull complete
87f78d636266: Pull complete
4bd7a2dad750: Pull complete
4c07baf06858: Pull complete
Digest: sha256:994cc3113ce004ae73df11f0dbc5088cbe6bb0da1691dd7e6f55474202a4f211
Status: Downloaded newer image for postgres:latest
오류 해결 과정
컨테이너 생성 후 데이터베이스에 연결해서 테스트 하려고 했더니 접속이 되지 않아 컨테이너 로그를 확인해 봅니다.
오류 – 소유자
로그를 확인해 보면 server.key 파일 관련해서 오류가 발생한 것을 확인할 수 있습니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker logs postgres -f
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/data/pgdata ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Success. You can now start the database server using:
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
pg_ctl -D /var/lib/postgresql/data/pgdata -l logfile start
waiting for server to start....2024-11-27 09:39:59.800 UTC [47] FATAL: private key file "/var/lib/postgresql/server.key" must be owned by the database user or root
2024-11-27 09:39:59.800 UTC [47] LOG: database system is shut down
stopped waiting
pg_ctl: could not start server
Examine the log output.
PostgreSQL Database directory appears to contain a database; Skipping initialization
2024-11-27 09:40:03.275 UTC [1] FATAL: private key file "/var/lib/postgresql/server.key" must be owned by the database user or root
2024-11-27 09:40:03.275 UTC [1] LOG: database system is shut down
PostgreSQL Database directory appears to contain a database; Skipping initialization
2024-11-27 09:40:06.567 UTC [1] FATAL: private key file "/var/lib/postgresql/server.key" must be owned by the database user or root
2024-11-27 09:40:06.568 UTC [1] LOG: database system is shut down
PostgreSQL Database directory appears to contain a database; Skipping initialization
소유자 id 확인
위 스크립트의 11 번째 줄을 보면 pgdata 폴더의 퍼미션을 수정하는 로그를 확인할 수 있습니다.
컨테이너가 생성되는 과정에서 데이터 폴더의 소유자가
컨테이너의 postgres 계정의 id 인 999 로 수정되어 있습니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ ls -al
total 4
drwxrwxrwx+ 1 kkomzi users 54 Nov 27 14:35 .
drwxrwxrwx+ 1 root root 564 Nov 27 13:19 ..
drwxrwxrwx+ 1 kkomzi users 82 Nov 27 13:37 ca
-rwxrwxrwx+ 1 kkomzi users 892 Nov 27 17:48 docker-compose.yaml
drwx------ 1 999 users 454 Nov 27 18:46 pgdata
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$
소유자 변경
sudo 로 전환해서 파일 소유자를 다음과 같이 999 로 수정합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ sudo -i
root@KKOMZI_HPN54L:~# chown 999 /volume1/docker/postgres/ca/server.key
root@KKOMZI_HPN54L:~# exit
logout
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$
오류 – 퍼미션
다시 로그를 확인해 보면 퍼미션도 수정하라고 합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker logs postgres -f
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
~~~~~~ 생략
2024-11-27 09:50:28.729 UTC [1] FATAL: private key file "/var/lib/postgresql/server.key" has group or world access
2024-11-27 09:50:28.729 UTC [1] DETAIL: File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.
2024-11-27 09:50:28.729 UTC [1] LOG: database system is shut down
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$
퍼미션 수정
sudo 로 전환해서 파일 퍼미션를 다음과 같이 600 으로 수정합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ sudo -i
root@KKOMZI_HPN54L:~# chmod 600 /volume1/docker/postgres/ca/server.key
root@KKOMZI_HPN54L:~# exit
logout
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$
다시 로그를 확인해 보면 에러 없이 정상적으로 실행이 된 것을 확인할 수 있습니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker logs postgres -f
~~~생략
2024-11-27 09:54:39.042 UTC [1] LOG: starting PostgreSQL 17.2 (Debian 17.2-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-11-27 09:54:39.058 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2024-11-27 09:54:39.058 UTC [1] LOG: listening on IPv6 address "::", port 5432
2024-11-27 09:54:39.115 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-11-27 09:54:39.167 UTC [30] LOG: database system was shut down at 2024-11-27 09:39:58 UTC
2024-11-27 09:54:39.219 UTC [1] LOG: database system is ready to accept connections
오류 – 데이터베이스가 존재하지 않습니다.
하지만 직접 접속해 보면 다음과 같이 데이터베이스가 생성되지 않았다고 합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker exec -it postgres /bin/bash
root@37119dca925d:/# psql -U kkomzi
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "kkomzi" does not exist
데이터 폴더 하위 다시 생성
아직 어떤 이유로 발생하는 문제인지는 모르겠지만 일단 다음과 같은 방법으로 해결하였습니다.
컨테이너를 삭제한 다음 pgdata 폴더 하위의 모든 파일을 삭제하고 다시 컨테이너를 실행하면 제대로 동작하는 것을 확인할 수 있었습니다.
하위 폴더 및 파일 삭제는 WinSCP 로 접속된 상황이라 UI 에서 삭제하였습니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker-compose down
Stopping postgres ... done
Removing postgres ... done
Removing network postgres_default
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker-compose up -d
Creating network "postgres_default" with the default driver
Creating postgres ... done
접속 테스트
직접 접속해서 로그인 한 다음 테스트 합니다.
kkomzi@KKOMZI_HPN54L:/volume1/docker/postgres$ docker exec -it postgres /bin/bash
root@37e12de71f0f:/# psql -U kkomzi
psql (17.2 (Debian 17.2-1.pgdg120+1))
Type "help" for help.
kkomzi-# \du
List of roles
Role name | Attributes
-----------+------------------------------------------------------------
kkomzi | Superuser, Create role, Create DB, Replication, Bypass RLS
kkomzi-# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges
-----------+--------+----------+-----------------+------------+------------+--------+-----------+-------------------
kkomzi | kkomzi | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | kkomzi | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | kkomzi | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/kkomzi +
| | | | | | | | kkomzi=CTc/kkomzi
template1 | kkomzi | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/kkomzi +
| | | | | | | | kkomzi=CTc/kkomzi
(4 rows)
kkomzi-#
0 Comments