Skip to content

Commit dbb2bc8

Browse files
feat(mariadb): add custom MariaDB app container and align build/test wiring (#1183)
The retry work on `build-mariadb-container` required introducing a first-class `apps/mariadb` target instead of relying on porting artifacts. This PR adds the MariaDB app surface in `apps/` and aligns build/test behavior with current base-image and rootless-runtime expectations. - **App surface added (`apps/mariadb`)** - Added `Dockerfile`, `docker-bake.hcl`, `start.sh`, defaults, logrotate config, and container smoke test. - This makes MariaDB buildable/releasable through the standard app pipeline. - **Docker build semantics corrected for Ubuntu package source** - Removed broken strict version pinning for MariaDB apt packages in the new app Dockerfile. - Kept the image version tag in bake metadata while decoupling it from apt package pinning. - **Bake args cleaned to match Dockerfile usage** - Removed unused `VERSION` build arg passthrough in `apps/mariadb/docker-bake.hcl` since the Dockerfile no longer consumes it directly. - **Rootless test mount behavior fixed** - Updated `apps/mariadb/container_test.go` to create a writable temp config mount for UID/GID `apps`, avoiding permission failures during DB initialization and cleanup. ```dockerfile RUN apt-get update && \ apt-get install -y --no-install-recommends \ logrotate \ mariadb-server \ mariadb-backup \ mariadb-client \ mariadb-common \ mariadb-server-core ``` <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/trueforge-org/containerforge/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PrivatePuffin <7613738+PrivatePuffin@users.noreply.github.com>
1 parent a0ed683 commit dbb2bc8

6 files changed

Lines changed: 540 additions & 0 deletions

File tree

apps/mariadb/Dockerfile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
FROM ghcr.io/trueforge-org/ubuntu:24.4@sha256:0628c88c702e66783b5565dadf138d0f878ee3c5e8ef8fc7c52b28224ae4d174
3+
4+
# set version label
5+
ARG TARGETARCH
6+
USER root
7+
8+
# environment variables
9+
ENV MYSQL_DIR="/config"
10+
ENV DATADIR="$MYSQL_DIR/databases"
11+
12+
RUN \
13+
echo "**** install runtime packages ****" && \
14+
apt-get update && \
15+
apt-get install -y --no-install-recommends \
16+
logrotate \
17+
mariadb-server \
18+
mariadb-backup \
19+
mariadb-client \
20+
mariadb-common \
21+
mariadb-server-core && \
22+
echo "**** cleanup ****" && \
23+
apt-get clean && \
24+
rm -rf \
25+
/var/lib/apt/lists/* \
26+
/tmp/* \
27+
$HOME/.cache
28+
29+
# copy local files
30+
USER apps
31+
COPY . /
32+
COPY ./root /
33+
34+
# ports and volumes
35+
EXPOSE 3306
36+
37+
VOLUME /config
38+
39+
WORKDIR /config

apps/mariadb/container_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/testcontainers/testcontainers-go"
11+
"github.com/testcontainers/testcontainers-go/wait"
12+
)
13+
14+
func Test(t *testing.T) {
15+
ctx := context.Background()
16+
17+
appName := os.Getenv("APP")
18+
require.NotEmpty(t, appName, "APP environment variable must be set")
19+
image := os.Getenv("TEST_IMAGE")
20+
if image == "" {
21+
image = "ghcr.io/trueforge-org/" + appName + ":rolling"
22+
}
23+
24+
configDir, err := os.MkdirTemp("", "mariadb-test-*")
25+
require.NoError(t, err)
26+
t.Cleanup(func() { _ = os.RemoveAll(configDir) })
27+
require.NoError(t, os.Chmod(configDir, 0o777))
28+
29+
app, err := testcontainers.Run(
30+
ctx, image,
31+
testcontainers.WithMounts(
32+
testcontainers.BindMount(configDir, testcontainers.ContainerMountTarget("/config")),
33+
),
34+
testcontainers.WithExposedPorts("3306/tcp"),
35+
testcontainers.WithWaitStrategy(
36+
wait.ForListeningPort("3306/tcp"),
37+
),
38+
)
39+
testcontainers.CleanupContainer(t, app)
40+
require.NoError(t, err)
41+
}

apps/mariadb/docker-bake.hcl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
target "docker-metadata-action" {}
2+
3+
variable "APP" {
4+
default = "mariadb"
5+
}
6+
7+
variable "VERSION" {
8+
default = "11.4.8-r0"
9+
}
10+
11+
variable "LICENSE" {
12+
default = "AGPL-3.0-or-later"
13+
}
14+
15+
variable "SOURCE" {
16+
default = "https://mariadb.org/"
17+
}
18+
19+
group "default" {
20+
targets = ["image-local"]
21+
}
22+
23+
target "image" {
24+
inherits = ["docker-metadata-action"]
25+
labels = {
26+
"org.opencontainers.image.source" = "${SOURCE}"
27+
"org.opencontainers.image.licenses" = "${LICENSE}"
28+
}
29+
}
30+
31+
target "image-local" {
32+
inherits = ["image"]
33+
output = ["type=docker"]
34+
tags = ["${APP}:${VERSION}"]
35+
}
36+
37+
target "image-all" {
38+
inherits = ["image"]
39+
platforms = [
40+
"linux/amd64",
41+
"linux/arm64"
42+
]
43+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
## custom configuration file based on https://github.com/just-containers/mariadb/blob/master/rootfs/etc/mysql/my.cnf
2+
## please be aware that changing options here may break things
3+
#
4+
# The MySQL database server configuration file.
5+
#
6+
# One can use all long options that the program supports.
7+
# Run program with --help to get a list of available options and with
8+
# --print-defaults to see which it would actually understand and use.
9+
#
10+
# For explanations see
11+
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
12+
13+
# This will be passed to all mysql clients
14+
# It has been reported that passwords should be enclosed with ticks/quotes
15+
# especially if they contain "#" chars...
16+
[client]
17+
port = 3306
18+
socket = /run/mysqld/mysqld.sock
19+
20+
default-character-set = utf8mb4
21+
22+
# Here is entries for some specific programs
23+
# The following values assume you have at least 32M ram
24+
25+
# This was formally known as [safe_mysqld]. Both versions are currently parsed.
26+
[mysqld_safe]
27+
socket = /run/mysqld/mysqld.sock
28+
nice = 0
29+
30+
[mysqld]
31+
#
32+
# * Basic Settings
33+
#
34+
user = apps
35+
pid-file = /run/mysqld/mysqld.pid
36+
socket = /run/mysqld/mysqld.sock
37+
port = 3306
38+
basedir = /usr
39+
datadir = /var/lib/mysql
40+
tmpdir = /tmp
41+
lc_messages_dir = /usr/share/mariadb
42+
lc_messages = en_US
43+
skip-external-locking
44+
#
45+
# Instead of skip-networking the default is now to listen only on
46+
# localhost which is more compatible and is not less secure.
47+
#bind-address = 127.0.0.1
48+
#
49+
# * Fine Tuning
50+
#
51+
key_buffer_size = 128M
52+
max_connections = 100
53+
connect_timeout = 5
54+
wait_timeout = 600
55+
max_allowed_packet = 16M
56+
thread_cache_size = 128
57+
thread_stack = 192K
58+
sort_buffer_size = 4M
59+
bulk_insert_buffer_size = 16M
60+
tmp_table_size = 32M
61+
max_heap_table_size = 32M
62+
63+
#performance_schema = on
64+
character_set_server = utf8mb4
65+
collation_server = utf8mb4_general_ci
66+
transaction_isolation = READ-COMMITTED
67+
binlog_format = MIXED
68+
69+
#
70+
# * MyISAM
71+
#
72+
# This replaces the startup script and checks MyISAM tables if needed
73+
# the first time they are touched. On error, make copy and try a repair.
74+
myisam-recover-options = BACKUP
75+
#open-files-limit = 2000
76+
table_open_cache = 400
77+
#table_cache = 64
78+
#thread_concurrency = 10
79+
myisam_sort_buffer_size = 512M
80+
concurrent_insert = 2
81+
read_buffer_size = 2M
82+
read_rnd_buffer_size = 1M
83+
#
84+
# * Query Cache Configuration
85+
#
86+
# Cache only tiny result sets, so we can fit more in the query cache.
87+
query_cache_limit = 128K
88+
query_cache_size = 64M
89+
# for more write intensive setups, set to DEMAND or OFF
90+
query_cache_type = DEMAND
91+
#
92+
# * Logging and Replication
93+
#
94+
console = 1
95+
# Both location gets rotated by the cronjob.
96+
# Be aware that this log type is a performance killer.
97+
# As of 5.1 you can enable the log at runtime!
98+
#general_log = 1
99+
#general_log_file = /config/log/mysql/mysql.log
100+
#
101+
# Error log - should be very few entries.
102+
#
103+
log_warnings = 2
104+
# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf
105+
log_error = /config/log/mysql/mariadb-error.log
106+
#
107+
# Enable the slow query log to see queries with especially long duration
108+
slow_query_log = 1
109+
slow_query_log_file = /config/log/mysql/mariadb-slow.log
110+
long_query_time = 5
111+
#log_slow_rate_limit = 1000
112+
#log-queries-not-using-indexes
113+
#log_slow_admin_statements
114+
#
115+
# The following can be used as easy to replay backup logs or for replication.
116+
# note: if you are setting up a replication slave, see
117+
# https://mariadb.com/kb/en/setting-up-replication/
118+
# about other settings you may need to change.
119+
#server-id = 1
120+
#report_host = master1
121+
#auto_increment_increment = 2
122+
#auto_increment_offset = 1
123+
log_bin = /config/log/mysql/mariadb-bin
124+
log_bin_index = /config/log/mysql/mariadb-bin.index
125+
# not fab for performance, but safer
126+
#sync_binlog = 1
127+
#binlog_do_db = include_database_name
128+
#binlog_ignore_db = include_database_name
129+
expire_logs_days = 10
130+
max_binlog_size = 100M
131+
# slaves
132+
#relay_log = /config/log/mysql/relay-bin
133+
#relay_log_index = /config/log/mysql/relay-bin.index
134+
#relay_log_info_file = /config/log/mysql/relay-bin.info
135+
#log_slave_updates
136+
#read_only
137+
#
138+
# If applications support it, this stricter sql_mode prevents some
139+
# mistakes like inserting invalid dates etc.
140+
#sql_mode = NO_ENGINE_SUBSTITUTION,TRADITIONAL
141+
#
142+
# * InnoDB
143+
#
144+
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
145+
# Read the manual for more InnoDB related options. There are many!
146+
default_storage_engine = InnoDB
147+
# you can't just change log file size, requires special procedure
148+
#innodb_log_file_size = 50M
149+
innodb_buffer_pool_size = 256M
150+
innodb_log_buffer_size = 8M
151+
innodb_file_per_table = 1
152+
innodb_open_files = 400
153+
innodb_io_capacity = 400
154+
innodb_flush_method = O_DIRECT
155+
#
156+
# * Security Features
157+
#
158+
# Read the manual, too, if you want chroot!
159+
# chroot = /var/lib/mysql/
160+
#
161+
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
162+
#
163+
# ssl-ca=/etc/mysql/cacert.pem
164+
# ssl-cert=/etc/mysql/server-cert.pem
165+
# ssl-key=/etc/mysql/server-key.pem
166+
167+
[mysqldump]
168+
quick
169+
quote-names
170+
max_allowed_packet = 16M
171+
172+
[mysql]
173+
#no-auto-rehash # faster start of mysql but no tab completion
174+
175+
[isamchk]
176+
key_buffer = 16M
177+
178+
#
179+
# * Galera-related settings
180+
#
181+
[galera]
182+
# Mandatory settings
183+
#wsrep_on=ON
184+
#wsrep_provider=
185+
#wsrep_cluster_address=
186+
#binlog_format=MIXED
187+
#default_storage_engine=InnoDB
188+
#innodb_autoinc_lock_mode=2
189+
#
190+
# Allow server to accept connections on all interfaces.
191+
#
192+
#bind-address=0.0.0.0
193+
#
194+
# Optional setting
195+
#wsrep_slave_threads=1
196+
#innodb_flush_log_at_trx_commit=0
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/config/log/mysql/*.log {
2+
firstaction
3+
/usr/bin/mariadb-admin -uroot --local version >/dev/null 2>&1
4+
endscript
5+
su apps apps
6+
missingok
7+
create 660 apps apps
8+
notifempty
9+
daily
10+
minsize 1M
11+
maxsize 100M
12+
rotate 30
13+
dateext
14+
dateformat .%Y-%m-%d-%H-%M-%S
15+
compress
16+
delaycompress
17+
sharedscripts
18+
olddir archive/
19+
createolddir 770 apps apps
20+
postrotate
21+
/usr/bin/mariadb-admin -uroot --local flush-error-log flush-engine-log flush-general-log flush-slow-log
22+
endscript
23+
}

0 commit comments

Comments
 (0)