Xây dựng môi trường phát triển với Docker compose
Tiếp nối bài viết trước Giới thiệu về Docker, bài viết này sẽ giới thiệu một công cụ để quản lý và chạy nhiều docker containers liên kết với nhau để xây dựng một môi trường phát triển ở local cho các developers, đó là công cụ docker compose.
1. Docker compose là gì
. Định nghĩa
“Compose is a tool for defining and running multi-container applications with Docker. With Compose, you define a multi-container application in a single file, then spin your application up in a single command which does everything that needs to be done to get it running.”
Bạn có thể tham khảo thêm thông tin chi tiết về docker compose ở đây
2. Xây dựng môi trường phát triển với docker compose
2.1 Mục tiêu : xây dựng một môi trường phát triển local gồm các thành phần ở dưới
-Reverse proxy : nginx
-Framework : play-framework/scala
-Database : Mysql 5.6
2.2 Phân tích : sử dụng docker compose để quản lý và liên kết 3 containers, mỗi container chạy 1 service như ở trên gồm có nginx, play-framework/scala và mysql server
2.3 Cài đặt docker compose : tham khảo ở đây
2.4 Thiết lập cấu hình và chạy docker compose cho project
Tạo một folder có cấu trúc như hình bên dưới, bạn có thể đặt tên theo project hoặc tùy ý, ở đây tạm đặt là docker-compose
Trong đó :
- docker-compose/ : thư mục gốc lưu trữ
- docker-compose/app_web : thư mục lưu trữ mã nguồn của ứng dụng play-framework/scala
- docker-compose/mysql : thư mục lưu trữ Dockerfile dùng để xây dựng và chạy mysql-server container
- Dockerfile (mysql container)
FROM mysql/mysql-server:5.6 ENV MYSQL_DATABASE=app_dev ENV MYSQL_USER=app_web ENV MYSQL_PASSWORD=pleasechangeme ENV MYSQL_ROOT_PASSWORD=pleasechangemetoo
- Dockerfile (mysql container)
- docker-compose/nginx : thư mục lưu trữ Dockerfile, file cấu hình nginx dùng để xây dựng và chạy nginx container
- Dockerfile (nginx container)
FROM centos:centos6 MAINTAINER longlx (long_lx@septeni-technology.jp) # Install epel repository RUN yum install -y http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm && yum update -y && yum clean all -y # Install nginx RUN yum install -y nginx # Remove the default nginx configuration file RUN rm -v /etc/nginx/nginx.conf # Copy a configuration file from the current directory ADD nginx.conf /etc/nginx/ ADD app.local.conf /etc/nginx/conf.d/ # Append "daemon off;" to the beginning of the configuration RUN echo "daemon off;" >> /etc/nginx/nginx.conf CMD service nginx start
- Dockerfile (nginx container)
- docker-compose/Dockerfile : Dockerfile dùng để xây dựng và chạy play-framework/scala container
- Dockerfile (play-framework/scala container)
FROM centos:centos6 MAINTAINER longlx (long_lx@septeni-technology.jp) # install java 8 RUN yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel && \ yum clean all # install activator RUN yum update -y && yum install -y unzip RUN curl -O http://downloads.typesafe.com/typesafe-activator/1.3.6/typesafe-activator-1.3.6.zip RUN unzip typesafe-activator-1.3.6.zip -d /opt && mv /opt/activator-* /opt/activator-1.3.6/ && \ rm typesafe-activator-1.3.6.zip && chmod a+x /opt/activator-1.3.6/activator ENV PATH $PATH:/opt/activator-1.3.6 RUN mkdir /app_web WORKDIR /app_web # copy source code to container's volume COPY app_web /app_web CMD ["activator", "run"]
- Dockerfile (play-framework/scala container)
- docker-compose/docker-compose.yml : file cấu hình mà docker compose sẽ sử dùng để đọc thông tin cấu hình khi chạy lệnh “docker-compose up”
- docker-compose.yml
nginx: build: ./nginx ports: - "8080:80" volumes_from: - web links: - web web: build: . ports: - "9000:9000" volumes: - /root links: - mysql tty: true mysql: build: ./mysql ports: - "3006:3006"
- docker-compose.yml
Đến đây việc chuẩn bị cấu hình cho docker compose đã hoàn tất. Tiếp theo chúng ta sẽ build các images từ Dockerfile và run các containers từ các images đó :
lx:~$cd docker-compose # build images lx:~/docker-compose$ docker-compose build # run and link containers lx:~/docker-compose$ docker-compose up
Hiển thị các containers đang chạy bằng lệnh :
lx:~/docker-compose$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------- dockercompose_mysql_1 /entrypoint.sh mysqld Up 0.0.0.0:3006->3006/tcp, 3306/tcp dockercompose_nginx_1 /bin/sh -c service nginx start Up 0.0.0.0:8080->80/tcp dockercompose_web_1 activator run
Hiển thị logs của web containter bằng lệnh :
lx:~/docker-compose$ docker logs -f dockercompose_web_1 --- (Running the application, auto-reloading is enabled) --- [info] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application [info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 (Server started, use Ctrl+D to stop and go back to the console...) [info] Compiling 130 Scala sources and 2 Java sources to /app_web/target/scala-2.11/classes... [info] 'compiler-interface' not yet compiled for Scala 2.11.6. Compiling... [info] Compilation completed in 9.253 s
Truy cập từ trình duyệt http://app.local:8080/ :
2.5 Tổng kết : như vậy bạn đã có một môi trường phát triển hoàn chỉnh gồm các stacks : nginx/play-framework/mysql trên máy của mình chỉ với một vài thao tác sử dụng docker, docker compose. Việc chia sẻ với các developers khác cũng trở nên dễ dàng hơn, bạn chỉ cần đưa lên một source repository hoặc đẩy các images lên Docker Hub và các thành viên khác có thể sử dụng và đóng góp.
Hiện tại trong tài liệu chính thức của docker compose không khuyến nghị sử dụng cho production, chỉ nên sử dụng ở môi trường development, staging, continous integration. Hy vọng trong tương lai gần chúng ta có thể sử dụng docker compose cho tất cả các môi trường giúp cho việc phát triển và phân phối các ứng dụng trở nên dễ dàng và trơn tru hơn.
Một vấn đề nữa là khi mount một thư mục trên máy linux đã được mã hóa ổ đĩa, với một thư mục trên play-framework/scala container thì lúc biên dịch sbt sẽ báo lỗi :
"play.sbt.PlayExceptions$CompilationException: Compilation error[File name too long]"
Nguyên nhân có thể do giới hạn class file name của sbt và giới hạn của bản thân docker container. Khi có giải pháp cho vấn đề này người viết bài sẽ cập nhật.
Thank you for reading, all comments are welcome !