Grow up

生活とプログラミング

DockerでAnsibleを使ってcronを設定する

f:id:knkomko:20210718235123p:plain:w250

はじめに

エージェントレスな構成管理ツール Ansible を使ってみました。
今回 Docker を使って cron の設定を試しています。

github.com

フォルダ構成
C:\docker\ansible-cron\
│  docker-compose.yml
│  inventry.ini
│  playbook.yml
│
├─ansible\
│     Dockerfile
│
└─target\
    │  Dockerfile
    │
    └─home\
cron の設定内容

Ansible を使うため playbook.yml に cron の設定内容を記載しています。
1分間隔で /var/log/test.log に test の文字列を追記することにしました。

- hosts: target
  tasks:
  - name: "setup cron"
    cron: 
      name: "create log" 
      minute: "*" 
      hour: "*" 
      day: "*"
      job: "echo 'test' >> /var/log/test.log"
Docker コンテナの起動
# docker-compose.yml のディレクトリに移動
$cd C:\docker\ansible-cron\
# コンテナの起動
$docker compose up -d --build
inventory.ini の変更

Ansibleからcronの設定を行うコンテナのIPアドレスを inventory.ini に入力します。
今回は 192.168.16.2 と記載していますが、環境に合わせて変更が必要です。

[target]
192.168.16.2

[target:var]
ansible_python_interpreter=/usr/bin/python3

コンテナのIPアドレスは内部で起動しているUbuntuに接続すると確認できます。

# target コンテナに接続
$docker exec -it target bash
# IPアドレスの確認
$hostname -i
playbook.yml の実行

ansible のコンテナに接続してAnsibleから cron の設定を行います。
今回SSH接続のパスワードは password としています。

# ansible コンテナに接続
$docker exec -it ansible bash
# Ansibleから cron の設定
$ansible-playbook -i inventry.ini playbook.yml --ask-pass

SSH password:

PLAY [target] *******************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************
ok: [192.168.16.2]
TASK [setup cron] ***************************************************************************************************************************************************************
changed: [192.168.16.2]
PLAY RECAP **********************************************************************************************************************************************************************
192.168.16.2               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
cron ファイルの確認

今回設定した内容は root のファイル名で記載されています。

$cat /var/spool/cron/crontabs/root

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab2yp2i8ru installed on Sun Jul 18 14:24:59 2021)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
#Ansible: create log
 * * * * * echo 'test' >> /var/log/test.log
cron の動作確認

1分間隔で文字列が追記されていることを確認します。

$cat /var/log/test.log
test
test
test
cron の実行ログ

デバックをする際に使用したので忘備録として残します。
rsyslog の設定ファイルから cron の実行ログを残すように変更を行います。

# rsyslog の設定を変更
$vi /etc/rsyslog.d/50-default.conf
# コメントアウトを外す
cron.* /var/log/cron.log

設定を反映させるために rsyslog のサービスを再起動します。

$service rsyslog restart

cron の実行ログは /var/log/cron.log から確認できます。

$cat /var/log/cron.log

Jul 18 14:25:01 7a07b9e45953 CRON[554]: (root) CMD (echo 'test' >> /var/log/test.log)
Jul 18 14:26:01 7a07b9e45953 CRON[567]: (root) CMD (echo 'test' >> /var/log/test.log)
Jul 18 14:27:01 7a07b9e45953 CRON[569]: (root) CMD (echo 'test' >> /var/log/test.log)

Write Excel file using Apache POI in Android

f:id:knkomko:20210622232542p:plain

はじめに

今回は Excel ファイルを作成する Apach POI を試してみました。
Android のダウンロードフォルダにExcelファイルを保存しています。
f:id:knkomko:20210622232819j:plain:w250

build.gradle
implementation 'org.apache.poi:poi:3.17'
MainActivity

Strage Access Framework を使用してExcelファイルを保存しています。

private fun createFile() {
    val current = LocalDateTime.now()
    val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")
    val formatted = current.format(formatter)
    val fileName = "${formatted}.xlsx"
    val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
    intent.type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    intent.putExtra(Intent.EXTRA_TITLE, fileName)
    startActivityForResult(intent, CREATE_FILE)
}

HSSFWorkbook、HSSFSheet、HSSFRow、HSSFCell、でセルを指定します。
セルへの書き込みは hssfCell.setCellValue*1 で行っています。
最後は hssWorkbook.write(outputStream) でExcelファイルを保存しています。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == CREATE_FILE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
            var uri: Uri? = data.data

            var hssfWorkbook: HSSFWorkbook = HSSFWorkbook()
            var hssfSheet: HSSFSheet = hssfWorkbook.createSheet()

            var count: Int = 0
            for (y in 0..5) {
                var hssfRow: HSSFRow = hssfSheet.createRow(y)
                for (x in 0..5) {
                    var hssfCell: HSSFCell = hssfRow.createCell(x)
                    hssfCell.setCellValue((count++).toString())
                }
            }

            try {
                if(uri != null) {
                    applicationContext.contentResolver.openOutputStream(uri).use { outputStream ->
                        hssfWorkbook.write(outputStream)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

*1:count++).toString(

Ubuntu 20.04 GUI版JMeterをDockerで起動する

f:id:knkomko:20210605222454p:plain

はじめに

Windowsの開発環境に変更を加えたくなかったのでDockerで起動しているUbuntuGUIに変更してJMeterを使ってみました。

使用するファイル
C:\
│  docker-compose.yml
│
├─home\
└─ubuntu\
        Dockerfile
docker-compose.yml
version: '3'

services:
   app:
     build: 
      context: ./ubuntu/
      dockerfile: ./Dockerfile
     ports:
      - '2222:22'
      - '13389:3389'
     tty: true
     container_name: ubuntu20.04
     volumes:
      - ./home:/home
Dockerfile
FROM ubuntu:20.04

RUN apt update
RUN apt install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
 
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
ENTRYPOINT [ "/usr/sbin/sshd", "-D" ]

RUN apt-get update
RUN echo y | apt-get upgrade

# JMeter
RUN echo y | apt-get install openjdk-8-jdk
RUN cd /opt
RUN wget http://ftp.meisei-u.ac.jp/mirror/apache/dist//jmeter/binaries/apache-jmeter-5.2.1.tgz
RUN tar xvzf apache-jmeter-5.2.1.tgz
RUN echo "export PATH=$PATH:/opt/apache-jmeter-5.2.1/bin" >> ~/.bashrc

EXPOSE 3389
ssh接続

Ubuntussh接続します。
今回ssh接続のパスワードは password にしています。

$ssh -p 2222 root@localhost
RDP サーバ xrdp インストール
$apt-get install xrdp
デスクトップ環境 lxde インストール
$apt-get install lxde
Windows からリモートデスクトップ接続

Ubuntuリモートデスクトップ接続します。

localhost:13389

f:id:knkomko:20210606014815p:plain:w350

root でログインします。

username: root
password: password

f:id:knkomko:20210606014952p:plain:w350

Ubuntuリモートデスクトップ接続できる事が確認できます。
f:id:knkomko:20210606015138p:plain:w350

JMeter の起動

System Tools の LXTerminal を起動します。
f:id:knkomko:20210606015315p:plain:w350

ホームディレクトリに移動してJMeterを実行します。

$jmeter

f:id:knkomko:20210606013943p:plain:w350

JMeter が起動して使える事を確認します。
f:id:knkomko:20210606014140p:plain:w350

Ubuntu 20.04 SSHサーバをDockerで起動する

f:id:knkomko:20210605222454p:plain

はじめに

WindowsUbuntuを使う方法にWindows Subsystem for Linux がありますが、他の開発者も使う事や再構築のし易さを考えて今回はDockerを使いました。

使用するファイル
C:\
│  docker-compose.yml
│
├─home\
└─ubuntu\
        Dockerfile
docker-compose.yml
version: '3'

services:
   app:
     build: 
      context: ./ubuntu/
      dockerfile: ./Dockerfile
     ports:
      - '2222:22'
     tty: true
     container_name: ubuntu20.04
     volumes:
      - ./home:/home
Dockerfile
FROM ubuntu:20.04

RUN apt update
RUN apt install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
 
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
ENTRYPOINT [ "/usr/sbin/sshd", "-D" ]
ssh接続の確認

ssh接続はUbuntuの22番ポートにポートフォワーディングしている2222番ポートを指定します。今回ssh接続のパスワードはpasswordとしています。

ssh -p 2222 root@localhost
コンテナを作り直してssh接続する場合

コンテナを作り直すとssh接続が失敗します。

PS C:\docker\ubuntu20_04> ssh -p 2222 root@localhost
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:*********************************************************.
Please contact your system administrator.
Add correct host key in C:\\Users\\<User name>/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in C:\\Users\\<User name>/.ssh/known_hosts:2
ECDSA host key for [localhost]:2222 has changed and you have requested strict checking.
Host key verification failed.

SSHでは初回接続時に接続先ホストの公開鍵を保存しておき、次回接続時にホスト鍵を比較して前回と同じホストに接続したかを確認するような仕組みになっています。
「SSHホスト鍵が変わってるよ!」と怒られたときの対処 - Qiita

known_hostsファイルからssh鍵を削除する事でssh接続が行えました。

$ ssh-keygen -R '[localhost]:2222'

DockerでFTPサーバを起動してC#でファイル転送を行う

はじめに

前回はDockerでSQL Serverを起動して開発に利用しました。
knkomko.hatenablog.com

今回はFTPサーバを使うため、前回と同様にDockerを利用していきます。
DockerでPure-FTPdを起動してC#によりファイル転送を行います。

yml形式のファイルとC#ソースコードはこちらです。
github.com

開発環境

・Widnows10 Pro
・Docker Engine Community Version 20.10.5

使用するファイル
C:\DOCKER\PURE-FTP\
│  docker-compose.yml
│
├─ etc\
│
└─ home\
docker-compose.yml

FTPでファイルをアップロードすると ./home ディレクトリに保存されます。

version: '3'

services:
  ftp-server:
    image: stilliard/pure-ftpd:hardened
    container_name: ftp-server
    ports:
      - "21:21"
      - "30000-30009:30000-30009"
    volumes:
      - ./home:/home/ftpusers
      - ./etc:/etc/ssl/private
    environment:
      - PUBLICHOST=localhost
      - FTP_USER_NAME=xuser
      - FTP_USER_PASS=xpass
      - FTP_USER_HOME=/home/ftpusers
      - ADDED_FLAGS="--tls=2"
FTPサーバの起動

yml形式のファイルと同じディレクトリで compose upを実行します。

$docker compose up -d --build

container ls で起動しているコンテナにFTPサーバが表示されることを確認します。

$docker container ls

CONTAINER ID   IMAGE                          COMMAND                  CREATED          STATUS          PORTS                                                      NAMES
d31b413c7a11   stilliard/pure-ftpd:hardened   "/bin/sh -c '/run.sh…"   54 seconds ago   Up 46 seconds   0.0.0.0:21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp   ftp-server

stop <コンテナ名> で起動しているコンテナを停止できます。

$docker stop ftp-server

start <コンテナ名> で停止しているコンテナを起動できます。

$docker start ftp-server
FTPサーバの確認

Windows10の場合になります。
エクスプローラーからFTPサーバに接続ができる事を確認します。

ftp://localhost/

f:id:knkomko:20210505003922p:plain:w450

サインオンの画面ではアカウント情報を入力します。
[Log On]ボタンを押下するとFTPサーバに接続できます。

ユーザー名:xuser
パスワード:xpass

f:id:knkomko:20210505154820p:plain:w450

C#でファイル転送

FTPサーバーにファイル転送を行うサンプルになります。
f:id:knkomko:20210505162802p:plain:w450

サンプルの作成にあたって参考にした公式ドキュメントです。
docs.microsoft.com

ファイルの転送の方法は2ステップです。

ステップ1でFTPサーバにログオンします。
ログオンに成功するとファイル転送を行うStreamが取得できます。

// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + TextHost.Text + "/" + ListBoxDirectory.SelectedItem.ToString());
request.Method = WebRequestMethods.Ftp.DownloadFile;

// FTP user logon.
request.Credentials = new NetworkCredential(TextUserName.Text, TextPassword.Text);

ステップ2でファイルの転送を行います。
ダウンロードになりますが、FileStreamを使用してFTPサーバにあるファイルのバイナリを1024バイトごと読み込んで、ローカルのファイルに書き込んでいます。

using (FileStream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads\" + ListBoxDirectory.SelectedItem.ToString(), FileMode.CreateNew, FileAccess.Write))
using (Stream responseStream = response.GetResponseStream())
{
    byte[] buffer = new byte[1024];
    while (true)
    {
        int readSize = responseStream.Read(buffer, 0, buffer.Length);
        if (readSize == 0)
        {
            break;
        }
        fs.Write(buffer, 0, readSize);
    }
}

Ubuntu 18.04 自己署名証明書でSSLに対応する

はじめに

SSLに対応したテスト環境が必要になったので自己署名証明書を利用しました。
今回は証明書を発行して Google ChromeSSLに対応する方法をまとめます。
内容は example.com にアクセスして Nginx のトップページを表示します。

自己認証局の準備

証明書の保存場所を指定します。

$sudo vim /etc/ssl/openssl.cnf

[ CA_default ]

dir             = /etc/ssl/example-ca           # Where everything is kept

証明書の保存場所を作成します。

$mkdir /etc/ssl/example-ca

$cd /etc/ssl/example-ca

$ sudo mkdir certs
$ sudo mkdir private
$ sudo mkdir crl
$ sudo mkdir newcerts

$sudo sh -c "echo '01' > /etc/ssl/example-ca/serial" 
$sudo touch /etc/ssl/example-ca/index.txt
CA証明書の作成
$cd /etc/ssl/example-ca
#有効期限が10年の自己署名証明書を作成
sudo openssl req -new -x509 -newkey rsa:2048 -out cacert.pem -keyout private/cakey.pem -days 36500
#認証局のパスワードを入力
Enter PEM pass phrase:
#パスワードの再入力
Verifying - Enter PEM pass phrase:
#証明書の情報を入力
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Ota
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example CA
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Example CA
Email Address []:email@example.com

2つのファイルが作成されている事を確認します。

#CA証明書
/etc/ssl/example-ca/cacert.pem
#CA証明書の秘密鍵
/etc/ssl/example-ca/private/cakey.pem
作成したCA証明書をブラウザにインポート

以下のコマンドで作成した example-ca.der をクライアント側で実行します。

$sudo openssl x509 -inform PEM -outform DER -in /etc/ssl/example-ca/cacert.pem -out /etc/ssl/example-ca/example-ca.der

Windows10 の場合になります。
exemple-ca.der をダブルクリックして起動して、[証明書のインストール]ボタンを左クリック。
f:id:knkomko:20210503011911p:plain:w350

"ローカルコンピュータ"を選択して[次へ]ボタンを左クリック。
f:id:knkomko:20210503012150p:plain:w350

"証明書をすべて次のストアに配置する"を選択して[参照]ボタンを左クリック。
f:id:knkomko:20210503012259p:plain:w350

"信頼されたルート証明機関"を選択して[OK]ボタンを左クリック。
f:id:knkomko:20210503012346p:plain:w250

[次へ]ボタンを左クリック。
f:id:knkomko:20210503012444p:plain:w350

[完了]ボタンを左クリック。
f:id:knkomko:20210503012518p:plain:w350

メッセージが表示されたらインストールは完了です。
f:id:knkomko:20210503012538p:plain:w250

自己署名証明書の作成
$sudo mkdir /etc/ssl/example.com/

$sudo openssl req -new -keyout /etc/ssl/example.com/example-key.pem -out /etc/ssl/example.com/example-csr.pem

#秘密鍵のパスワードを入力
Enter PEM pass phrase:
#パスワードの再入力
Verifying - Enter PEM pass phrase:
#証明書の情報を入力
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Ota
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example CA
Organizational Unit Name (eg, section) []:
#ドメイン名を入力
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:email@example.com
#パスワードを入力
A challenge password []:
An optional company name []:

2つのファイルが作成されている事を確認します。

#サーバ証明書要求ファイル
/etc/ssl/example.com/example-csr.pem
#サーバ秘密鍵
/etc/ssl/example.com/example-key.pem
SAN を含んだ自己署名証明書の作成

Google Chrome 58 から Common Name ではなく SubjectAltName でドメイン名を確認するため、SubjectAltName を含んだ自己署名証明書を作成します。

$cd /etc/ssl/example.com
$sudo sh -c "echo subjectAltName=DNS:example.com > san.ext"

ファイルが作成されている事を確認します。

#SubjectAltName ファイル
/etc/ssl/example.com/san.ext

root権限を使用して署名を行います。

#rootにログインする
$sudo su
#自己承認局で署名
$openssl ca -days 36500 -cert /etc/ssl/example-ca/cacert.pem -keyfile /etc/ssl/example-ca/private/cakey.pem -in /etc/ssl/example.com/example-csr.pem > /etc/ssl/example.com/example.crt -extfile /etc/ssl/example.com/san.ext
#自己認証局のパスワードを入力
Enter pass phrase for /etc/ssl/Hoge-Private-CA/private/cakey.pem:
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n] y
#rootからログアウトする
$exit

ファイルが作成されている事を確認します。

#SubjectAltName を含んだ自己署名証明書ファイル
/etc/ssl/example.com/example.crt
Nginx のインストール
$sudo apt update

$sudo apt-get install -y wget

$sudo apt-get install -y gnupg2

$wget https://nginx.org/keys/nginx_signing.key

$sudo apt-key add nginx_signing.key

$sudo vi /etc/apt/sources.list

# sources.list に追加する 
deb http://nginx.org/packages/ubuntu/ bionic nginx
deb-src http://nginx.org/packages/ubuntu/ bionic nginx

$sudo apt update

$sudo apt install nginx

# Nginx のバージョンが表示される事を確認する
$nginx -v
Nginx の設定

Nginxのサービス起動時に証明書のパスワード入力を求められるため
パスワードを入力したファイルを作成して参照するようにします。

$sudo vim /etc/ssl/example.com/pwf

#パスワードを入力
example

証明書を利用してSSL通信ができるように設定します。

$sudo vim /etc/nginx/conf.d/default.conf

#default.conf を変更
server {
    listen      80;
    listen      443 ssl;
    ssl on;                                                                                                                                                                       
    server_name  example.com;

    ssl_certificate /etc/ssl/example.com/example.crt;
    ssl_password_file /etc/ssl/example.com/pwf
    ssl_certificate_key /etc/ssl/example.com/example-key.pem

Nginx のサービスを開始します。
証明書のアクセス権が無いとエラーになるのでroot権限で実行しています。

#rootにログインする
$sudo su

#設定ファイルのテスト
$nginx -t

#サービスの開始
$systemctl start nginx

#rootからログアウトする
$exit
hostファイルの編集

DNSサーバの代わりにhostファイルを使用して名前解決をしました。
Windows10 の場合は C:\Windows\System32\drivers\etc にあります。
f:id:knkomko:20210503013032p:plain:w450

サーバのIPとサーバ証明書に入力していたドメイン名を入力します。

<サーバのIP>          example.com

f:id:knkomko:20210503013225p:plain:w450

SSLの確認

SSLに対応している事が確認できました。
f:id:knkomko:20210503013720p:plain:w450

DockerでSQL Serverのデータベースをリストアして起動する

f:id:knkomko:20210430223349p:plain

はじめに

これまでSQL Serverを利用した開発は、EC2インスタンスを使用していました。
Dockerを使うと手元の環境で SQL Server を起動して開発を行う事が出来るので
今回はDockerの利点である環境の自動構築を行い、接続までの手順をまとめます。

開発環境

・Widnows10 Pro
・Docker Engine Community Version 20.10.5

全体像

docker compose コマンドで環境の自動構築を行う時にSQL ServerのバックアップファイルをリストアすることでEC2利用時と同じデータベースを再現します。

f:id:knkomko:20210430223815p:plain

使用するファイル
C:\DOCKER\SAMPLE-MSSQL
│  docker-compose.yml
│
├─ mssql
│      db-init.sh
│      ddl.sql
│      Dockerfile
│      entrypoint.sh
│
├─ mssql-backup
│      sampledb.bak
│
└─ mssql-data
docker-compose.yml
version: '3'

services:
   db:
     build: 
      context: ./mssql/
      dockerfile: ./Dockerfile
     container_name: sample-mssql-2017
     ports:
      - "1433:1433"
     environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=Sa@mple@dm1n
      - MSSQL_PID=Express
      - MSSQL_LCID=1041
      - MSSQL_COLLATION=Japanese_CI_AS
      - PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
     volumes:
      - ./mssql-data:/var/opt/mssql
      - ./mssql-backup:/var/opt/mssql/data/backup
Dockerfile
FROM mcr.microsoft.com/mssql/server:2017-latest

COPY ./entrypoint.sh /usr/src/entrypoint.sh
COPY ./db-init.sh /usr/src/db-init.sh
COPY ./ddl.sql /usr/src/ddl.sql

WORKDIR /usr/src/

RUN chmod +x /usr/src/db-init.sh

CMD /bin/bash ./entrypoint.sh
entrypoint.sh

デバッグし易いように db-init.sh の実行ログを log.txt として残しています。

 ./db-init.sh >> /var/opt/mssql/data/backup/log.txt 2>&1 & /opt/mssql/bin/sqlservr
db-init.sh

25s の待ち時間はリストアを行う為にSQL Serverが起動するまで待ちます。
10s の待ち時間はデータベースユーザを追加する為にリストアの終了を待ちます。

/bin/sleep 25s

touch /var/opt/mssql/data/sampledb.mdf
touch /var/opt/mssql/data/sampledb_Log.ldf

/opt/mssql-tools/bin/sqlcmd -H localhost -U sa -P S@mple@dm1n -Q "RESTORE DATABASE sampledb FROM DISK = '/var/opt/mssql/data/backup/sampledb.bak' WITH  FILE = 1, STATS = 5, REPLACE, MOVE 'sampledb' TO '/var/opt/mssql/data/sampledb.mdf', MOVE 'sampledb_Log' TO '/var/opt/mssql/data/sampledb_Log.ldf'"

/bin/sleep 10s

/opt/mssql-tools/bin/sqlcmd -H localhost -U sa -P S@mple@dm1n -i /usr/src/ddl.sql
ddl.sql
EXECUTE AS LOGIN = 'sa'

USE sampletable
GO

DROP USER SampleUser

CREATE USER SampleUser  for login SampleUser

ALTER USER SampleUser 
    WITH DEFAULT_SCHEMA = dbo
GO

GRANT CONNECT TO SampleUser
GO

exec sp_addrolemember 'db_owner', SampleUser
GO
SQL Server の起動
docker compose up --build
SQL Server の接続

SQL Server Management Studio を使用して接続ができることを確認しました。
f:id:knkomko:20210430221003p:plain