Chainguard Container for liquibase
Liquibase is a database schema change management solution that enables you to revise and release database changes faster and safer from development to production.
Chainguard Containers are regularly-updated, secure-by-default container images.
Download this Container Image
For those with access, this container image is available on cgr.dev
:
docker pull cgr.dev/ORGANIZATION/liquibase:latest
Be sure to replace the ORGANIZATION
placeholder with the name used for your organization's private repository within the Chainguard Registry.
Compatibility Notes
The Liquibase Chainguard image is meant to serve as a drop-in replacement for the Liquibase Image on DockerHub. Like most Chainguard images, this image is minimal and has few-to-zero CVEs and does not run as the root user.
Getting Started
To begin, start the Liquibase container with a command like the following:
docker run --rm cgr.dev/ORGANIZATION/liquibase
This will return Liquibase's command-line usage instructions.
Next, create the first changelog file:
cat <<EOF > /tmp/liquibase/changelogs/example-changelog.sql
--liquibase formatted sql
--changeset your.name:1 labels:example-label context:example-context
--comment: example comment
create table person (
id integer primary key autoincrement not null,
name varchar(50) not null,
address1 varchar(50),
address2 varchar(50),
city varchar(30)
)
--rollback DROP TABLE person;
--changeset your.name:2 labels:example-label context:example-context
--comment: example comment
create table company (
id integer primary key autoincrement not null,
name varchar(50) not null,
address1 varchar(50),
address2 varchar(50),
city varchar(30)
)
--rollback DROP TABLE company;
--changeset other.dev:3 labels:example-label context:example-context
--comment: example comment
alter table person add column country varchar(2)
--rollback ALTER TABLE person DROP COLUMN country;
EOF
This example assumes that you have a SQLite database named test_db.sqlite3
in the /tmp/liquibase/db
directory.
Next, ensure the following Liquibase environment variables are set:
LIQUIBASE_COMMAND_URL=jdbc:sqlite:/tmp/liquibase/db/test_db.sqlite3
LIQUIBASE_SEARCH_PATH=/liquibase/changelogs
LIQUIBASE_COMMAND_URL
sets the JDBC Connection URL that will be used to establish a connection between Liquibase and your database.
LIQUIBASE_SEARCH_PATH
sets the search location Liquibase will use to find any changelog files to apply to your database.
Finally, run the migration:
docker run --rm -v "/tmp/liquibase/db:/liquibase/db" \
-v "/tmp/liquibase/changelogs:/liquibase/changelogs" \
-e LIQUIBASE_COMMAND_URL=jdbc:sqlite:/liquibase/db/test_db.sqlite3 \
-e LIQUIBASE_SEARCH_PATH=/liquibase/changelogs \
cgr.dev/ORGANIZATION/liquibase liquibase update --changelog-file=example-changelog.sql
If everything worked as expected, you will receive the following output:
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## ##
####################################################
Starting Liquibase at 17:57:14 using Java 17.0.14-internal (version 4.31.1 #0 built at 2025-03-13 23:48+0000)
Liquibase Version: 4.31.1
WARNING: License service not loaded, cannot determine Liquibase Pro license status. Please consider re-installing Liquibase to include all dependencies. Continuing operation without Pro license.
Running Changeset: example-changelog.sql::1::your.name
Running Changeset: example-changelog.sql::2::your.name
Running Changeset: example-changelog.sql::3::other.dev
UPDATE SUMMARY
Run: 3
Previously run: 0
Filtered out: 0
-------------------------------
Total change sets: 3
Liquibase: Update has been successful. Rows affected: 6
Liquibase command 'update' was executed successfully.
Liquibase with Kubernetes
Kubernetes is often a common choice for deploying and managing containerized applications.
Liquibase can be integrated with Kubernetes by embedding Liquibase into the startup process of an application with initContainers or through a Kubernetes Job process.
To kick things off, create the changelog file:
cat <<EOF > /tmp/liquibase/changelogs/example-changelog-mariademo.sql
--liquibase formatted sql
--changeset your.name:1 labels:example-label context:example-context
--comment: example comment
create table person (
id integer primary key auto_increment not null,
name varchar(50) not null,
address1 varchar(50),
address2 varchar(50),
city varchar(30)
)
--rollback DROP TABLE person;
--changeset your.name:2 labels:example-label context:example-context
--comment: example comment
create table company (
id integer primary key auto_increment not null,
name varchar(50) not null,
address1 varchar(50),
address2 varchar(50),
city varchar(30)
)
--rollback DROP TABLE company;
--changeset other.dev:3 labels:example-label context:example-context
--comment: example comment
alter table person add column country varchar(2)
--rollback ALTER TABLE person DROP COLUMN country;
EOF
Next create a ConfigMap using the changelog file as the source:
kubectl create configmap liquibase-changelog --from-file=/tmp/liquibase/changelogs/
Following that, create the liquibase job manifest:
apiVersion: batch/v1
kind: Job
metadata:
name: liquibase-mariadb-demo
spec:
template:
spec:
containers:
- name: liquibase
image: cgr.dev/ORGANIZATION/liquibase
command: ["liquibase", "update", "--username=$(DATABASE_USERNAME)", "--password=$(DATABASE_PASSWORD)", "--changelog-file=example-changelog-mariademo.sql"]
env:
- name: LIQUIBASE_SEARCH_PATH
value: /liquibase/test/changelogs
- name: LIQUIBASE_COMMAND_URL
value: "$MARIADB_JDBC_URL"
- name: DATABASE_USERNAME
value: "$MARIADB_USER"
- name: DATABASE_PASSWORD
value: "$MARIADB_PASS"
volumeMounts:
- name: liquibase-changelog-volume
mountPath: /liquibase/test/changelogs
volumes:
- name: liquibase-changelog-volume
configMap:
name: liquibase-changelog
restartPolicy: Never
backoffLimit: 0
If everything worked as expected, your output should be similar to the following:
kubectl get pods
NAME READY STATUS RESTARTS AGE
liquibase-mariadb-demo-qg9nx 0/1 Completed 0 4s
mariadb-0 1/1 Running 0 10m
mariadb-operator-8644965c85-88gdr 1/1 Running 1 (171m ago) 4d12h
mariadb-operator-cert-controller-5d6bb78b65-c7b5g 1/1 Running 1 (171m ago) 4d12h
mariadb-operator-webhook-586d988ddf-jwwln 1/1 Running 1 (171m ago) 4d12h
kubectl logs liquibase-mariadb-demo-qg9nx
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## ##
####################################################
Starting Liquibase at 18:57:03 using Java 17.0.14-internal (version 4.31.1 #0 built at 2025-03-13 23:48+0000)
Liquibase Version: 4.31.1
WARNING: License service not loaded, cannot determine Liquibase Pro license status. Please consider re-installing Liquibase to include all dependencies. Continuing operation without Pro license.
Running Changeset: example-changelog-mariademo.sql::1::your.name
Running Changeset: example-changelog-mariademo.sql::2::your.name
Running Changeset: example-changelog-mariademo.sql::3::other.dev
UPDATE SUMMARY
Run: 3
Previously run: 0
Filtered out: 0
-------------------------------
Total change sets: 3
Liquibase: Update has been successful. Rows affected: 3
Liquibase command 'update' was executed successfully.
Documentation and Resources
What are Chainguard Containers?
Chainguard Containers are minimal container images that are secure by default.
In many cases, the Chainguard Containers tagged as :latest
contain only an open-source application and its runtime dependencies. These minimal container images typically do not contain a shell or package manager. Chainguard Containers are built with Wolfi, our Linux undistro designed to produce container images that meet the requirements of a more secure software supply chain.
The main features of Chainguard Containers include:
For cases where you need container images with shells and package managers to build or debug, most Chainguard Containers come paired with a -dev
variant.
Although the -dev
container image variants have similar security features as their more minimal versions, they feature additional software that is typically not necessary in production environments. We recommend using multi-stage builds to leverage the -dev
variants, copying application artifacts into a final minimal container that offers a reduced attack surface that won’t allow package installations or logins.
Learn More
To better understand how to work with Chainguard Containers, please visit Chainguard Academy and Chainguard Courses.
In addition to Containers, Chainguard offers VMs and Libraries. Contact Chainguard to access additional products.
Trademarks
This software listing is packaged by Chainguard. The trademarks set forth in this offering are owned by their respective companies, and use of them does not imply any affiliation, sponsorship, or endorsement by such companies.