Next: , Up: Guix System Containers   [Contents][Index]


4.2.1 A Database Container

A good example might be a PostgreSQL database server. Much of the complexity of setting up such a database server is encapsulated in this deceptively short service declaration:

(service postgresql-service-type
         (postgresql-configuration
          (postgresql postgresql-14)))

A complete operating system declaration for use with a Guix System container would look something like this:

(use-modules (gnu))
(use-package-modules databases)
(use-service-modules databases)

(operating-system
  (host-name "container")
  (timezone "Europe/Berlin")
  (file-systems (cons (file-system
                        (device (file-system-label "does-not-matter"))
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))
  (bootloader (bootloader-configuration
               (bootloader grub-bootloader)
               (targets '("/dev/sdX"))))
  (services
   (cons* (service postgresql-service-type
                   (postgresql-configuration
                    (postgresql postgresql-14)
                    (config-file
                     (postgresql-config-file
                      (log-destination "stderr")
                      (hba-file
                       (plain-file "pg_hba.conf"
                                   "\
local	all	all			trust
host	all	all	10.0.0.1/32 	trust"))
                      (extra-config
                       '(("listen_addresses" "*")
                         ("log_directory"    "/var/log/postgresql")))))))
          (service postgresql-role-service-type
                   (postgresql-role-configuration
                    (roles
                     (list (postgresql-role
                            (name "test")
                            (create-database? #t))))))
          %base-services)))

With postgresql-role-service-type we define a role “test” and create a matching database, so that we can test right away without any further manual setup. The postgresql-config-file settings allow a client from IP address 10.0.0.1 to connect without requiring authentication—a bad idea in production systems, but convenient for this example.

Let’s build a script that will launch an instance of this Guix System as a container. Write the operating-system declaration above to a file os.scm and then use guix system container to build the launcher. (see Invoking guix system in GNU Guix Reference Manual).

$ guix system container os.scm
The following derivations will be built:
  /gnu/store/…-run-container.drv
  …
building /gnu/store/…-run-container.drv...
/gnu/store/…-run-container

Now that we have a launcher script we can run it to spawn the new system with a running PostgreSQL service. Note that due to some as yet unresolved limitations we need to run the launcher as the root user, for example with sudo.

$ sudo /gnu/store/…-run-container
system container is running as PID 5983
…

Background the process with Ctrl-z followed by bg. Note the process ID in the output; we will need it to connect to the container later. You know what? Let’s try attaching to the container right now. We will use nsenter, a tool provided by the util-linux package:

$ guix shell util-linux
$ sudo nsenter -a -t 5983
root@container /# pgrep -a postgres
49 /gnu/store/…-postgresql-14.4/bin/postgres -D /var/lib/postgresql/data --config-file=/gnu/store/…-postgresql.conf -p 5432
51 postgres: checkpointer
52 postgres: background writer
53 postgres: walwriter
54 postgres: autovacuum launcher
55 postgres: stats collector
56 postgres: logical replication launcher
root@container /# exit

The PostgreSQL service is running in the container!


Next: Container Networking, Up: Guix System Containers   [Contents][Index]