미리 로드된 데이터베이스를 사용하여 Docker 이미지 만들기
--
-- PostgreSQL database dump
--
-- Dumped from database version 11.5
-- Dumped by pg_dump version 11.3
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: my_db; Type: DATABASE; Schema: -; Owner: postgres
--
CREATE DATABASE my_db WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8';
ALTER DATABASE my_db OWNER TO postgres;
\connect my_db
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: clients; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.clients (
id integer NOT NULL,
name character varying(150) NOT NULL
);
ALTER TABLE public.clients OWNER TO postgres;
--
-- Name: clients_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--
CREATE SEQUENCE public.clients_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public.clients_id_seq OWNER TO postgres;
--
-- Name: clients_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
--
ALTER SEQUENCE public.clients_id_seq OWNED BY public.clients.id;
--
-- Name: clients id; Type: DEFAULT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.clients ALTER COLUMN id SET DEFAULT nextval('public.clients_id_seq'::regclass);
--
-- Data for Name: clients; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY public.clients (id, name) FROM stdin;
1 Client 1
2 Client 2
\.
--
-- Name: clients_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
--
SELECT pg_catalog.setval('public.clients_id_seq', 2, true);
--
-- Name: clients clients_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.clients
ADD CONSTRAINT clients_pkey PRIMARY KEY (id);
--
-- PostgreSQL database dump complete
--
그것은 Clients
표와 두 개의 기록이 있는 간단한 데이터베이스이다.Postgresql Docker 용기를 시작하고 이 저장 파일을 불러와서 팀과 공유하려면, 이 SQL 파일을/Docker 입구점 initdb에 추가할 수 있습니다.d/컨테이너 내의 폴더(예: explained into the Postgresql Image docs from DockerHub).
Initialization scripts If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files, run any executable *.sh scripts, and source any non-executable *.sh scripts found in that directory to do further initialization before starting the service.
다음 Dockerfile은postgres:11 alpine을 기본 이미지로 사용하고test dump를 복사합니다.ql 파일을 entrypoint 폴더로 복사합니다.
FROM postgres:11-alpine
COPY test_dump.sql /docker-entrypoint-initdb.d/
하면, 만약, 만약...$ docker image build . -t preloaded_db:latest
생성된 그림으로 용기를 시작합니다$ docker container run -d --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres --name test_preloaded_db preloaded_db:latest
우리는 우리의 데이터베이스에서 데이터베이스가 만들어진 것을 볼 수 있다.(비밀번호 postgres
)$ psql -h localhost -U postgres
postgres=# \c my_db
psql (11.3, server 11.5)
You are now connected to database “my_db” as user “postgres”.
my_db=# SELECT * FROM clients;
id | name
— — + — — — — —
1 | Client 1
2 | Client 2
(2 rows)
경탄했어현재 우리는 데이터베이스를 불러오는 docker 이미지가 있습니다.그런데 저희가 이 용기의 일지를 확인해 보면...$ docker container logs test_preloaded_db
CREATE DATABASE 및 CREATE TABLE 명령을 볼 수 있습니다./usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/test_dump.sql
SET
SET
SET
SET
SET
set_config
-----------------
(1 row)
SET
SET
SET
SET
CREATE DATABASE
ALTER DATABASE
...
이것은 용기를 만들 때마다 덤프를 처리한다는 것을 알려 줍니다.만약 우리가 이 용기를 없애고 새 용기를 만들면, 덤프는 다시 처리될 것이다.이것은 매우 좋지만, 만약 우리가 큰 데이터베이스와 큰 저장 파일을 가지고 있다면, 용기의 시작 과정은 매우 느릴 것이다. 왜냐하면 전체 저장을 처리하는 데 시간이 좀 걸릴 수 있기 때문이다.우리는 이미지에 데이터베이스를 미리 불러와서 복구할 수 있다.우리가 계속하기 전에, 우리가 만든 용기를 소각합시다
$ docker container rm -f test_preloaded_db
이미지에 데이터베이스 미리 로드
이미지에 데이터베이스를 미리 불러오려면 Dockerfile에서 원본 PostgreSQL 이미지와 같은
entrypoint
을 실행하여 구축 단계에서 저장을 실행할 수 있도록 알려야 합니다.Multi-Stage build을 사용하여 구축을 두 단계로 나누어 보겠습니다.첫 번째는 덤프 파일을 사용하여 entrypoint
을 실행하고, 두 번째는 데이터 폴더를 생성된 이미지에 복사합니다.# dump build stage
FROM postgres:11-alpine as dumper
COPY test_dump.sql /docker-entrypoint-initdb.d/
RUN ["sed", "-i", "s/exec \"$@\"/echo \"skipping...\"/", "/usr/local/bin/docker-entrypoint.sh"]
ENV POSTGRES_USER=postgres
ENV POSTGRES_PASSWORD=postgres
ENV PGDATA=/data
RUN ["/usr/local/bin/docker-entrypoint.sh", "postgres"]
# final build stage
FROM postgres:11-alpine
COPY --from=dumper /data $PGDATA
첫 번째 단계에서는 다음을 설명합니다.postgres: 11 alpine as dumper에서 절차에 사용할 기본 그림을 정의했습니다.이 예에서
postgres
은 11-alpine
이라는 표기를 가지고 있다.복제 테스트 덤프.ql/docker 입구점 initdb.d/
test_dump.sql
파일을 /docker-entrypoint-initdb.d/
폴더로 복사합니다.['sed','-i','s/exec'$@'/echo'skipping.../','/usr/local/bin/docker entrypoint.sh'] 를 실행하려면
sed
파일에 존재하는 exec "$@"
내용을 삭제해야 합니다. 그러면 PostgreSQL 백엔드 프로그램이 시작되지 않습니다(이 단계에서는 필요하지 않습니다).ENV POSTGRES_USER=POSTGRES;ENV POSTGRES_PASSWORD=POSTGRES;ENV PGDATA=/data Sets 환경 변수로
docker-entrypoint.sh
과 user
을 정의하고 PostgreSQL에 password
을 데이터 폴더로 사용한다고 알려주면 다음 단계에서 [/usr/local/bin/docker entrypoint.sh]를 실행하고'postgres']를 실행하면 입구점 자체를 실행합니다.이것은 덤프를 실행하고 데이터를
/data
폴더에 불러옵니다./data
명령을 실행하여 sed
컨텐츠를 삭제했기 때문에 PostgreSQL 데몬 2단계에는 다음 설명만 포함됩니다.
COPY-from=dumper/data$PGDATA 이것은
$@
폴더의 모든 파일을 /data
단계에서 현재 단계의 $PGDATA로 복사하여 용기를 시작할 때 데이터를 미리 불러옵니다. (새 용기를 만들 때마다 덤프를 실행할 필요가 없습니다.)$ docker image build . -t preloaded_db:new
출력에서 처리 중인 덤프 파일을 볼 수 있으며, 모든 작업이 끝나면 그림이 생성됩니다.우리는 이 새 그림으로 용기를 시작할 수 있다
$ docker container run -d --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres --name test_preloaded_db preloaded_db:latest
데이터베이스가 로드되었습니다.$ psql -h localhost -U postgres
psql (11.3, server 11.5)
Type “help” for help.
postgres=# \c my_db
psql (11.3, server 11.5)
You are now connected to database “my_db” as user “postgres”.
my_db=# SELECT * FROM clients;
id | name
— — + — — — — —
1 | Client 1
2 | Client 2
(2 rows)
그러나 로그를 검사하면 용기를 만들 때마다 덤프를 처리하지 않습니다$ docker container logs test_preloaded_db
2019–09–16 01:42:22.458 UTC [1] LOG: listening on IPv4 address “0.0.0.0”, port 5432
2019–09–16 01:42:22.458 UTC [1] LOG: listening on IPv6 address “::”, port 5432
2019–09–16 01:42:22.460 UTC [1] LOG: listening on Unix socket “/var/run/postgresql/.s.PGSQL.5432”
2019–09–16 01:42:22.470 UTC [18] LOG: database system was shut down at 2019–09–16 01:41:02 UTC
2019–09–16 01:42:22.473 UTC [1] LOG: database system is ready to accept connections
PostgreSQL 부팅만 진행 중임을 알 수 있습니다.dumper
이미지 단계에서 수행되기 때문에 덤프가 수행되지 않았습니다.프로세스를 단순화하기 위한 Makefile 만들기
데이터베이스 덤프를 만들고 이미지를 만드는 과정을 간소화하기 위해Makefile을 만드는 것을 좋아합니다.이 Makefile에는 데이터베이스 덤프 파일을 만들고 이미지를 만들고 날짜에 따라 표시하는 명령이 포함되어 있으며, 등록표에서 매일 덤프 파일을 다운로드할 수 있습니다.
default: all
.PHONY: default all fetch_dump
date := `date '+%Y-%m-%d'`
TARGET_IMAGE ?= my_app
all: check_vars fetch_dump generate_image push_to_registry clean finished
check_vars:
@test -n "$(DB_ENDPOINT)" || (echo "You need to set DB_ENDPOINT environment variable" >&2 && exit 1)
@test -n "$(DB_NAME)" || (echo "You need to set DB_NAME environment variable" >&2 && exit 1)
@test -n "$(DESTINATION_REPOSITORY)" || (echo "You need to set DESTINATION_REPOSITORY environment variable" >&2 && exit 1)
fetch_dump: DB_USER ?= postgres
fetch_dump:
@echo ""
@echo "====== Fetching remote dump ======"
@PGPASSWORD="$(DB_PASSWORD)" pg_dump -h $(DB_ENDPOINT) -d $(DB_NAME) -U $(DB_USER) > dump.sql
generate_image:
generate_image:
@docker build . -t $(TARGET_IMAGE):latest -t $(DESTINATION_REPOSITORY)/$(TARGET_IMAGE):latest -t $(DESTINATION_REPOSITORY)/$(TARGET_IMAGE):$(date)
push_to_registry:
@echo ""
@echo "====== Pushing image to repository ======"
@docker push $(DESTINATION_REPOSITORY)/$(TARGET_IMAGE)
clean:
@echo ""
@echo "====== Cleaning used files ======"
@rm -f dump.sql
finished:
@echo ""
@echo "Finished with success. Pushed image to $(DESTINATION_REPOSITORY)/$(TARGET_IMAGE)"
나는 다음 명령을 실행하여 새로운 저장된 이미지를 생성할 수 있다$ make DB_ENDPOINT=127.0.0.1 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=my_db TARGET_IMAGE=myapp-data DESTINATION_REPOSITORY=gcr.io/my_project
이 명령은 대개 일부 서버의 Cron 작업에 통합되어 매일 실행됩니다.이것만 있으면, 나는 나의 이미지 등록표에 매일 저장할 수 있다.또 다른 흥미로운 것은 사용자 데이터를 혼동하기 위해 SQL 스크립트를 추가하는 것이다.This article can be helpful if you want to achive this
고마워요 고마워요☕️
Reference
이 문제에 관하여(미리 로드된 데이터베이스를 사용하여 Docker 이미지 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/caduribeiro/creating-a-docker-image-with-a-preloaded-database-3dom텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)