[Docker] PostgreSQL 도커로 실행하기
Docker를 사용해서 최신버전의 PostgreSQL을 실행하여 데이터베이스 및 계정을 생성하고 데이터베이스 접근 권한과 계정에게 권한 설정하는 방법 등 아주 기본적인 설정에 대해 알아보려고 한다.
1. PostgreSQL 버전 선택
가장 먼저 해야 할 일은 사용할 PostgreSQL의 버전을 선택해야 한다.
현재 15 버전까지 나와 있는 것을 확인할 수 있었고
Docker Hub에서 지원하는 PostgreSQL의 버전을 확인할 수 있다.
만약 버전이 너무 많아서 선택이 어렵다면
PostgreSQL 버전별 차이점도 비교할 수 있으니 참고해서 선택하면 될 듯하다.
2. Docker로 PostgreSQL 실행
2-1. postgres 이미지 pull
사용할 PostgreSQL 버전을 선택했다면
버전에 맞게 postgres 이미지를 pull 받으면 된다.
가장 최신버전을 사용하기 위해 latest를 입력해서 pull 받아왔다.
docker pull postgres:latest
postgres 이미지를 제대로 pull 받았는지 docker images 명령어를 사용하여 확인할 수 있다.
아래 사진에서 TAG를 보면 latest를 받아온 것을 확인할 수 있다.
(현재 최신버전이 15.1이기 때문에 latest와 15.1의 두 IMAGE ID가 동일한 것을 확인할 수 있다.)
2-2. postgres 실행
이제 pull 받아온 postgres 이미지를 컨테이너로 실행해 보자.
docker run -p 5432:5432 --name test-postgres \
-e POSTGRES_PASSWORD=11223344 \
-e TZ=Asia/Seoul \
-v /home/testuser/pgdata:/var/lib/postgresql/data \
-d postgres:latest
포트는 5432(default)로 지정하고 이름과 데이터베이스 비밀번호를 입력하고
타임존은 Asiz/Seoul로 지정해 준다.
컨테이너끼리 하나의 저장 공간을 공유해서 데이터를 읽거나 써야 하기 때문에
데이터를 영속적으로 저장하는 공간이 필요하다. (만약 그럴 필요가 없다면 넘어가도 된다.)
Docker는 볼륨(volume)과 바인드 마운트 (bind mount) 옵션을 제공하는데
해당 예제에서는 docker 호스트 서버에 임의의 경로(/home/testuser/pgdata)로 지정했다.
docker ps 명령어를 통해 내가 설정한 대로 컨테이너가 제대로 실행되었는지 확인하면 된다.
3. PostgreSQL 설정 (DB생성, 계정생성, 권한설정)
Docker를 이용해서 PostgreSQL 실행까지는 완료했다.
이번에는 간단한 PostgreSQL 설정을 해보자.
3-1. 컨테이너 postgresql 접속
[CONTAINER ID]에 내가 실행한 컨테이너 아이디를 입력한다.
docker exec -it [CONTAINER ID] bash
-------------------------------------
docker exec -it af430351165e bash
컨테이너로 들어왔으면 이번엔 psql을 사용해서 [USER ID]에 postgres를 입력하여 postgresql로 접속한다.
psql -U [USER ID]
---------------------
psql -U postgres
위에서 컨테이너를 실행할 때 입력했던 POSTGRES_PASSWORD 값을 입력하면 된다.
접속에 성공하면 아래와 같이 입력창이 변경된 것을 알 수 있다.
3-2. 데이터베이스 생성
이어서 새로 데이터베이스를 생성을 해보자.
create database test_db;
입력창에서 \l (소문자 L) 명령어를 통해 확인해보면 데이터베이스 목록을 확인할 수 있다.
\l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-------------+----------+----------+------------+------------+------------+-----------------+------------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
test_db | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc |
3-3. 계정 생성 (user) 및 권한 설정
계정이름은 test_user로 비밀번호는 test1234로 생성해 보자.
create role test_user with login password 'test1234';
권한 설정의 경우는 필요에 따라 설정해주면 된다.
나의 경우는 데이터베이스 생성 권한과 superuser 권한 설정을 해줬다.
alter user test_user with createdb;
alter user test_user with superuser;
\du 명령어를 통해 유저와 권한 설정이 어떻게 되어 있는지 확인이 가능하다.
\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
test_user | Superuser, Create DB | {}
test_user에 위에서 생성한 test_db에 대한 접근권한도 같이 주도록 한다.
grant all privileges on database test_db to test_user;
4. 테이블 생성 및 조회
기본적인 설정은 끝났으니 이제 테스트용 테이블을 생성해 보자.
create table tbl_test
(
test_code VARCHAR(6) not null,
test_name VARCHAR(100) not null,
test_id VARCHAR(10) not null,
test_date TIMESTAMP default CURRENT_TIMESTAMP not null,
constraint pk_tbl_test primary key (test_code)
);
간단하게 데이터를 insert 하고 테이블을 조회해서 테이블을 확인해 보자.
insert into tbl_test values('0001', '첫번째 테스트', 'test', '2023-01-09 00:00:00');
select * from tbl_test;
test_code | test_name | test_id | test_date
-----------+---------------+---------+---------------------
0001 | 첫번째 테스트 | test | 2023-01-09 00:00:00
(1 row)
정상적으로 insert 된 데이터를 확인할 수 있다.
참고 - WSL docker
추가로 내가 겪었던 문제인데, 테스트를 윈도우에서 WSL을 이용해서 ubuntu로 접속해서 테스트하는데
docker 컨테이너 ip로 내부에서는 잘 접근이 되지만 외부에서는 접근이 불가능하다는 문제점이 있었다.
윈도우 방화벽도 열어주고, PostgreSQL 설정들도 변경해줬는데도 되지 않아
찾아보니 포트 포워딩을 해주면 외부에서도 접근이 가능하다고 한다.
그러기 위해서는 확장자 ps1 파일을 만들어 Power Shell로 실행해주면 된다.
아래 내용 중 $ports = @(5432); 이 괄호 안에 내가 사용하는 포트번호를 쉼표(,)로 구분해서 넣어주면 된다.
ex) $ports = @(5432, 8080, 8090);
ports_sql.ps1
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if ( $found ) {
$remoteport = $matches[0];
}
else {
Write-Output "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
$ports = @(5432);
Invoke-Expression "netsh interface portproxy reset";
for ( $i = 0; $i -lt $ports.length; $i++ ) {
$port = $ports[$i];
Invoke-Expression "netsh interface portproxy add v4tov4 listenport=$port connectport=$port connectaddress=$remoteport";
}
Invoke-Expression "netsh interface portproxy show v4tov4";
Power Shell(관리자 권한으로 실행)을 실행하여 해당 파일 위치로 이동한다.
이동한 후 해당 파일을 실행해주면 포트 포워딩 완료 되고
docker 컨테이너로 외부에서도 접근이 가능해진다.
.\ports_wsl.ps1
ipv4 수신 대기: ipv4에 연결:
주소 포트 주소 포트
--------------- ---------- --------------- ----------
* 5432 [ip 번호] 5432
위 내용의 단점은 윈도우를 시작할 때마다 파일을 실행해줘야 된다는 점인데
윈도우 스케줄러를 이용하면 해결되는 모양이다.
필요시 윈도우 스케줄러 등록하여 자동으로 실행되게끔 하면 될 듯싶다.