Redmine サーバを引っ越して Podman で起動した
3 年ぶりに Redmine のサーバを引越しした。
ライフログのために Redmine を愛用している。何かと忙しく複雑な日々のスケジュールや買い物をチケットとして管理する。一言でいえばクラウド日記帳のような使い方ということだが…チケットに様々な情報を記録し、それをどんどん関連付けていくことで、過去のイベントや行動、反省点を振り返りながら行動できる。難しいことは Redmine に記録する。その後は、また必要になるまで忘れてしまって良い。その分だけ目の前のできごとに集中して楽しむことができる。これが私のスタイルに適合して暮らしの必需品になっている。
引越し元のサーバは Amazon EC2 である。 その時の作業メモは本ブログに残してある (自分用 Redmine を Amazon EC2 + Docker 環境に移行した)。 3 年前の当時 EC2 の Saving Plans を買って運用してきた。 それを最近になって使い切ったので、より安い VPS へまた移すことにする。
もちろん、当時の移行の記録や、サーバ見直しのスケジュールも Redmine で管理してきた。
引越し先は WebARENA Indigo。他には Vultr や Linode 等も検討したが、円安もあってそれほど安くないし、WebARENA Indigo のリソースが丁度良いと考えた。WebARENA Indigo では、RAM 1 GB, 1 vCPU, 20 GB SSD の構成を月額 450 円で使える。 しかも、ちょうど 「eKYC」本人確認キャンペーン を開催している。最大 3 ヶ月間は 35 % OFF で使えるらしい。月額 300 円。これはお得だ。
この記事では Redmine サーバを引越しするための手順を記録する。 引越し後のサーバでは OS に初めて AlmaLinux を使ってみた。 加えて、せっかくなので Podman に挑戦した。 これまで使ってきた docker-compose.yml を活用し、かつユーザ権限で Redmine サーバを常時起動させるには少し工夫が必要だった。
1. バックアップ
何をするにもまずはバックアップ。移行元のサーバにログインしてバックアップを取得する。
1.1. 旧サーバの様子を確認
ログインする:
> ssh fg-redmine
Last login: Mon Sep 25 17:06:47 2023 from 172.135.178.217.shared.user.transix.jp
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-2/
54 package(s) needed for security, out of 71 available
Run "sudo yum update" to apply all updates.
サーバの状態を確認する:
$ w
17:10:03 up 81 days, 23:49, 1 user, load average: 0.08, 0.02, 0.01
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
ec2-user pts/0 172.135.178.217. 17:09 1.00s 0.01s 0.00s w
$ uname -a
Linux ip-172-31-12-243.ap-northeast-1.compute.internal 4.14.318-241.531.amzn2.x86_64 #1 SMP Tue Jun 27 21:49:00 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
$ docker --version
Docker version 20.10.23, build 7155243
Docker Compose で起動していた:
$ cd redmine/
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------------------
redmine_certbot_1 /bin/sh -c trap exit TERM; ... Up 443/tcp, 80/tcp
redmine_db_1 docker-entrypoint.sh postgres Up 5432/tcp
redmine_nginx_1 /docker-entrypoint.sh /bin ... Up 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp
redmine_redmine_1 /docker-entrypoint.sh rail ... Up 3000/tcp
docker-compose.yml は下記のようにしていた:
version: '3.1'
services:
certbot:
image: certbot/certbot
restart: always
volumes:
- ./data/letsencrypt:/etc/letsencrypt
- certbot:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${!}; done;'"
nginx:
image: nginx:1-alpine
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx/conf:/etc/nginx/conf.d
- ./data/nginx/ssl:/etc/ssl/private
- ./data/letsencrypt:/etc/letsencrypt
- certbot:/var/www/letsencrypt
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
redmine:
image: redmine:5.0.5-alpine
restart: always
volumes:
- ./data/redmine/conf/configuration.yml:/usr/src/redmine/config/configuration.yml
- ./data/redmine/files:/usr/src/redmine/files
- ./data/redmine/plugins:/usr/src/redmine/plugins
- ./data/redmine/themes/bleuclair:/usr/src/redmine/public/themes/bleuclair
environment:
REDMINE_DB_POSTGRES: db
REDMINE_DB_DATABASE: redmine
REDMINE_DB_USERNAME: postgres
REDMINE_DB_PASSWORD: ************
db:
image: postgres:9.5-alpine
restart: always
volumes:
- db-data:/var/lib/postgresql/data
- ./backup/db:/backup
environment:
POSTGRES_DB: redmine
POSTGRES_PASSWORD: ************
volumes:
db-data:
certbot:
1.2. バックアップ生成
では早速、データベースのバックアップを生成していく。
Docker ボリュームを使用し、./backup
ディレクトリをデータベースのコンテナの /backup
にマウントしてある。
PostgreSQL サーバ上で pg_dump
コマンドを実行し、その出力を /backup
へ出力した:
$ BKNAME="redmine-2023926"
$ docker-compose exec db pg_dump -U postgres -Fc -h localhost -f "/backup/$BKNAME.sqlc" redmine
$ ls backup/db/
redmine-20230705.sqlc redmine-2023926.sqlc
次に、先程の SQL ファイルと、Redmine のファイル群をローカル PC へ一気に回収する。
Redmine のファイル群は rsync
で直接ダウンロードする。王道ならばサーバ上で一度 GZIP とか BZIP2 とかにまとめてしまうところ。しかし、そうするとディスク容量がファイル実体の 2 倍必要になってしまう。ディスク容量の費用をケチるために直接 rsync
する。
下記はローカル PC 上で実行した:
> cd backup/web/redmine.xaxxi.net/
> bash
$ BKNAME="redmine-20230926"
$ scp "fg-redmine:/home/ec2-user/redmine/backup/db/$BKNAME.sqlc" .
$ rsync -av "fg-redmine:/home/ec2-user/redmine/data/redmine/*" "$BKNAME"
$ tar zcf "$BKNAME.tar.gz" "$BKNAME"
$ ls -lh
合計 2.3G
(中略)
drwxr-xr-x. 2 fujii fujii 0 9月 26 02:12 redmine-2023926
-rwxr-xr-x. 1 fujii fujii 3.0M 9月 26 02:12 redmine-2023926.sqlc
-rwxr-xr-x. 1 fujii fujii 237M 9月 26 02:13 redmine-2023926.tar.gz
1.3. 以前のバックアップを削除
最後に、前回のメンテナンスで作った古いバックアップを削除した。
どうせ AWS 側のサーバは畳むのだから、この作業は不要だ。 しかし次回のメンテナンスも、今書いているこの手順を見て行う。 その時に忘れないために残しておく。
$ rm backup/db/redmine-20230705.sqlc
2. Redmine サーバの更新
移行前のサーバの Redmine を最新に更新し、その Redmine で動作することを確認しておく。 これで新しいサーバでは最新の Redmine バージョンから始めることができる。 データの復元が少し安全になるだろう。
更新前の Redmine バージョンは 5.0.4:
Redmine version 5.0.4.stable
Ruby version 3.1.3-p185 (2022-11-24) [x86_64-linux-musl]
Rails version 6.1.7
Environment production
Database adapter PostgreSQL
Mailer queue ActiveJob::QueueAdapters::AsyncAdapter
Mailer delivery smtp
2.1. パッケージ更新
パッケージを更新する:
$ sudo yum update
(中略)
Removed:
kernel.x86_64 0:4.14.301-224.520.amzn2
Installed:
grub2.x86_64 1:2.06-14.amzn2.0.1 grub2-pc.x86_64 1:2.06-14.amzn2.0.1
grub2-tools.x86_64 1:2.06-14.amzn2.0.1 grub2-tools-efi.x86_64 1:2.06-14.amzn2.0.1
grub2-tools-extra.x86_64 1:2.06-14.amzn2.0.1 grub2-tools-minimal.x86_64 1:2.06-14.amzn2.0.1
kernel.x86_64 0:4.14.322-246.539.amzn2
Updated:
amazon-ssm-agent.x86_64 0:3.2.1377.0-1.amzn2 bind-export-libs.x86_64 32:9.11.4-26.P2.amzn2.13.4
bind-libs.x86_64 32:9.11.4-26.P2.amzn2.13.4 bind-libs-lite.x86_64 32:9.11.4-26.P2.amzn2.13.4
bind-license.noarch 32:9.11.4-26.P2.amzn2.13.4 bind-utils.x86_64 32:9.11.4-26.P2.amzn2.13.4
ca-certificates.noarch 0:2021.2.50-72.amzn2.0.8 containerd.x86_64 0:1.6.19-1.amzn2.0.3
curl.x86_64 0:8.2.1-1.amzn2.0.3 dhclient.x86_64 12:4.2.5-79.amzn2.1.5
dhcp-common.x86_64 12:4.2.5-79.amzn2.1.5 dhcp-libs.x86_64 12:4.2.5-79.amzn2.1.5
ec2-hibinit-agent.noarch 0:1.0.2-5.amzn2 elfutils-default-yama-scope.noarch 0:0.176-2.amzn2.0.2
elfutils-libelf.x86_64 0:0.176-2.amzn2.0.2 elfutils-libs.x86_64 0:0.176-2.amzn2.0.2
glibc.x86_64 0:2.26-63.amzn2.0.1 glibc-all-langpacks.x86_64 0:2.26-63.amzn2.0.1
glibc-common.x86_64 0:2.26-63.amzn2.0.1 glibc-locale-source.x86_64 0:2.26-63.amzn2.0.1
glibc-minimal-langpack.x86_64 0:2.26-63.amzn2.0.1 grub2-common.noarch 1:2.06-14.amzn2.0.1
grub2-pc-modules.noarch 1:2.06-14.amzn2.0.1 kernel-tools.x86_64 0:4.14.322-246.539.amzn2
krb5-libs.x86_64 0:1.15.1-55.amzn2.2.6 libcap.x86_64 0:2.54-1.amzn2.0.2
libcrypt.x86_64 0:2.26-63.amzn2.0.1 libcurl.x86_64 0:8.2.1-1.amzn2.0.3
libgcc.x86_64 0:7.3.1-17.amzn2 libgomp.x86_64 0:7.3.1-17.amzn2
libicu.x86_64 0:50.2-4.amzn2.0.1 libidn.x86_64 0:1.28-4.amzn2.0.5
libidn2.x86_64 0:2.3.0-1.amzn2.0.3 libjpeg-turbo.x86_64 0:2.0.90-2.amzn2.0.6
libnghttp2.x86_64 0:1.41.0-1.amzn2.0.3 libpng.x86_64 2:1.5.13-8.amzn2.0.5
libssh2.x86_64 0:1.4.3-12.amzn2.2.6 libstdc++.x86_64 0:7.3.1-17.amzn2
libtasn1.x86_64 0:4.10-1.amzn2.0.6 libtiff.x86_64 0:4.0.3-35.amzn2.0.14
libxml2.x86_64 0:2.9.1-6.amzn2.5.12 libxml2-python.x86_64 0:2.9.1-6.amzn2.5.12
microcode_ctl.x86_64 2:2.1-47.amzn2.2.15 openldap.x86_64 0:2.4.44-25.amzn2.0.7
openssh.x86_64 0:7.4p1-22.amzn2.0.5 openssh-clients.x86_64 0:7.4p1-22.amzn2.0.5
openssh-server.x86_64 0:7.4p1-22.amzn2.0.5 openssl.x86_64 1:1.0.2k-24.amzn2.0.9
openssl-libs.x86_64 1:1.0.2k-24.amzn2.0.9 python-configobj.noarch 0:4.7.2-7.amzn2.0.1
python-ipaddress.noarch 0:1.0.16-2.amzn2.0.2 python-pillow.x86_64 0:2.0.0-23.gitd1c6db8.amzn2.0.7
python-requests.noarch 0:2.6.0-10.amzn2.0.1 python2-rsa.noarch 0:3.4.1-1.amzn2.0.4
python3.x86_64 0:3.7.16-1.amzn2.0.4 python3-libs.x86_64 0:3.7.16-1.amzn2.0.4
python3-pip.noarch 0:20.2.2-1.amzn2.0.4 python3-setuptools.noarch 0:49.1.3-1.amzn2.0.3
runc.x86_64 0:1.1.7-3.amzn2 shadow-utils.x86_64 2:4.1.5.1-24.amzn2.0.3
sudo.x86_64 0:1.8.23-10.amzn2.3.4 system-release.x86_64 1:2-15.amzn2
tcpdump.x86_64 14:4.9.2-4.amzn2.1.0.1 yajl.x86_64 0:2.0.4-4.amzn2.0.3
Replaced:
grub2.x86_64 1:2.06-9.amzn2.0.3 grub2-tools.x86_64 1:2.06-9.amzn2.0.3
Complete!
Redmine 稼働状態を調べる。 なぜわざわざ確認するかというと、パッケージ更新によりプロセスが停止してしまうことがあったからだ。 サーバ費用をケチったせいだ。
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------------------
redmine_certbot_1 /bin/sh -c trap exit TERM; ... Up 443/tcp, 80/tcp
redmine_db_1 docker-entrypoint.sh postgres Up 5432/tcp
redmine_nginx_1 /docker-entrypoint.sh /bin ... Up 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp
redmine_redmine_1 /docker-entrypoint.sh rail ... Up 3000/tcp
でも今回はちゃんと生き延びたようだ。
2.2. Redmine 本体の更新
Redmine イメージを更新する。更新後のバージョンは v5.0.5。 docker-compose.yml を編集して Redmine のイメージを変更した:
$ vim docker-compose.yml
$ grep redmine: docker-compose.yml
redmine:
image: redmine:5.0.5-alpine
$ docker-compose pull
Redmine コンテナを再起動:
$ docker-compose down
$ docker-compose up -d
このあと無事に Redmine が動作することを確認した。 バージョンはほとんど同じなのでマイグレーションは不要。 それでも再度バックアップを取っておくのが望ましい。
更新後のバージョン:
Redmine version 5.0.5.stable
Ruby version 3.1.4-p223 (2023-03-30) [x86_64-linux-musl]
Rails version 6.1.7.2
Environment production
Database adapter PostgreSQL
Mailer queue ActiveJob::QueueAdapters::AsyncAdapter
Mailer delivery smtp
3. 新規サーバの準備
引越し先のサーバは先述の通り、WebARENA Indigo である。 OS には AlmaLinux 9.0 を選択した。AlmaLinux をインストールして使うのは初めて。楽しみだ。
インスタンスは作成済みの状態から作業を始める。
SSH 接続する。
fg-indigo2
は ~/.ssh/config
に登録してある:
> ssh fg-indigo2
[alma@i-19100000524547 ~]$
3.1. サーバ構成を眺める
まず記念に w
:
$ w
17:33:48 up 7 min, 2 users, load average: 0.00, 0.03, 0.01
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
alma pts/0 17:30 52.00s 0.00s 0.00s -bash
alma pts/1 17:32 3.00s 0.01s 0.00s w
これも記念で OS 確認:
$ uname -a
Linux i-19100000524547 5.14.0-70.13.1.el9_0.x86_64 #1 SMP PREEMPT Tue May 17 15:53:11 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/almalinux-release
AlmaLinux release 9.0 (Emerald Puma)
ストレージ。ルートパーティションは 20 GB:
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 453M 0 453M 0% /dev
tmpfs 481M 0 481M 0% /dev/shm
tmpfs 193M 2.9M 190M 2% /run
/dev/vda4 20G 908M 19G 5% /
/dev/vda3 495M 99M 397M 20% /boot
/dev/vda2 200M 6.2M 194M 4% /boot/efi
tmpfs 97M 0 97M 0% /run/user/1000
CPU。1 vCPU だけ。個人で使うには問題無いと思っている:
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 46 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Vendor ID: GenuineIntel
Model name: Intel Xeon E312xx (Sandy Bridge)
CPU family: 6
Model: 42
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
Stepping: 1
BogoMIPS: 4399.98
Flags: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm
constant_tsc rep_good nopl cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_dea
dline_timer aes xsave avx hypervisor lahf_lm pti xsaveopt
Virtualization features:
Hypervisor vendor: KVM
Virtualization type: full
Caches (sum of all):
L1d: 32 KiB (1 instance)
L1i: 32 KiB (1 instance)
L2: 4 MiB (1 instance)
NUMA:
NUMA node(s): 1
NUMA node0 CPU(s): 0
Vulnerabilities:
Itlb multihit: KVM: Mitigation: VMX unsupported
L1tf: Mitigation; PTE Inversion
Mds: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Meltdown: Mitigation; PTI
Spec store bypass: Vulnerable
Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Spectre v2: Mitigation; Retpolines, STIBP disabled, RSB filling
Srbds: Not affected
Tsx async abort: Not affected
RAM は 1 GB くらい:
$ cat /proc/meminfo
MemTotal: 983688 kB
MemFree: 702468 kB
MemAvailable: 695292 kB
Buffers: 5052 kB
Cached: 102960 kB
SwapCached: 0 kB
Active: 54432 kB
Inactive: 102552 kB
Active(anon): 936 kB
Inactive(anon): 52528 kB
Active(file): 53496 kB
Inactive(file): 50024 kB
Unevictable: 1536 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 50376 kB
Mapped: 47452 kB
Shmem: 4492 kB
KReclaimable: 24392 kB
Slab: 50264 kB
SReclaimable: 24392 kB
SUnreclaim: 25872 kB
KernelStack: 1868 kB
PageTables: 1652 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 491844 kB
Committed_AS: 282632 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 14148 kB
VmallocChunk: 0 kB
Percpu: 476 kB
HardwareCorrupted: 0 kB
AnonHugePages: 2048 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 0 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 90092 kB
DirectMap2M: 958464 kB
ネットワーク。eth0。IP アドレスはなんとなく隠して貼っておく:
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
altname enp0s10
altname ens10
inet ***.***.**.***/24 brd ***.***.**.*** scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 ****::***:****:****:***/64 scope link
valid_lft forever preferred_lft forever
4.2. 基本的な設定
とりあえずシステム更新する:
$ sudo su -
# dnf --refresh update
# reboot
VIM だけは入れておく:
# dnf install vim-minimal
# vi --version | head -1
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Feb 09 2023 00:00:00)
ホスト名を設定して気持ちをスッキリさせる:
# hostname fg-indigo2
# vi /etc/hostname
後に邪魔になるので SELinux は無効化してしまう:
# getenforce
Enforcing
# vi /etc/selinux/config
# grep -e ^SELINUX= /etc/selinux/config
SELINUX=disabled
4. Podman の導入
以前のサーバでは Docker を使っていた。今回はせっかくなので Podman を使う。
4.1. Podman
Podman は Redhat 社が中心のオープンソースコミュニティで開発しているコンテナ管理ツール。Pods はコンテナをまとめたもの。Pods を manage するので Podman という名称らしい。
Docker と互換性を持ち、OCI (Open Container Initiative) コンテナに対応している。 そのため Docker HUB に登録されたイメージを使用することができる。 CLI コマンドも似せてあり、同じような考え方で操作できる。
Docker との大きな違いは、Podman がデーモンレスであること。 デーモンを介さずに起動することでルート権限を悪用されるセキュリティ上の問題を回避する。 ルートレスコンテナ、ユーザ権限で起動するコンテナに対応している。 Dockerd のようなデーモンに依存しないため、Dockerd が終了したら全コンテナが停止するということもない。
4.2. Podman の準備
Podman をインストールした:
# dnf install podman
# podman --version
podman version 4.4.1
podman-docker
パッケージをインストールすると docker
コマンドで Podman を使用できるようになる。
この記事を書いている今なら「初めから podman
コマンドを使えば良くね」と考えるが、
作業当時はよくわかっていなかったこともあり、基本 docker
コマンドで操作した。
この後に続く手順も docker
、docker-compose
を前提にした操作となる。
# dnf install podman-docker
# docker --version
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
podman version 4.4.1
言われた通りに /etc/containers/nodocker
を作成するとメッセージが静かになる:
# touch /etc/containers/nodocker
Podman API Socket を有効化する。Docker コマンド経由で使用するには必要:
# systemctl enable podman.socket
Created symlink /etc/systemd/system/sockets.target.wants/podman.socket → /usr/lib/systemd/system/podman.socket.
# systemctl status podman.socket
● podman.socket - Podman API Socket
Loaded: loaded (/usr/lib/systemd/system/podman.socket; enabled; preset: disabled)
Active: active (listening) since Mon 2023-09-25 18:02:20 UTC; 7min ago
Until: Mon 2023-09-25 18:02:20 UTC; 7min ago
Triggers: ● podman.service
Docs: man:podman-system-service(1)
Listen: /run/podman/podman.sock (Stream)
CGroup: /system.slice/podman.socket
Sep 25 18:02:20 fg-indigo2 systemd[1]: Listening on Podman API Socket.
起動したソケットに接続してテストする。OK が返ってきた:
# curl -w "\n" -H "Content-Type: application/json" --unix-socket /var/run/docker.sock http://localhost/_ping
OK
カーネルパラメータの net.ipv4.ip_unprivileged_port_start
を変更した。
ユーザ権限で 80 番ポートを LISTEN できるようになる:
# vi /etc/sysctl.d/99-sysctl.conf
# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80
ここからは alma
ユーザに戻り、ユーザ権限で作業する。
ユーザモードの Podman ソケットも生成:
# exit
$ systemctl --user enable podman.socket
Created symlink /home/alma/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket.
ユーザモードの Podman ソケットを使うよう、環境変数を設定する:
$ export DOCKER_HOST=unix:///run/user/1000/podman/podman.sock
$ vi ~/.bash_profile
$ grep DOCKER_HOST ~/.bash_profile
export DOCKER_HOST=unix:///run/user/1000/podman/podman.sock
ようやく hello-world を実行できるようになった:
$ docker run --rm hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull quay.io/podman/hello:latest...
Getting image source signatures
Copying blob d08b40be6878 done
Copying config e2b3db5d4f done
Writing manifest to image destination
Storing signatures
!... Hello Podman World ...!
.--"--.
/ - - \
/ (O) (O) \
~~~| -=(,Y,)=- |
.---. /` \ |~~
~/ o o \~~~~.----. ~~
| =(X)= |~ / (O (O) \
~~~~~~~ ~| =(Y_)=- |
~~~~ ~~~| U |~~
Project: https://github.com/containers/podman
Website: https://podman.io
Documents: https://docs.podman.io
Twitter: @Podman_io
ダグトリオみたいなのが現われた。Podman のマスコットキャラクターである。ありがてえ。
4.3. Docker compose のインストール
以前のサーバと同じような手順で Redmine を起動したいと考え、Docker Compose をインストールした。 Docker と共通のものを使うことができる:
# curl -SL https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# chmod 0755 /usr/local/bin/docker-compose
# docker-compose --version
Docker Compose version v2.20.3
実際のところ直接 Pods を使うべきだったのか否か、調べていない。
5. Redmine の構築
5.1. SSL 証明書の発行
Let’s Encrypt から証明書を取得する。certbot を Docker で実行した。 コマンド実行前に、取得対象のドメインの DNS レコードを設定しておく必要がある。
慎重に作業するなら、以前と異なるドメインを使うと良い。 この手順では記述を割愛したが、私は一旦仮ドメインの証明書を取得し構築後、うまくいったのを見届けてから本来のドメインで同じ作業をやり直した。
$ mkdir -p ~/redmine/data/letsencrypt
$ cd ~/redmine
$ docker run --rm -ti -v $PWD/data/letsencrypt:/etc/letsencrypt -p 80:80 certbot/certbot certonly --standalone
Requesting a certificate for redmine.xaxxi.net
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/redmine.xaxxi.net/fullchain.pem
Key is saved at: /etc/letsencrypt/live/redmine.xaxxi.net/privkey.pem
This certificate expires on 2023-12-25.
These files will be updated when the certificate renews.
NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$ ls data/letsencrypt
accounts archive live renewal renewal-hooks
5.2. Nginx の設定ファイル作成
Nginx の設定ファイルを作成する:
$ mkdir -p ~/redmine/data/nginx/{conf,ssl}
$ vi data/nginx/conf/proxy.conf
$ cat data/nginx/ssl/dhparam.pem
proxy.conf の内容は下記とした:
server {
listen 80;
server_name redmine.xaxxi.net;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
return 301 https://redmine.xaxxi.net$request_uri;
}
server {
listen 443 ssl;
server_name redmine.xaxxi.net;
ssl_certificate /etc/letsencrypt/live/redmine.xaxxi.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/redmine.xaxxi.net/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_trusted_certificate /etc/letsencrypt/live/redmine.xaxxi.net/chain.pem;
ssl_dhparam /etc/ssl/private/dhparam.pem;
add_header Strict-Transport-Security "max-age=63072000" always;
ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
proxy_set_header X-Forward-For $remote_addr;
proxy_pass http://redmine:3000/;
client_max_body_size 500M;
}
}
5.4. Redmine を起動
ここまでやると、とりあえず真っ新な状態の Redmine を起動できた。
$ docker-compose pull
$ docker-compose up -d
5.5. Redmine のデータ復元
Redmine のバックアップデータをアップロードする。 アップロード先のディレクトリを用意:
$ mkdir -p ~/redmine/backup/data/redmine
$ mkdir -p ~/redmine/backup/db
ローカル PC からバックアップファイルをアップロードした。 手順の初めに用意したものだ:
> rsync -aP redmine-20230926/* fg-indigo2:/home/alma/redmine/data/redmine/
> rsync -aP redmine-20230926.sqlc fg-indigo2:/home/alma/redmine/backup/db
PostgreSQL のデータを復元:
$ docker-compose exec db pg_restore -U postgres -d redmine -c -n public /backup/redmine-20230926.sqlc
なんか大量のエラーを出力した。全部プラグイン関係のもののようだ。使わないので見捨てた。
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2781; 1259 37130 INDEX unique_schema_migrations postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "unique_schema_migrations" does not exist
Command was: DROP INDEX public.unique_schema_migrations;
pg_restore: [archiver (db)] Error from TOC entry 2763; 1259 37315 INDEX index_projects_on_easy_baseline_for_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_projects_on_easy_baseline_for_id" does not exist
Command was: DROP INDEX public.index_projects_on_easy_baseline_for_id;
pg_restore: [archiver (db)] Error from TOC entry 2846; 1259 37328 INDEX index_easy_baseline_sources_on_source_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_easy_baseline_sources_on_source_id" does not exist
Command was: DROP INDEX public.index_easy_baseline_sources_on_source_id;
pg_restore: [archiver (db)] Error from TOC entry 2845; 1259 37329 INDEX index_easy_baseline_sources_on_destination_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_easy_baseline_sources_on_destination_id" does not exist
Command was: DROP INDEX public.index_easy_baseline_sources_on_destination_id;
pg_restore: [archiver (db)] Error from TOC entry 2844; 1259 37327 INDEX index_easy_baseline_sources_on_baseline_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_easy_baseline_sources_on_baseline_id" does not exist
Command was: DROP INDEX public.index_easy_baseline_sources_on_baseline_id;
pg_restore: [archiver (db)] Error from TOC entry 2679; 1259 37053 INDEX index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id" does not exist
Command was: DROP INDEX public.index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id;
pg_restore: [archiver (db)] Error from TOC entry 2682; 1259 37052 INDEX index_dmsf_workflow_steps_on_dmsf_workflow_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_workflow_steps_on_dmsf_workflow_id" does not exist
Command was: DROP INDEX public.index_dmsf_workflow_steps_on_dmsf_workflow_id;
pg_restore: [archiver (db)] Error from TOC entry 2673; 1259 37051 INDEX index_dmsf_locks_on_entity_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_locks_on_entity_id" does not exist
Command was: DROP INDEX public.index_dmsf_locks_on_entity_id;
pg_restore: [archiver (db)] Error from TOC entry 2670; 1259 37050 INDEX index_dmsf_links_on_project_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_links_on_project_id" does not exist
Command was: DROP INDEX public.index_dmsf_links_on_project_id;
pg_restore: [archiver (db)] Error from TOC entry 2667; 1259 37049 INDEX index_dmsf_folders_on_project_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_folders_on_project_id" does not exist
Command was: DROP INDEX public.index_dmsf_folders_on_project_id;
pg_restore: [archiver (db)] Error from TOC entry 2664; 1259 37048 INDEX index_dmsf_files_on_project_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_files_on_project_id" does not exist
Command was: DROP INDEX public.index_dmsf_files_on_project_id;
pg_restore: [archiver (db)] Error from TOC entry 2661; 1259 37047 INDEX index_dmsf_file_revisions_on_dmsf_file_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_dmsf_file_revisions_on_dmsf_file_id" does not exist
Command was: DROP INDEX public.index_dmsf_file_revisions_on_dmsf_file_id;
pg_restore: [archiver (db)] Error from TOC entry 2611; 1259 37030 INDEX index_agile_data_on_position postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_agile_data_on_position" does not exist
Command was: DROP INDEX public.index_agile_data_on_position;
pg_restore: [archiver (db)] Error from TOC entry 2610; 1259 37029 INDEX index_agile_data_on_issue_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_agile_data_on_issue_id" does not exist
Command was: DROP INDEX public.index_agile_data_on_issue_id;
pg_restore: [archiver (db)] Error from TOC entry 2607; 1259 37028 INDEX index_agile_colors_on_container_type postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_agile_colors_on_container_type" does not exist
Command was: DROP INDEX public.index_agile_colors_on_container_type;
pg_restore: [archiver (db)] Error from TOC entry 2606; 1259 37027 INDEX index_agile_colors_on_container_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "index_agile_colors_on_container_id" does not exist
Command was: DROP INDEX public.index_agile_colors_on_container_id;
pg_restore: [archiver (db)] Error from TOC entry 2676; 1259 37026 INDEX idx_dmsf_wfstepact_on_wfstepassign_id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: index "idx_dmsf_wfstepact_on_wfstepassign_id" does not exist
Command was: DROP INDEX public.idx_dmsf_wfstepact_on_wfstepassign_id;
pg_restore: [archiver (db)] Error from TOC entry 2843; 2606 37326 CONSTRAINT easy_baseline_sources_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.easy_baseline_sources" does not exist
Command was: ALTER TABLE ONLY public.easy_baseline_sources DROP CONSTRAINT easy_baseline_sources_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2684; 2606 36941 CONSTRAINT dmsf_workflows_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflows" does not exist
Command was: ALTER TABLE ONLY public.dmsf_workflows DROP CONSTRAINT dmsf_workflows_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2681; 2606 36939 CONSTRAINT dmsf_workflow_steps_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_steps" does not exist
Command was: ALTER TABLE ONLY public.dmsf_workflow_steps DROP CONSTRAINT dmsf_workflow_steps_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2678; 2606 36937 CONSTRAINT dmsf_workflow_step_assignments_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_step_assignments" does not exist
Command was: ALTER TABLE ONLY public.dmsf_workflow_step_assignments DROP CONSTRAINT dmsf_workflow_step_assignments_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2675; 2606 36935 CONSTRAINT dmsf_workflow_step_actions_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_step_actions" does not exist
Command was: ALTER TABLE ONLY public.dmsf_workflow_step_actions DROP CONSTRAINT dmsf_workflow_step_actions_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2672; 2606 36933 CONSTRAINT dmsf_locks_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_locks" does not exist
Command was: ALTER TABLE ONLY public.dmsf_locks DROP CONSTRAINT dmsf_locks_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2669; 2606 36931 CONSTRAINT dmsf_links_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_links" does not exist
Command was: ALTER TABLE ONLY public.dmsf_links DROP CONSTRAINT dmsf_links_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2666; 2606 36929 CONSTRAINT dmsf_folders_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_folders" does not exist
Command was: ALTER TABLE ONLY public.dmsf_folders DROP CONSTRAINT dmsf_folders_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2663; 2606 36927 CONSTRAINT dmsf_files_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_files" does not exist
Command was: ALTER TABLE ONLY public.dmsf_files DROP CONSTRAINT dmsf_files_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2660; 2606 36925 CONSTRAINT dmsf_file_revisions_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_file_revisions" does not exist
Command was: ALTER TABLE ONLY public.dmsf_file_revisions DROP CONSTRAINT dmsf_file_revisions_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2658; 2606 36923 CONSTRAINT dmsf_file_revision_accesses_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_file_revision_accesses" does not exist
Command was: ALTER TABLE ONLY public.dmsf_file_revision_accesses DROP CONSTRAINT dmsf_file_revision_accesses_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2609; 2606 36901 CONSTRAINT agile_data_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.agile_data" does not exist
Command was: ALTER TABLE ONLY public.agile_data DROP CONSTRAINT agile_data_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2605; 2606 36899 CONSTRAINT agile_colors_pkey postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.agile_colors" does not exist
Command was: ALTER TABLE ONLY public.agile_colors DROP CONSTRAINT agile_colors_pkey;
pg_restore: [archiver (db)] Error from TOC entry 2603; 2604 37321 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.easy_baseline_sources" does not exist
Command was: ALTER TABLE public.easy_baseline_sources ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2470; 2604 36428 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflows" does not exist
Command was: ALTER TABLE public.dmsf_workflows ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2469; 2604 36427 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_steps" does not exist
Command was: ALTER TABLE public.dmsf_workflow_steps ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2468; 2604 36426 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_step_assignments" does not exist
Command was: ALTER TABLE public.dmsf_workflow_step_assignments ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2467; 2604 36425 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_workflow_step_actions" does not exist
Command was: ALTER TABLE public.dmsf_workflow_step_actions ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2466; 2604 36424 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_locks" does not exist
Command was: ALTER TABLE public.dmsf_locks ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2464; 2604 36423 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_links" does not exist
Command was: ALTER TABLE public.dmsf_links ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2463; 2604 36422 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_folders" does not exist
Command was: ALTER TABLE public.dmsf_folders ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2460; 2604 36421 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_files" does not exist
Command was: ALTER TABLE public.dmsf_files ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2457; 2604 36420 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_file_revisions" does not exist
Command was: ALTER TABLE public.dmsf_file_revisions ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2453; 2604 36419 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.dmsf_file_revision_accesses" does not exist
Command was: ALTER TABLE public.dmsf_file_revision_accesses ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2403; 2604 36409 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.agile_data" does not exist
Command was: ALTER TABLE public.agile_data ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 2402; 2604 36408 DEFAULT id postgres
pg_restore: [archiver (db)] could not execute query: ERROR: relation "public.agile_colors" does not exist
Command was: ALTER TABLE public.agile_colors ALTER COLUMN id DROP DEFAULT;
pg_restore: [archiver (db)] Error from TOC entry 302; 1259 37316 SEQUENCE easy_baseline_sources_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "easy_baseline_sources_id_seq" does not exist
Command was: DROP SEQUENCE public.easy_baseline_sources_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 303; 1259 37318 TABLE easy_baseline_sources postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "easy_baseline_sources" does not exist
Command was: DROP TABLE public.easy_baseline_sources;
pg_restore: [archiver (db)] Error from TOC entry 228; 1259 36024 SEQUENCE dmsf_workflows_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_workflows_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_workflows_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 227; 1259 36017 TABLE dmsf_workflows postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_workflows" does not exist
Command was: DROP TABLE public.dmsf_workflows;
pg_restore: [archiver (db)] Error from TOC entry 226; 1259 36015 SEQUENCE dmsf_workflow_steps_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_workflow_steps_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_workflow_steps_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 225; 1259 36012 TABLE dmsf_workflow_steps postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_workflow_steps" does not exist
Command was: DROP TABLE public.dmsf_workflow_steps;
pg_restore: [archiver (db)] Error from TOC entry 224; 1259 36010 SEQUENCE dmsf_workflow_step_assignments_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_workflow_step_assignments_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_workflow_step_assignments_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 223; 1259 36007 TABLE dmsf_workflow_step_assignments postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_workflow_step_assignments" does not exist
Command was: DROP TABLE public.dmsf_workflow_step_assignments;
pg_restore: [archiver (db)] Error from TOC entry 222; 1259 36005 SEQUENCE dmsf_workflow_step_actions_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_workflow_step_actions_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_workflow_step_actions_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 221; 1259 35999 TABLE dmsf_workflow_step_actions postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_workflow_step_actions" does not exist
Command was: DROP TABLE public.dmsf_workflow_step_actions;
pg_restore: [archiver (db)] Error from TOC entry 220; 1259 35997 SEQUENCE dmsf_locks_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_locks_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_locks_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 219; 1259 35994 TABLE dmsf_locks postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_locks" does not exist
Command was: DROP TABLE public.dmsf_locks;
pg_restore: [archiver (db)] Error from TOC entry 218; 1259 35992 SEQUENCE dmsf_links_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_links_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_links_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 217; 1259 35985 TABLE dmsf_links postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_links" does not exist
Command was: DROP TABLE public.dmsf_links;
pg_restore: [archiver (db)] Error from TOC entry 216; 1259 35983 SEQUENCE dmsf_folders_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_folders_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_folders_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 215; 1259 35975 TABLE dmsf_folders postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_folders" does not exist
Command was: DROP TABLE public.dmsf_folders;
pg_restore: [archiver (db)] Error from TOC entry 214; 1259 35973 SEQUENCE dmsf_files_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_files_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_files_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 213; 1259 35965 TABLE dmsf_files postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_files" does not exist
Command was: DROP TABLE public.dmsf_files;
pg_restore: [archiver (db)] Error from TOC entry 212; 1259 35963 SEQUENCE dmsf_file_revisions_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_file_revisions_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_file_revisions_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 211; 1259 35955 TABLE dmsf_file_revisions postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_file_revisions" does not exist
Command was: DROP TABLE public.dmsf_file_revisions;
pg_restore: [archiver (db)] Error from TOC entry 210; 1259 35953 SEQUENCE dmsf_file_revision_accesses_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "dmsf_file_revision_accesses_id_seq" does not exist
Command was: DROP SEQUENCE public.dmsf_file_revision_accesses_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 209; 1259 35949 TABLE dmsf_file_revision_accesses postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "dmsf_file_revision_accesses" does not exist
Command was: DROP TABLE public.dmsf_file_revision_accesses;
pg_restore: [archiver (db)] Error from TOC entry 184; 1259 35814 SEQUENCE agile_data_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "agile_data_id_seq" does not exist
Command was: DROP SEQUENCE public.agile_data_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 183; 1259 35811 TABLE agile_data postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "agile_data" does not exist
Command was: DROP TABLE public.agile_data;
pg_restore: [archiver (db)] Error from TOC entry 182; 1259 35809 SEQUENCE agile_colors_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR: sequence "agile_colors_id_seq" does not exist
Command was: DROP SEQUENCE public.agile_colors_id_seq;
pg_restore: [archiver (db)] Error from TOC entry 181; 1259 35803 TABLE agile_colors postgres
pg_restore: [archiver (db)] could not execute query: ERROR: table "agile_colors" does not exist
Command was: DROP TABLE public.agile_colors;
WARNING: errors ignored on restore: 69
これで Redmine を再起動する。 以前と同じチケットが表示されたら、移行は完了。めでたし、めでたし。
$ docker-compose down
$ docker-compose up -d
6. Redmine のサービス化
ここまでで docker-compose
を使って Redmine を起動できた。
しかし一晩経つと勝手にコンテナを終了してしまうことが判明した。
どうやらルート権限で起動していると終了しないが、ユーザ権限では駄目な模様。
Podman 自体がデーモンレスなので、コマンドだけ docker-compose
を使ったところで止められてしまうようだ。
6.1. Podman Compose のユニットファイル作成
Systemd にサービスとして登録すれば常時起動させることができる。 ここで Podman Compose を利用する。 Podman Compose には、docker-compose.yml に従い Pods を生成、さらに Systemd のユニットファイルを作成する便利な機能がある。
podman-compose
をインストールするために Pip が必要:
$ sudo su -
# dnf install python3-pip
# exit
podman-compose
をインストール:
# pip3 install podman-compose
Collecting podman-compose
Using cached podman_compose-1.0.6-py2.py3-none-any.whl (34 kB)
Requirement already satisfied: pyyaml in /usr/lib64/python3.9/site-packages (from podman-compose) (5.4.1)
Requirement already satisfied: python-dotenv in /usr/local/lib/python3.9/site-packages (from podman-compose) (1.0.0)
Installing collected packages: podman-compose
Successfully installed podman-compose-1.0.6
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
Podman Compose のユニットファイルを作成。 Pod を起動するユニットファイルの基本になる。これはルート権限で行う必要がある:
# podman-compose systemd -a create-unit
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 4.4.1
writing [/etc/systemd/user/podman-compose@.service]: ...
writing [/etc/systemd/user/podman-compose@.service]: done.
while in your project type `podman-compose systemd -a register`
# exit
6.2. Redmine Pod のユニットファイル登録
ここからは再びユーザ権限で操作する。 ユーザ向けにも Podman Compose をインストール:
$ pip3 install podman-compose
docker-compose.yml
の内容で Redmine Pod を生成。
Pod とは先述の通り、複数コンテナをまとめたものである。
podman-compose systemd -a register
で Pod 生成だけでなく Systemd へ登録してくれる。
当然 docker-compose.yml
の置いてあるディレクトリでコマンドを実行する:
$ podman-compose systemd -a register
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 4.4.1
writing [/home/alma/.config/containers/compose/projects/redmine.env]: ...
writing [/home/alma/.config/containers/compose/projects/redmine.env]: done.
creating the pod without starting it: ...
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 4.4.1
** excluding: set()
['podman', 'ps', '--filter', 'label=io.podman.compose.project=redmine', '-a', '--format', '']
podman volume inspect redmine_certbot || podman volume create redmine_certbot
['podman', 'volume', 'inspect', 'redmine_certbot']
['podman', 'network', 'exists', 'redmine_default']
podman create --name=redmine_certbot_1 --label io.podman.compose.config-hash=3092854c4b61817d29f8e447c6d1a0f169e19c51c5ff2dae715d109ad8e3fc3e --label io.podman.compose.project=redmine --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@redmine.service --label com.docker.compose.project=redmine --label com.docker.compose.project.working_dir=/home/alma/redmine --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=certbot -v /home/alma/redmine/data/letsencrypt:/etc/letsencrypt -v redmine_certbot:/var/www/certbot --net redmine_default --network-alias certbot --restart always --entrypoint ["/bin/sh", "-c", "trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait ${!}; done;"] certbot/certbot
cbecc79821ef0751c8889abd171be3f6add8188167f2124d4493566fa7ad3b0c
exit code: 0
podman volume inspect redmine_certbot || podman volume create redmine_certbot
['podman', 'volume', 'inspect', 'redmine_certbot']
['podman', 'network', 'exists', 'redmine_default']
podman create --name=redmine_nginx_1 --label io.podman.compose.config-hash=3092854c4b61817d29f8e447c6d1a0f169e19c51c5ff2dae715d109ad8e3fc3e --label io.podman.compose.project=redmine --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@redmine.service --label com.docker.compose.project=redmine --label com.docker.compose.project.working_dir=/home/alma/redmine --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=nginx -v /home/alma/redmine/data/nginx/conf:/etc/nginx/conf.d -v /home/alma/redmine/data/nginx/ssl:/etc/ssl/private -v /home/alma/redmine/data/letsencrypt:/etc/letsencrypt -v redmine_certbot:/var/www/letsencrypt --net redmine_default --network-alias nginx -p 80:80 -p 443:443 --restart always nginx:1-alpine /bin/sh -c while :; do sleep 6h & wait ${!}; nginx -s reload; done & nginx -g "daemon off;"
5ceaa3c1f4391c2df34fc38561b2acf34fe5463fa8bd319f634d4f572213136e
exit code: 0
['podman', 'network', 'exists', 'redmine_default']
podman create --name=redmine_redmine_1 --label io.podman.compose.config-hash=3092854c4b61817d29f8e447c6d1a0f169e19c51c5ff2dae715d109ad8e3fc3e --label io.podman.compose.project=redmine --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@redmine.service --label com.docker.compose.project=redmine --label com.docker.compose.project.working_dir=/home/alma/redmine --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=redmine -e REDMINE_DB_POSTGRES=db -e REDMINE_DB_DATABASE=redmine -e REDMINE_DB_USERNAME=postgres -e REDMINE_DB_PASSWORD=hyc96br1askf -v /home/alma/redmine/data/redmine/conf/configuration.yml:/usr/src/redmine/config/configuration.yml -v /home/alma/redmine/data/redmine/files:/usr/src/redmine/files -v /home/alma/redmine/data/redmine/plugins:/usr/src/redmine/plugins -v /home/alma/redmine/data/redmine/themes/bleuclair:/usr/src/redmine/public/themes/bleuclair --net redmine_default --network-alias redmine --restart always redmine:5.0.5-alpine
efa924520752682e46537dfb9f7b4b0eb8021353c7ddc1991fcbf868b4894c25
exit code: 0
podman volume inspect redmine_db-data || podman volume create redmine_db-data
['podman', 'volume', 'inspect', 'redmine_db-data']
['podman', 'network', 'exists', 'redmine_default']
podman create --name=redmine_db_1 --label io.podman.compose.config-hash=3092854c4b61817d29f8e447c6d1a0f169e19c51c5ff2dae715d109ad8e3fc3e --label io.podman.compose.project=redmine --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@redmine.service --label com.docker.compose.project=redmine --label com.docker.compose.project.working_dir=/home/alma/redmine --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=db -e POSTGRES_DB=redmine -e POSTGRES_PASSWORD=hyc96br1askf -v redmine_db-data:/var/lib/postgresql/data -v /home/alma/redmine/backup/db:/backup --net redmine_default --network-alias db --restart always postgres:9.5-alpine
fe430ad70d25ceb813e9435a7af986d1ce2a6aa793e6a9c383a3447742cf1aa7
exit code: 0
final exit code is 0
you can use systemd commands like enable, start, stop, status, cat
all without `sudo` like this:
systemctl --user enable --now 'podman-compose@redmine'
systemctl --user status 'podman-compose@redmine'
journalctl --user -xeu 'podman-compose@redmine'
and for that to work outside a session
you might need to run the following command *once*
sudo loginctl enable-linger 'alma'
you can use podman commands like:
podman pod ps
podman pod stats 'pod_redmine'
podman pod logs --tail=10 -f 'pod_redmine'
なんか色々と自動的に進めてくれたようだ。
しかしこのままではうまく起動しない。
podman-commpose\@.service
を編集し、--in-pod 1
を追加した。
既に Issue が出ているので、きっと近い内に直ると思う。
変更後のユニットファイル:
$ cat /etc/xdg/systemd/user/podman-compose\@.service
# /etc/systemd/user/podman-compose@.service
[Unit]
Description=%i rootless pod (podman-compose)
[Service]
Type=simple
EnvironmentFile=%h/.config/containers/compose/projects/%i.env
ExecStartPre=-/usr/local/bin/podman-compose --in-pod 1 up --no-start
ExecStartPre=/usr/bin/podman pod start pod_%i
ExecStart=/usr/local/bin/podman-compose wait
ExecStop=/usr/bin/podman pod stop pod_%i
[Install]
WantedBy=default.target
変更の差分:
$ diff -u /tmp/podman-compose.service /etc/xdg/systemd/user/podman-compose\@.service
--- /tmp/podman-compose.service 2023-09-28 18:43:23.705503890 +0000
+++ /etc/xdg/systemd/user/podman-compose@.service 2023-09-28 18:39:54.297475319 +0000
@@ -6,7 +6,7 @@
[Service]
Type=simple
EnvironmentFile=%h/.config/containers/compose/projects/%i.env
-ExecStartPre=-/usr/local/bin/podman-compose up --no-start
+ExecStartPre=-/usr/local/bin/podman-compose --in-pod 1 up --no-start
ExecStartPre=/usr/bin/podman pod start pod_%i
ExecStart=/usr/local/bin/podman-compose wait
ExecStop=/usr/bin/podman pod stop pod_%i
変更を適用するにはお馴染 daemon-reload
が必要:
$ systemctl --user daemon-reload
6.3. Redmine Pod の起動
これで準備は整った。Systemctl で Pod を有効化する:
$ systemctl --user enable --now 'podman-compose@redmine'
起動できたみたいだ!!
$ systemctl --no-pager --full --user status 'podman-compose@redmine.service'
● podman-compose@redmine.service - redmine rootless pod (podman-compose)
Loaded: loaded (/etc/xdg/systemd/user/podman-compose@.service; enabled; preset: disabled)
Active: active (running) since Thu 2023-09-28 18:40:57 UTC; 6min ago
Main PID: 164783 (podman)
Tasks: 7 (limit: 5637)
Memory: 32.8M
CPU: 3.206s
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/app-podman\x2dcompose.slice/podman-compose@redmine.service
└─164783 podman wait -- redmine_certbot_1 redmine_nginx_1 redmine_redmine_1 redmine_db_1
Sep 28 18:40:56 fg-indigo2 podman-compose[164701]: ['podman', 'network', 'exists', 'redmine_default']
Sep 28 18:40:56 fg-indigo2 podman-compose[164701]: podman create --name=redmine_db_1 --pod=pod_redmine --label io.podman.compose.config-hash=3092854c4b61817d29f8e447c6d1a0f169e19c51c5ff2dae715d109ad8e3fc3e --label io.podman.compose.project=redmine --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@redmine.service --label com.docker.compose.project=redmine --label com.docker.compose.project.working_dir=/home/alma/redmine --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=db -e POSTGRES_DB=redmine -e POSTGRES_PASSWORD=hyc96br1askf -v redmine_db-data:/var/lib/postgresql/data -v /home/alma/redmine/backup/db:/backup --net redmine_default --network-alias db --restart always postgres:9.5-alpine
Sep 28 18:40:56 fg-indigo2 podman-compose[164771]: Error: creating container storage: the container name "redmine_db_1" is already in use by b5dcabc6bc8ed2124e9822a5f14db90868a69156d8f0af2a77a3058a474ab435. You have to remove that container to be able to reuse that name: that name is already in use
Sep 28 18:40:56 fg-indigo2 podman-compose[164701]: exit code: 125
Sep 28 18:40:57 fg-indigo2 podman[164777]: 1a3e7d4c10caa60ffcc6d0b441ded2d75481b7584d0d7e008ffb9c2d433e8a09
Sep 28 18:40:57 fg-indigo2 systemd[143293]: Started redmine rootless pod (podman-compose).
Sep 28 18:40:57 fg-indigo2 podman-compose[164783]: podman-compose version: 1.0.6
Sep 28 18:40:57 fg-indigo2 podman-compose[164783]: ['podman', '--version', '']
Sep 28 18:40:57 fg-indigo2 podman-compose[164783]: using podman version: 4.4.1
Sep 28 18:40:57 fg-indigo2 podman-compose[164783]: podman wait -- redmine_certbot_1 redmine_nginx_1 redmine_redmine_1 redmine_db_1
あとは布団に入るだけ。目が覚めても Redmine にアクセス可能であれば、構築は成功だ。
8. まとめ
旅行へ行く直前に作業したので、常時起動できるようになるのが間に合って良かった。 勿論、旅行中も Redmine には存分に活躍して頂いた。
文中で「ダグトリオみたいなキャラクタ」と書いたが、カラーで見るとアザラシのように見える。 本当はセルキーという、アイルランドの人魚的な存在らしい。 普段、海ではアザラシの皮を被っていて、陸にあがるときに人間の姿になるとのこと。 セルキーのグループを Pod と呼ぶそうな。ということはセルキーはコンテナなのか…?
9. 参考リンク
Redmine
Certbot
Podman
- What is Podman?
- Getting Started with Podman - Podman
- 【Podman v3】ルートレスモードでdocker-composeを実行する - 赤帽エンジニアブログ
- Podman4でDocker Composeを使う方法: ポッドマンが倒せない(8)
- Podmanでのファイル作成の使用
- Podmanで遭遇したトラブルシューティング - Qiita
- GitHub - containers/podman-compose: a script to run docker-compose.yml using podman
- Podman Compose Systemd registers an unusable service · Issue #753 · containers/podman-compose · GitHub Podmanをコンテナ内で動かす「Podman in Podman」の2つのポイント - 赤帽エンジニアブログ