shell: docker run needs shell

don't want to get into parsing quotes!
This commit is contained in:
Girish Ramakrishnan
2024-02-22 10:34:56 +01:00
parent a6f078330f
commit 60994f9ed1
4 changed files with 42 additions and 41 deletions
+29 -29
View File
@@ -936,7 +936,7 @@ async function startTurn(existingInfra) {
// this exports 3478/tcp, 5349/tls and 50000-51000/udp. note that this runs on the host network because docker's userland proxy
// is spun for every port. we can disable this in some future release with --userland-proxy=false
// https://github.com/moby/moby/issues/8356 and https://github.com/moby/moby/issues/14856
const runCmd = `docker run --restart=always -d --name="turn" \
const runCmd = `docker run --restart=always -d --name=turn \
--hostname turn \
--net host \
--log-driver syslog \
@@ -947,10 +947,10 @@ async function startTurn(existingInfra) {
--memory-swap ${memoryLimit} \
--dns 172.18.0.1 \
--dns-search=. \
-e CLOUDRON_TURN_SECRET="${turnSecret}" \
-e CLOUDRON_TURN_SECRET=${turnSecret} \
-e CLOUDRON_REALM="${realm}" \
--label isCloudronManaged=true \
${readOnly} -v /tmp -v /run "${image}" ${cmd}`;
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
await safe(shell.exec('stopTurn', 'docker stop turn', {})); // ignore error
await safe(shell.exec('removeTurn', 'docker rm -f turn', {})); // ignore error
@@ -1140,7 +1140,7 @@ async function startMysql(existingInfra) {
const cmd = serviceConfig.recoveryMode ? '/bin/bash -c \'echo "Debug mode. Sleeping" && sleep infinity\'' : '';
// memory options are applied dynamically. import requires all the memory we can get
const runCmd = `docker run --restart=always -d --name="mysql" \
const runCmd = `docker run --restart=always -d --name=mysql \
--hostname mysql \
--net cloudron \
--net-alias mysql \
@@ -1154,14 +1154,14 @@ async function startMysql(existingInfra) {
-e CLOUDRON_MYSQL_TOKEN=${cloudronToken} \
-e CLOUDRON_MYSQL_ROOT_HOST=172.18.0.1 \
-e CLOUDRON_MYSQL_ROOT_PASSWORD=${rootPassword} \
-v "${dataDir}/mysql:/var/lib/mysql" \
-v ${dataDir}/mysql:/var/lib/mysql \
--label isCloudronManaged=true \
--cap-add SYS_NICE \
${readOnly} -v /tmp -v /run "${image}" ${cmd}`;
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
await safe(shell.exec('stopMysql', 'docker stop mysql', {})); // ignore error
await safe(shell.exec('removeMysql', 'docker rm -f mysql', {})); // ignore error
await shell.exec('startMysql', runCmd, {});
await shell.exec('startMysql', runCmd, { shell: '/bin/bash' });
if (!serviceConfig.recoveryMode) {
await waitForContainer('mysql', 'CLOUDRON_MYSQL_TOKEN');
@@ -1359,7 +1359,7 @@ async function startPostgresql(existingInfra) {
const useVectorRsExtension = !!serviceConfig.useVectorRsExtension;
// memory options are applied dynamically. import requires all the memory we can get
const runCmd = `docker run --restart=always -d --name="postgresql" \
const runCmd = `docker run --restart=always -d --name=postgresql \
--hostname postgresql \
--net cloudron \
--net-alias postgresql \
@@ -1371,16 +1371,16 @@ async function startPostgresql(existingInfra) {
--dns-search=. \
--ip ${constants.POSTGRESQL_SERVICE_IPv4} \
--shm-size=128M \
-e CLOUDRON_POSTGRESQL_ROOT_PASSWORD="${rootPassword}" \
-e CLOUDRON_POSTGRESQL_TOKEN="${cloudronToken}" \
-e CLOUDRON_POSTGRESQL_USE_VECTOR_RS="${ useVectorRsExtension ? 'true': '' }" \
-v "${dataDir}/postgresql:/var/lib/postgresql" \
-e CLOUDRON_POSTGRESQL_ROOT_PASSWORD=${rootPassword} \
-e CLOUDRON_POSTGRESQL_TOKEN=${cloudronToken} \
-e CLOUDRON_POSTGRESQL_USE_VECTOR_RS=${ useVectorRsExtension ? 'true': '' } \
-v ${dataDir}/postgresql:/var/lib/postgresql \
--label isCloudronManaged=true \
${readOnly} -v /tmp -v /run "${image}" ${cmd}`;
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
await safe(shell.exec('stopPostgresql', 'docker stop postgresql', {})); // ignore error
await safe(shell.exec('removePostgresql', 'docker rm -f postgresql', {})); // ignore error
await shell.exec('startPostgresql', runCmd, {});
await shell.exec('startPostgresql', runCmd, { shell: '/bin/bash' });
if (!serviceConfig.recoveryMode) {
await waitForContainer('postgresql', 'CLOUDRON_POSTGRESQL_TOKEN');
@@ -1504,7 +1504,7 @@ async function startMongodb(existingInfra) {
const cmd = serviceConfig.recoveryMode ? '/bin/bash -c \'echo "Debug mode. Sleeping" && sleep infinity\'' : '';
// memory options are applied dynamically. import requires all the memory we can get
const runCmd = `docker run --restart=always -d --name="mongodb" \
const runCmd = `docker run --restart=always -d --name=mongodb \
--hostname mongodb \
--net cloudron \
--net-alias mongodb \
@@ -1515,15 +1515,15 @@ async function startMongodb(existingInfra) {
--dns 172.18.0.1 \
--dns-search=. \
--ip ${constants.MONGODB_SERVICE_IPv4} \
-e CLOUDRON_MONGODB_ROOT_PASSWORD="${rootPassword}" \
-e CLOUDRON_MONGODB_TOKEN="${cloudronToken}" \
-v "${dataDir}/mongodb:/var/lib/mongodb" \
-e CLOUDRON_MONGODB_ROOT_PASSWORD=${rootPassword} \
-e CLOUDRON_MONGODB_TOKEN=${cloudronToken} \
-v ${dataDir}/mongodb:/var/lib/mongodb \
--label isCloudronManaged=true \
${readOnly} -v /tmp -v /run "${image}" ${cmd}`;
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
await safe(shell.exec('stopMongodb', 'docker stop mongodb', {})); // ignore error
await safe(shell.exec('removeMongodb', 'docker rm -f mongodb', {})); // ignore error
await shell.exec('startMongodb', runCmd, {});
await shell.exec('startMongodb', runCmd, { shell: '/bin/bash' });
if (!serviceConfig.recoveryMode) {
await waitForContainer('mongodb', 'CLOUDRON_MONGODB_TOKEN');
@@ -1652,7 +1652,7 @@ async function startGraphite(existingInfra) {
const cmd = serviceConfig.recoveryMode ? '/bin/bash -c \'echo "Debug mode. Sleeping" && sleep infinity\'' : '';
// port 2003 is used by collectd
const runCmd = `docker run --restart=always -d --name="graphite" \
const runCmd = `docker run --restart=always -d --name=graphite \
--hostname graphite \
--net cloudron \
--net-alias graphite \
@@ -1665,14 +1665,14 @@ async function startGraphite(existingInfra) {
--dns 172.18.0.1 \
--dns-search=. \
-p 127.0.0.1:2003:2003 \
-v "${paths.PLATFORM_DATA_DIR}/graphite:/var/lib/graphite" \
-v ${paths.PLATFORM_DATA_DIR}/graphite:/var/lib/graphite \
--label isCloudronManaged=true \
${readOnly} -v /tmp -v /run "${image}" ${cmd}`;
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
await safe(shell.exec('stopGraphite', 'docker stop graphite', {})); // ignore error
await safe(shell.exec('removeGraphite', 'docker rm -f graphite', {})); // ignore error
if (upgrading) await shell.promises.sudo('removeGraphiteDir', [ RMADDONDIR_CMD, 'graphite' ], {});
await shell.exec('startGraphite', runCmd, {});
await shell.exec('startGraphite', runCmd, { shell: '/bin/bash' });
// restart collectd to get the disk stats after graphite starts. currently, there is no way to do graphite health check
setTimeout(async () => await safe(shell.promises.sudo('restartcollectd', [ RESTART_SERVICE_CMD, 'collectd' ], {})), 60000);
@@ -1756,14 +1756,14 @@ async function setupRedis(app, options) {
--log-driver syslog \
--log-opt syslog-address=udp://127.0.0.1:2514 \
--log-opt syslog-format=rfc5424 \
--log-opt tag="${redisName}" \
--log-opt tag=${redisName} \
-m ${memory} \
--memory-swap ${memoryLimit} \
--dns 172.18.0.1 \
--dns-search=. \
-e CLOUDRON_REDIS_PASSWORD="${redisPassword}" \
-e CLOUDRON_REDIS_TOKEN="${redisServiceToken}" \
-v "${paths.PLATFORM_DATA_DIR}/redis/${app.id}:/var/lib/redis" \
-e CLOUDRON_REDIS_PASSWORD=${redisPassword} \
-e CLOUDRON_REDIS_TOKEN=${redisServiceToken} \
-v ${paths.PLATFORM_DATA_DIR}/redis/${app.id}:/var/lib/redis \
--label isCloudronManaged=true \
${readOnly} -v /tmp -v /run ${image} ${cmd}`;
@@ -1776,7 +1776,7 @@ async function setupRedis(app, options) {
const [inspectError, result] = await safe(docker.inspect(redisName));
if (inspectError) {
await shell.exec('startRedis', runCmd, {});
await shell.exec('startRedis', runCmd, { shell: '/bin/bash' });
} else { // fast path
debug(`Re-using existing redis container with state: ${JSON.stringify(result.State)}`);
}