Install rgallery with Tanka
Prerequisites
The following prerequisites are required to install rgallery within a Kubernetes cluster:
Setup folder structure
tk init
tk env add environments/rgallery --namespace=rgallery --server=<Kubernetes API server>
Setup rgallery libary
jb module coming soon.
mkdir -p lib/rgallery
touch lib/rgallery/rgallery.libsonnet
In lib/rgallery/rgallery.libsonnet
, copy the following contents:
{
new(name, image, dataPath, mediaPath, cachePath):: {
local k = (import 'ksonnet-util/kausal.libsonnet'),
local this = self,
local statefulset = k.apps.v1.statefulSet,
local service = k.core.v1.service,
local configmap = k.core.v1.configMap,
local container = k.core.v1.container,
local containerPort = k.core.v1.containerPort,
local persistentVolume = k.core.v1.persistentVolume,
local persistentVolumeClaim = k.core.v1.persistentVolumeClaim,
local volume = k.core.v1.volume,
local volumeMount = k.core.v1.volumeMount,
local envVar = k.core.v1.envVar,
local utils = import 'utils/utils.libsonnet',
_config+: {
rgallery_config_template: importstr 'files/rgallery.yml',
},
rgallery_container::
container.new(name, image)
+ container.withPorts(
[
containerPort.new(name, 3000),
containerPort.new('metrics', 3001),
]
)
+ container.withEnvMixin([
envVar.new('TZ', 'Europe/Stockholm'),
])
+ container.withCommandMixin(['/usr/bin/rgallery', '--include-originals=true'])
+ utils.buildHealthcheck(port=3000, periodSeconds=10, initialDelaySeconds=1, timeoutSeconds=10)
+ container.withVolumeMounts([
volumeMount.new(name + '-cache', '/cache'),
volumeMount.new(name + '-media', '/media'),
volumeMount.new(name + '-data', '/data'),
])
+ container.securityContext.withRunAsUser(1000)
+ container.securityContext.withRunAsGroup(1000),
rgallery_config_template:
configmap.new('rgallery-config')
+ configmap.withData({
'config.yml': std.format(this._config.rgallery_config_template, this._config),
}),
rgallery_statefulset:
statefulset.new(name, 1, [this.rgallery_container])
+ statefulset.mixin.spec.template.spec.withVolumes([
{
name: name + '-media',
persistentVolumeClaim: {
claimName: name + '-media',
},
},
{
name: name + '-cache',
persistentVolumeClaim: {
claimName: name + '-cache',
},
},
{
name: name + '-data',
persistentVolumeClaim: {
claimName: name + '-data',
},
},
])
+ statefulset.spec.withServiceName(this.rgallery_statefulset.metadata.name)
+ statefulset.mixin.spec.template.metadata.withAnnotationsMixin({
configVersion: std.md5(std.format(this._config.rgallery_config_template, this._config)),
})
+ k.util.configVolumeMount('rgallery-config', '/config'),
rgallery_service:
k.util.serviceFor(this.rgallery_statefulset)
+ service.mixin.spec.withType('ClusterIP'),
rgallery_data_volume:
persistentVolume.new(name + '-data')
+ persistentVolume.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolume.spec.withCapacity({ storage: '20Gi' })
+ persistentVolume.spec.withStorageClassName('')
+ persistentVolume.spec.hostPath.withPath(dataPath),
rgallery_data_claim:
persistentVolumeClaim.new(name + '-data')
+ persistentVolumeClaim.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolumeClaim.spec.resources.withRequests({ storage: '20Gi' })
+ persistentVolumeClaim.spec.withStorageClassName('')
+ persistentVolumeClaim.spec.withVolumeName(name + '-data'),
rgallery_media_volume:
persistentVolume.new(name + '-media')
+ persistentVolume.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolume.spec.withCapacity({ storage: '20Gi' })
+ persistentVolume.spec.withStorageClassName('')
+ persistentVolume.spec.hostPath.withPath(mediaPath),
rgallery_media_claim:
persistentVolumeClaim.new(name + '-media')
+ persistentVolumeClaim.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolumeClaim.spec.resources.withRequests({ storage: '20Gi' })
+ persistentVolumeClaim.spec.withStorageClassName('')
+ persistentVolumeClaim.spec.withVolumeName(name + '-media'),
rgallery_cache_volume:
persistentVolume.new(name + '-cache')
+ persistentVolume.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolume.spec.withCapacity({ storage: '20Gi' })
+ persistentVolume.spec.withStorageClassName('')
+ persistentVolume.spec.hostPath.withPath(cachePath),
rgallery_cache_claim:
persistentVolumeClaim.new(name + '-cache')
+ persistentVolumeClaim.spec.withAccessModes(['ReadWriteOnce'])
+ persistentVolumeClaim.spec.resources.withRequests({ storage: '20Gi' })
+ persistentVolumeClaim.spec.withStorageClassName('')
+ persistentVolumeClaim.spec.withVolumeName(name + '-cache'),
},
}
In environments/rgallery/main.jsonnet
copy the following contents:
local rgallery = import 'gogallery/rgallery-simple.libsonnet';
local k = import 'ksonnet-util/kausal.libsonnet';
rgallery {
_config+:: {
namespace: 'rgallery',
},
namespace: k.core.v1.namespace.new($._config.namespace),
rgallery: rgallery.new(name='demo', image='robbymilo/rgallery:latest', dataPath='/mnt/rgallery/data', mediaPath='/mnt/rgallery/media', cachePath='/mnt/rgallery/cache') {
},
}
If you want to add lens aliases, create the file environments/rgallery/files/config.yml
and copy the following contents (replace with the necessary lens values):
aliases:
lenses: # exif:alias
"70.0-200.0 mm f/f2.8": "AF-S Nikkor 70-200mm f/2.8G ED VR II"
"VR 70-200mm f/2.8G": "AF-S Nikkor 70-200mm f/2.8G ED VR II"
"AF-S Nikkor 70-200mm f/2.8G ED VR II": "AF-S Nikkor 70-200mm f/2.8G ED VR II"
Apply changes
Note: The manifests run rgallery as a user with UID
1000
and GID1000
. The data, media, and cache directories must have appropriate read/write permissions for this user.
tk apply environments/rgallery