Closed geerlingguy closed 5 years ago
One quick question I want to jot here while it's on my mind:
Is it possible (if so, how?) to make a truly cumalative git-repo-based container image where new tags/hashes/versions only contain a new layer with the changes from the latest git hash (rather than each new container image containing the entire codebase as a layer, meaning every image will be at least as big as the size of the codebase)?
I know that was one of the whiz-bang intro-to-Docker-101 level things I remember hearing about... but in practice most places seem to add a COPY [codebase] [container path]
and that generates a new image with a unique layer with the entire codebase.
For a lot of poorly-architected codebases (I've seen them in the 1-5 GB range!), that means giant blobs of images for every single commit, ever!
The main thing that's annoying—if you do a kubectl delete pod [drupal8 pod here]
, it brings a new one up, and every time that happens you have to re-run the Drupal installer so the settings.php
file knows the database credentials.
Would like to make it so the settings.php can be dynamically generated, or gets info from environment variables (the latter seems better, and the vars for DB connection are already there).
Working on https://github.com/geerlingguy/drupal-container/issues/12 as a stop-gap, to hopefully allow multiple replicas of the Drupal container to run and use the same database connection and not do... weird things.
I think the approach I'm going to take is:
geerlingguy/drupal
container by default, for testing, etc.Also going to move #133 into that project's repo, since it literally contains all the contents of the Pi Dramble website now (yay!). And soon I'll also need to install that site on the running cluster/Pi itself and finally step away from Bartik :)
Just a scratchpad for potential changes to make the Drupal Example for Kubernetes to work as a drop-in swap for the current container:
DRUPAL_DATABASE_HOST: 'mysql'
DRUPAL_DATABASE_PORT: '3306'
DRUPAL_DATABASE_NAME: 'drupal'
DRUPAL_DATABASE_USERNAME: 'drupal'
DRUPAL_HASH_SALT: '{{ drupal_hash_salt }}'
DRUPAL_DATABASE_PASSWORD: [secret]
drupal-files
NFS volume mount is at path /var/www/html/sites/default/files
—might need to make that a variable so I can set it to /var/www/html/web/sites/default/files
instead. (Edit: Added var drupal_files_dir
).
I also will need to make the FROM
allow for an ARG
(https://www.jeffgeerling.com/blog/2017/use-arg-dockerfile-dynamic-image-specification), so I can use the base image geerlingguy/drupal:latest-arm32v7
when building for ARM.
To get the registry working correctly, I'm going to need to knock out https://github.com/geerlingguy/raspberry-pi-dramble/issues/114 as well...
Registry is working correctly now. So next steps (jotting since I'm folding up shop for the night):
k8s-cert-setup.yml
to k8s-registry-cert-setup.yml
and use it for the below tasks?registry.pidramble.test
hosts entry to /etc/hosts on all Pis, pointing at the IP address of kube3
(e.g. 192.168.77.4
for Vagrant).tls.crt
file to cert store on all Pis (copy to /etc/docker/certs.d/{{ docker_registry_domain }}/ca.crt
) (see docs for this).drupal_docker_image
and drupal_files_dir
to use Drupal Example for KubernetesARG
addition for FROM
as mentioned earlier).Looks like I'll have to do a few more things to the Drupal for Kubernetes project to get it fully ready to run in the Kubernetes environment... getting:
[Sun Feb 17 19:09:39.644065 2019] [php7:notice] [pid 10] [client 10.244.2.0:45648] Drupal\\Core\\Database\\DatabaseAccessDeniedException: SQLSTATE[HY000] [1045] Access denied for user 'drupal'@'10.244.1.9' (using password: YES) in /var/www/html/web/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php on line 427 #0 /var/www/html/web/core/lib/Drupal/Core/Database/Database.php(371): Drupal\\Core\\Database\\Driver\\mysql\\Connection::open(Array)\n#1 /var/www/html/web/core/lib/Drupal/Core/Database/Database.php(166): Drupal\\Core\\Database\\Database::openConnection('default', 'default')\n#2 [internal function]: Drupal\\Core\\Database\\Database::getConnection('default')\n#3 /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php(79): call_user_func_array('Drupal\\\\Core\\\\Dat...', Array)\n#4 /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/Container.php(171): Drupal\\Component\\DependencyInjection\\PhpArrayContainer->createService(Array, 'database')\n#5 /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php(260): Drupal\\Component\\DependencyInjection\\Container->get('database', 1)\n#6 /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php(62): Drupal\\Component\\DependencyInjection\\PhpArrayContainer->resolveServicesAndParameters(Array)\n#7 /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/Container.php(171): Drupal\\Component\\DependencyInjection\\PhpArrayContainer->createService(Array, 'cache.container')\n#8 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(543): Drupal\\Component\\DependencyInjection\\Container->get('cache.container')\n#9 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(904): Drupal\\Core\\DrupalKernel->getCachedContainerDefinition()\n#10 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(476): Drupal\\Core\\DrupalKernel->initializeContainer()\n#11 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(692): Drupal\\Core\\DrupalKernel->boot()\n#12 /var/www/html/web/index.php(19): Drupal\\Core\\DrupalKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#13 {main}
I had to manually edit settings.php:
$config_directories['sync'] = '../config/sync';
$databases['default']['default'] = array (
'database' => getenv('DRUPAL_DATABASE_NAME'),
'username' => getenv('DRUPAL_DATABASE_USERNAME'),
'password' => getenv('DRUPAL_DATABASE_PASSWORD'),
'prefix' => '',
'host' => getenv('DRUPAL_DATABASE_HOST'),
'port' => '',
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'driver' => 'mysql',
);
$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT');
Then I had to drop all tables and reinstall Drupal:
$ vendor/bin/drush sql-drop -y
$ vendor/bin/drush site:install minimal --db-url="mysql://drupal:$DRUPAL_DATABASE_PASSWORD@$DRUPAL_DATABASE_HOST/drupal" --site-name="Drupal Example Site for Kubernetes" --existing-config -y
Milestone: I have Drupal for Kubernetes running on the cluster:
But I need to fix the settings.php
situation so I can install-if-not-installed and have it automatically start if already installed (without messing up settings or having the wrong settings).
I thought I had already figured this out elsewhere, but I'm not seeing where I did so :/
Ah... I did set this up over in the drupal-container
repo: https://github.com/geerlingguy/drupal-container/blob/master/docker-entrypoint.sh#L27-L42
Problem is, that's only run for the downloaded Drupal tarball, not for the Drupal for Kubernetes codebase! So I'll need to create a template settings.php or something like that for use in production.
Fixed over in https://github.com/geerlingguy/drupal-for-kubernetes/issues/10 — local testing is good so far!
Next up, I need to start testing this on the real Pi cluster... and test building the image on ARM32 (right now I've only tested on AMD64).
Installing on a freshly-reset set of Pis now. Apparently Docker 18.09.2 has not yet been released for Raspbian:
E: Version '5:18.09.2~3-0~raspbian-stretch' for 'docker-ce' was not found
So I have to stick to 5:18.09.0~3-0~raspbian-stretch
for now :-/
(See: https://download.docker.com/linux/raspbian/dists/stretch/stable/binary-armhf/Packages)
Weird, now I'm running into:
$ kubectl exec -n drupal $DRUPAL_POD -- bash -c 'vendor/
bin/drush site:install minimal --db-url="mysql://drupal:$DRUPAL_DATABASE_PASSWORD@$DRUPAL_DATABASE_HOST/drupal" --site-name="Drupal Example Site for Kubernetes" --existing-config -y'
// You are about to DROP all tables in your 'drupal' database. Do you want to
// continue?: yes.
[notice] Starting Drupal installation. This takes a while.
TypeError: Return value of Doctrine\Common\Annotations\AnnotationRegistry::reset() must be an instance of Doctrine\Common\Annotations\void, none returned in Doctrine\Common\Annotations\AnnotationRegistry::reset() (line 55 of /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php).
TypeError: Return value of Doctrine\Common\Annotations\AnnotationRegistry::reset() must be an instance of Doctrine\Common\Annotations\void, none returned in /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 55 #0 /var/www/html/web/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php(113): Doctrine\Common\Annotations\AnnotationRegistry::reset()
#1 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityTypeManager.php(106): Drupal\Component\Annotation\Plugin\Discovery\AnnotatedClassDiscovery->getDefinitions()
#2 /var/www/html/web/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php(175): Drupal\Core\Entity\EntityTypeManager->findDefinitions()
#3 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityManager.php(675): Drupal\Core\Plugin\DefaultPluginManager->getDefinitions()
#4 /var/www/html/web/core/lib/Drupal/Core/Config/ConfigManager.php(100): Drupal\Core\Entity\EntityManager->getDefinitions()
#5 /var/www/html/web/core/lib/Drupal/Core/Config/ConfigInstaller.php(317): Drupal\Core\Config\ConfigManager->getEntityTypeIdByName('core.extension')
#6 /var/www/html/web/core/lib/Drupal/Core/Config/ConfigInstaller.php(132): Drupal\Core\Config\ConfigInstaller->createConfiguration('', Array)
...
Dangit... apparently this has to do with the PHP 7.0.33 version that is present on the ARM version of geerlingguy/drupal
.
I'll have to look at upgrading to 7.1 or later. See: https://github.com/acquia/blt/issues/2660#issuecomment-416316993
Trying https://getgrav.org/blog/raspberrypi-nginx-php7-dev — but actually considering building/using a buster
container as it already has php7.2-*
packages available and I wouldn't have to twiddle with apt priorities.
Could also use one of my favorite repos—apparently Oerdnj supports ARM now, who knew? https://github.com/oerdnj/deb.sury.org/issues/579
Upstream issue: https://github.com/geerlingguy/drupal-container/issues/17
PHP 7.3.x/buster did not work out of the box, so trying Ondrej Sury's repos now.
Still working on these issues through the drupal-for-kubernetes and drupal-container projects...
Build pipelines are always amazing until there are little failures in multiple stages.
Fixed the upstream issues, running PHP 7.2.x now, and the site loads from the Pi Cluster just as well as it does from the local Vagrant/VirtualBox cluster, yay!
I've added all the build directions to the Drupal for Kubernetes repo over here: https://github.com/geerlingguy/drupal-for-kubernetes/tree/master/docs
So here's where a lot of the rubber meets the road...
geerlingguy/drupal
image from Docker Hub.drupal-project
if I need more modules and Composery delights.99.9% of all the blog posts, docs, etc., assume you're just mounting the codebase inside the container using a Docker volume / bind mount / etc.
But I want to document (and start using in my personal infra, quite frankly!) a process whereby:
spec.template.spec.containers[0].image
in thedrupal8.yml
manifest to point to the new tagged image or latest hash).I might not go the full distance and automate everything 100% inside this project's codebase; but I do want that workflow to be enabled easily, and I want at least one or more of the following:
kubectl apply
of the changed image.