Docker+Ubuntu+PostgreSQL セットアップ

公式 Ubuntuイメージに PostgreSQLなどをつめこんでみます

## 参考ページ
docker docs 公式サイト
https://matsuand.github.io/docs.docker.jp.onthefly/


## インストールバージョン
Docker Desktop 4.6.1
Ubuntu 22.04 LTS 
PostgreSQL 15
.NET6
.NET7


## Docker Desktop のセットアップ
Mac / Windows 共通
https://www.docker.com/products/docker-desktop/

Windowsのみ WSL2 for x64
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi


## 初回動作確認
コマンドラインから動作テスト
```shell:/bin/bash
# 公式イメージを取得
docker pull hello-world

# コンテナを作成
docker run -it --name hello-world hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
(中略)
```

## コンテナ操作
```shell:/bin/bash
# コンテナ一覧
docker ps -a

# コンテナ開始
docker start コンテナID or コンテナ名

# コンテナ停止
docker stop コンテナID or コンテナ名
```

## イメージ操作
```shell:/bin/bash
# イメージ一覧
docker images

# イメージ削除
docker rm イメージ名[:タグ]
```

## イメージのカスタマイズ
公式で提供されるイメージをベースとして、追加アプリや設定を記述
以下、/Users/ユーザ名/Docker/Ubuntu 配下での作成を想定

```Dockerfile:Dockerfile
#---------------------------------
# For Docker
#---------------------------------
FROM ubuntu:22.04


#---------------------------------
# For Ubuntu
#---------------------------------
#シェル指定
SHELL ["/usr/bin/bash", "-l", "-c"]

#初回のアップデートを強制
RUN apt update && apt upgrade -y

#最低限のメンテナンスツール
#2回目以降のapt installでも毎回updateをして、dockerの差分buildによるキャッシュの悪さを回避する
RUN apt-get update && apt-get install -y ca-certificates curl dnsutils gnupg gnupg2 htop iputils-ping lsb-release net-tools sqlite3 vim wget lftp



#---------------------------------
# For PostgreSQL
#---------------------------------
ENV TZ=Asia/Tokyo
ENV LANG=ja_JP.UTF-8
ENV LANGUAGE=ja_JP:ja
ENV LC_ALL=ja_JP.UTF-8


#無人インストール化
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y locales-all
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null
RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
RUN apt-get update && apt-get install -y postgresql-15

#初期設定
USER postgres
RUN /etc/init.d/postgresql start && \
        psql -c "alter user postgres with encrypted password 'postgres'" && \
        psql -c "create user docker with password 'docker' superuser;" && \
        psql -c "create database docker owner docker;" && \
        psql -d docker -c "create schema authorization docker;" && \
        psql -c "create role readonly with login password 'readonly';" && \
        psql -c "grant pg_read_all_data to readonly;"
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/15/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/15/main/postgresql.conf
USER root

#ポート解放
EXPOSE 5432


#---------------------------------
# For .NET 6
# Ubuntu22.04から公式レポジトリ経由での取得が可能
#---------------------------------
# RUN apt-get update && apt-get install -y dotnet6


#---------------------------------
# For .NET 7
#---------------------------------
RUN wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN rm packages-microsoft-prod.deb
#RUN apt-get update && apt-get install -y apt-transport-https
RUN apt-get update && apt-get install -y dotnet-sdk-7.0 aspnetcore-runtime-7.0


#---------------------------------
# For OpenJDK
#---------------------------------
ENV TZ=Asia/Tokyo

#無人インストール化
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install -y openjdk-17-jdk

#環境変数
#/etc/environmentに書き込んでもログイン時にsourceしてないため、Dockerfileで変数セットする
#RUN echo "JAVA_HOME=\"/usr/lib/jvm/java-17-openjdk-amd64\"" >> /etc/environment
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64


#---------------------------------
# For TomCat
#---------------------------------
RUN apt update && apt install -y tomcat9 tomcat9-admin

ENV CATALINA_HOME=/usr/share/tomcat9
ENV CATALINA_BASE=/var/lib/tomcat9
COPY ./mnt/tomcat9/var/lib/tomcat9/conf/web.xml /var/lib/tomcat9/conf
COPY ./mnt/tomcat9/var/lib/tomcat9/webapps/ROOT/index.txt /var/lib/tomcat9/webapps/ROOT

#ポート解放
EXPOSE 8080


#---------------------------------
# For Nginx
#---------------------------------
RUN apt update && apt install -y ubuntu-keyring
RUN curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list
RUN apt update && apt install -y nginx fcgiwrap spawn-fcgi
COPY ./mnt/nginx/etc/nginx/nginx.conf /etc/nginx
COPY ./mnt/nginx/usr/share/nginx/html/* /usr/share/nginx/html
RUN chmod 755 /usr/share/nginx/html/index.sh
COPY ./mnt/fcgiwrap/etc/init.d/fcgiwrap /etc/init.d

#ポート解放
EXPOSE 8000


#---------------------------------
# For Node.js
#---------------------------------
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt update && apt install -y nodejs

#ポート解放
EXPOSE 8888


#---------------------------------
# For MongoDB
#---------------------------------
RUN wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
RUN echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
RUN apt update && apt install -y mongodb-org
EXPOSE 27017


#---------------------------------
# For Docker
#---------------------------------
#コンテナ起動時に各サービス・プロセスを起動
COPY ./startup.sh /startup.sh
RUN chmod 744 /startup.sh
STOPSIGNAL SIGINT
ENTRYPOINT /startup.sh
```

起動・終了スクリプトを ```startup.sh``` として作成
```shell:startup.sh
#!/bin/sh

#終了処理
handle(){
  /etc/init.d/fcgiwrap stop
  /etc/init.d/ngix stop
  /etc/init.d/postgresql stop
  exit 0
}
trap handle TERM INT

#起動処理
/usr/libexec/tomcat9/tomcat-start.sh &
/usr/bin/node /mnt/bind/nodejs/webserver.js &
/etc/init.d/fcgiwrap start
/etc/init.d/nginx start
/etc/init.d/postgresql start
/bin/bash
```


## イメージ構築
```shell:/bin/bash
docker build -t イメージ名[:タグ] .
```

## コンテナ作成
```shell:/bin/bash
docker run -it -d
  -p ホストポート1:コンテナポート1
  -p ホストポート2:コンテナポート2
  -p ホストポート3:コンテナポート3
  --mount type=bind,source=/Users/ユーザ名/Docker/Ubuntu/mnt,target=/mnt
  --name コンテナ名
  イメージ名:タグ
```

## 動作確認
Docker 上の Ubuntu へ接続し、さらに PostgreSQL へ接続してバージョン情報などを確認
```shell:/bin/bash
# コンテナ一覧
docker ps -a

# コンテナ情報
docker inspect コンテナ名

# コンテナ情報 (マウント情報)
docker inspect --format='{{.Mounts}}' コンテナ名

# コンテナ情報 (IP情報)
docker inspect --format='{{.NetworkSettings.IPAddress}}' コンテナ名

# コンテナ情報 (ポートフォーワード情報)
docker inspect --format='{{.NetworkSettings.Ports}}' コンテナ名 

# コンテナログ
docker logs コンテナ名

# Ubuntu 接続
docker exec -it コンテナ名 bash

# PostgreSQL 接続
psql -h 127.0.0.1 -U docker
Password for user docker: docker
```

```sql:psql
-- ここから PostgreSQL コマンドラインインターフェース
-- バージョン情報
select version();
version                                                              
------------------------------------------------------------------
PostgreSQL 14.2 (Ubuntu 14.2-1.pgdg20.04+1) on x86_64-pc-linux-gnu
(1 row)

-- 現在のデータベース
select current_database();
current_database 
------------------
docker
(1 row)

-- 現在のスキーマ
select current_schema;
current_schema 
----------------
docker
(1 row)

-- 終了
\q
```

```shell:/bin/bash
-- ここから /bin/bash
-- 終了
exit
```