|
@@ -1,8 +1,12 @@
|
1
|
1
|
# scalelite-run
|
2
|
2
|
|
3
|
|
-This document provides instructions on how to deploy scalelite + redis behind a nginx proxy
|
|
3
|
+This document provides instructions on how to deploy scalelite behind a nginx proxy
|
4
|
4
|
using docker-compose.
|
5
|
5
|
|
|
6
|
+This can be performed as an [All-In-One-Box Deployment](#all-in-one-box-deployment) or making use of distributed services in the cloud (or virtual private cloud) through a cloud computing provider as a [Distributed Deployment](#distributed-deployment).
|
|
7
|
+
|
|
8
|
+<a name="prerequisites"/>
|
|
9
|
+
|
6
|
10
|
## Prerequisites
|
7
|
11
|
|
8
|
12
|
- Install
|
|
@@ -10,26 +14,31 @@ using docker-compose.
|
10
|
14
|
and
|
11
|
15
|
[docker-compose](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04)
|
12
|
16
|
|
13
|
|
-- Make sure you have access to Blindside Networks private repository in
|
14
|
|
- [dockerhub](https://cloud.docker.com/u/blindsidenetwks/repository/list) particularly to:
|
|
17
|
+- Make sure you have access to Blindside Networks repositories in
|
|
18
|
+ [dockerhub](https://cloud.docker.com/u/blindsidenetwks/repository/list) (particularly to [scalelite](https://cloud.docker.com/u/blindsidenetwks/repository/docker/blindsidenetwks/scalelite)).
|
|
19
|
+
|
|
20
|
+- Make sure you have your own public domain name (e.g. blindside-dev.com) or a delegated one (e.g. <JOHN>.blindside-dev.com) and have access to manage it through a DNS.
|
15
|
21
|
|
16
|
|
- - [scalelite](https://cloud.docker.com/u/blindsidenetwks/repository/docker/blindsidenetwks/scalelite)
|
|
22
|
+<a name="preparation"/>
|
|
23
|
+
|
|
24
|
+## Preparation
|
|
25
|
+
|
|
26
|
+These steps were written for an Ubuntu 18.04 machine. It is assumed that your machine has the same (or a compatible version).
|
17
|
27
|
|
18
|
|
-- Make sure you have your own DNS and a public domain name (e.g. example.com) or a delegated one (e.g. <JOHN>.blindside-dev.com).
|
|
28
|
+<a name="accessing-dockerhub"/>
|
19
|
29
|
|
|
30
|
+### 1. Accessing DockerHub
|
20
|
31
|
|
21
|
|
-- As you have to have access to dockerhub private repositories sign in into docker hub with your account
|
|
32
|
+If you have to have access to dockerhub private repositories sign in into docker hub with your account
|
22
|
33
|
with `docker login` any type your username and password using the stdin.
|
23
|
34
|
|
24
|
35
|
```
|
25
|
36
|
docker login
|
26
|
37
|
```
|
27
|
38
|
|
28
|
|
-## Steps
|
|
39
|
+<a name="getting-the-scripts"/>
|
29
|
40
|
|
30
|
|
-These steps were written for an Ubuntu 18.04 machine. It is assumed that your machine has the same (or a compatible version).
|
31
|
|
-
|
32
|
|
-### Getting the scripts
|
|
41
|
+### 2. Getting the scripts
|
33
|
42
|
|
34
|
43
|
Clone this repository:
|
35
|
44
|
|
|
@@ -38,33 +47,60 @@ git clone git@github.com:blindsidenetworks/scalelite-run.git
|
38
|
47
|
cd scalelite-run
|
39
|
48
|
```
|
40
|
49
|
|
41
|
|
-Copy `dotenv` file located in the root of the project as `.env` and edit it
|
|
50
|
+<a name="all-in-one-box-deployment"/>
|
|
51
|
+
|
|
52
|
+## I. All-In-One-Box Deployment
|
|
53
|
+
|
|
54
|
+<a name="initial-settings"/>
|
|
55
|
+
|
|
56
|
+### 1. Initial settings
|
|
57
|
+
|
|
58
|
+Copy `dotenv` file located in the root of the project as `.env` and edit it.
|
42
|
59
|
|
43
|
60
|
```
|
44
|
61
|
cp dotenv .env
|
45
|
|
-vi .env
|
46
|
62
|
```
|
47
|
63
|
|
48
|
64
|
You need to replace the variable `HOST_NAME=sl.xlab.blindside-dev.com` with a hostname under your own domain name (e.g. `HOST_NAME=sl.john.blindside-dev.com`) or delegated sub-domain.
|
49
|
65
|
|
|
66
|
+```
|
|
67
|
+vi .env
|
|
68
|
+```
|
50
|
69
|
|
51
|
70
|
Copy `dotenv` file located in the scalelite directory as `.env` and in the same way as before, edit it:
|
52
|
71
|
|
53
|
72
|
```
|
54
|
73
|
cp scalelite/dotenv scalelite/.env
|
55
|
|
-vi scalelite/.env
|
56
|
74
|
```
|
57
|
75
|
|
58
|
76
|
You can start it as is, but you may want to replace both variables with your own values.
|
59
|
77
|
|
60
|
|
-`SECRET_KEY_BASE` is the Ruby On Rails secret key and should be replaced with a random one generated with `openssl rand -hex 64`.
|
|
78
|
+- `SECRET_KEY_BASE` is the Ruby On Rails secret key and should be replaced with a random one generated with `openssl rand -hex 64`.
|
|
79
|
+- `LOADBALANCER_SECRET` is the shared secret used by external applications for accessing Scalelite LoadBalancer as if it was a BigBlueButton server. By default, it includes the Secret used for test-install (which is also the first server added to the pool as example).
|
|
80
|
+
|
|
81
|
+```
|
|
82
|
+vi scalelite/.env
|
|
83
|
+```
|
|
84
|
+
|
|
85
|
+<a name="ssl-certificate"/>
|
|
86
|
+
|
|
87
|
+### 2. SSL Certificate
|
61
|
88
|
|
62
|
|
-`LOADBALANCER_SECRET` is the shared secret used by external applications for accessing the Load Balancer as if it was a BigBlueButton server. By default, it includes the Secret used for test-install (which is also the first server added to the pool as example).
|
|
89
|
+The docker-compose scripts come configured for using SSL Certificates, but you may want not to use an SSL certificate. If this is the case see the section [Removing SSL Certificate](#removing-ssl-certificate) in [Special Cases](#special-cases).
|
63
|
90
|
|
|
91
|
+The procedure for setting up the SSL Certificate will be different depending if [Let's Encrypt SSL CA](#letsencrypt-ssl-ca) CA or [Other SSL CA](#other-ssl-ca) will be used.
|
64
|
92
|
|
65
|
|
-### Using SSL Letsencrypt in the cloud
|
|
93
|
+<a name="letsencrypt-ssl-ca"/>
|
66
|
94
|
|
67
|
|
-If all the previous steps were followed properly and the machine is accessible in the Internet, only execute:
|
|
95
|
+#### 2.1. Using Let's Encrypt SSL CA
|
|
96
|
+
|
|
97
|
+There are also two paths that can be followed whether the box where Scalelite is going to be installed is [visible from the Internet](#letsencrypt-ssl-public-network) or [NOT visible from the Internet](#letsencrypt-ssl-private-network).
|
|
98
|
+
|
|
99
|
+<a name="letsencrypt-ssl-public-network"/>
|
|
100
|
+
|
|
101
|
+##### 2.1.1. Server is visible from the Internet
|
|
102
|
+
|
|
103
|
+If all the previous steps were properly followed and the machine is accessible in the Internet, only execute:
|
68
|
104
|
|
69
|
105
|
```
|
70
|
106
|
./init-letsencrypt.sh
|
|
@@ -72,19 +108,20 @@ If all the previous steps were followed properly and the machine is accessible i
|
72
|
108
|
|
73
|
109
|
This will generate the SSL certificates and run scalelite for the first time, so all the required files are automatically generated.
|
74
|
110
|
|
|
111
|
+<a name="letsencrypt-ssl-private-network"/>
|
75
|
112
|
|
76
|
|
-### Using SSL Letsencrypt certificate in private Networks
|
|
113
|
+##### 2.1.2. Server is NOT visible from the Internet
|
77
|
114
|
|
78
|
|
-If you are trying to install scalelite locally or in a private network, the process is more manual. You need to generate the SSL certificates with certbot by adding the challenge to your DNS.
|
|
115
|
+If you are trying to install scalelite locally or in a private network, the SSL certificate must be generated manually using certbot and by adding the manual challenge to the DNS.
|
79
|
116
|
|
80
|
|
-Install letsencrypt in your own computer
|
|
117
|
+Install Let's Encrypt
|
81
|
118
|
|
82
|
119
|
```
|
83
|
120
|
sudo apt-get update
|
84
|
121
|
sudo apt-get -y install letsencrypt
|
85
|
122
|
```
|
86
|
123
|
|
87
|
|
-Make yourself root
|
|
124
|
+Become root
|
88
|
125
|
|
89
|
126
|
```
|
90
|
127
|
sudo -i
|
|
@@ -96,7 +133,8 @@ Start creating the certificates
|
96
|
133
|
certbot certonly --manual -d sl.<JOHN>.blindside-dev.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges=dns --email hostmaster@blindsdie-dev.com --server https://acme-v02.api.letsencrypt.org/directory
|
97
|
134
|
```
|
98
|
135
|
|
99
|
|
-You will see something like this
|
|
136
|
+The output should look like this example
|
|
137
|
+
|
100
|
138
|
```
|
101
|
139
|
-server https://acme-v02.api.letsencrypt.org/directory
|
102
|
140
|
Saving debug log to /var/log/letsencrypt/letsencrypt.log
|
|
@@ -117,40 +155,99 @@ Before continuing, verify the record is deployed.
|
117
|
155
|
Press Enter to Continue
|
118
|
156
|
```
|
119
|
157
|
|
120
|
|
-Create a TXT record in your DNS for
|
|
158
|
+Create a TXT record in the DNS for
|
121
|
159
|
`_acme-challenge.sl.<JOHN>.blindside-dev.com` with the challenge string as
|
122
|
160
|
its value `2dxWYkcETHnimmQmCL0MCbhneRNxMEMo9yjk6P_17kE`
|
123
|
161
|
|
124
|
|
-Copy the certificates to your scalelite-run directory. Although `/etc/letsencrypt/live/`
|
|
162
|
+Copy the certificates to the scalelite-run directory. Although `/etc/letsencrypt/live/`
|
125
|
163
|
holds the latest certificate, they are only symbolic links. The real files must be copied and renamed
|
126
|
164
|
|
127
|
165
|
```
|
128
|
166
|
cp -R /etc/letsencrypt <YOUR ROOT>/scalelite-run/data/certbot/conf
|
129
|
167
|
```
|
130
|
168
|
|
131
|
|
-### Starting the application
|
|
169
|
+<a name="other-ssl-ca"/>
|
|
170
|
+
|
|
171
|
+#### 2.2. Using Other SSL CA
|
|
172
|
+
|
|
173
|
+For adding an SSL certificate from an CA other than Let's Encrypt,
|
|
174
|
+
|
|
175
|
+DO NOT execute the `./init-letsencrypt.sh` script
|
|
176
|
+
|
|
177
|
+Place the SSL Certificate, Intermediate Certificate (or Bundle with both of them if you have it) and Private Key files inside `nginx/ssl` as `fullchain.pem` and `privkey.pem`.
|
|
178
|
+E.g.
|
|
179
|
+```
|
|
180
|
+cd ~/
|
|
181
|
+cat your_domain_name.crt Intermediate.crt >> bundle.crt
|
|
182
|
+cp bundle.crt <YOUR ROOT>/scalelite/nginx/ssl/fullchain.pem
|
|
183
|
+cp private.key <YOUR ROOT>/scalelite/nginx/ssl/privkey.pem
|
|
184
|
+```
|
|
185
|
+
|
|
186
|
+Edit the template for nginx.
|
|
187
|
+```
|
|
188
|
+cd <YOUR ROOT>/scalelite
|
|
189
|
+vi nginx/sites.template
|
|
190
|
+```
|
|
191
|
+Comment the lines referencing the Let's Encrypt Certificate and uncomment the other two. After that, it should look like this:
|
|
192
|
+
|
|
193
|
+```
|
|
194
|
+...
|
|
195
|
+ ## Configuration for Letsencrypt SSL Certificate
|
|
196
|
+ #ssl_certificate /etc/letsencrypt/live/$NGINX_HOSTNAME/fullchain.pem;
|
|
197
|
+ #ssl_certificate_key /etc/letsencrypt/live/$NGINX_HOSTNAME/privkey.pem;
|
|
198
|
+
|
|
199
|
+ ## Configuration for SSL Certificate from a CA other than Letsencrypt
|
|
200
|
+ ssl_certificate /etc/ssl/fullchain.pem;
|
|
201
|
+ ssl_certificate_key /etc/ssl/privkey.pem;
|
|
202
|
+...
|
|
203
|
+```
|
|
204
|
+
|
|
205
|
+Comment out in `docker-compose.yml` the certbot container. After that, it should look like this:
|
|
206
|
+
|
|
207
|
+```
|
|
208
|
+...
|
|
209
|
+## Configuration for Letsencrypt SSL Certificate
|
|
210
|
+## comment out when using an SSL Certificate from a CA other than Letsencrypt
|
|
211
|
+# certbot:
|
|
212
|
+# image: certbot/certbot
|
|
213
|
+# volumes:
|
|
214
|
+# - ./data/certbot/conf:/etc/letsencrypt
|
|
215
|
+# - ./data/certbot/www:/var/www/certbot
|
|
216
|
+# entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
|
217
|
+...
|
|
218
|
+```
|
|
219
|
+
|
|
220
|
+Start the containers as usual.
|
|
221
|
+
|
|
222
|
+<a name="start-up"/>
|
132
|
223
|
|
133
|
|
-And finally, start your environment with docker-compose
|
|
224
|
+### 3. Start Up
|
|
225
|
+
|
|
226
|
+And finally, start the application with docker-compose
|
134
|
227
|
|
135
|
228
|
```
|
136
|
229
|
cd <YOUR ROOT>/scalelite-run
|
137
|
230
|
docker-compose up
|
138
|
231
|
```
|
139
|
232
|
|
140
|
|
-If everything goes well, you will see all the containers starting and at the
|
141
|
|
-end you will have access to scalelite through:
|
|
233
|
+If everything goes well, the logs will show ip in the console for all the containers starting and scalelite will be available at:
|
142
|
234
|
|
143
|
235
|
```
|
144
|
236
|
https://sl.<JOHN>.blindside-dev.com/bigbluebutton/api
|
145
|
237
|
```
|
146
|
238
|
|
147
|
|
-Note that you can always run the application in the background `docker-compose up -d`
|
|
239
|
+Note that the application can be run in the background with `docker-compose up -d`
|
|
240
|
+
|
|
241
|
+<a name="final-steps"/>
|
|
242
|
+
|
|
243
|
+### 4. Final Steps
|
148
|
244
|
|
149
|
|
-### Final Steps
|
|
245
|
+<a name="initializing-pool"/>
|
150
|
246
|
|
151
|
|
-As the only BigBlueButton Server configured by default is test-install, this comes intentionally disabled. You would have to either enable it or to add new ones. Either way this has to be done through the console.
|
|
247
|
+#### 4.1. Initializing pool of servers
|
|
248
|
+As the only BigBlueButton Server configured by default is test-install, it comes intentionally disabled. It has to be manually enabled or a new server added. Either option has to be done through the console.
|
152
|
249
|
|
153
|
|
-Open a new console and get the ids of the docker containers running:
|
|
250
|
+Open a new console and get the IDs of the docker containers running:
|
154
|
251
|
|
155
|
252
|
```
|
156
|
253
|
docker ps
|
|
@@ -162,18 +259,65 @@ Get into the container running the api
|
162
|
259
|
docker exec -it <CONTAINER_ID> sh
|
163
|
260
|
```
|
164
|
261
|
|
165
|
|
-Once inside, you can see execute all the rails commands as needed. In this case, lets assume that you want to enable the current BigBlueButton server
|
|
262
|
+Once inside, all the rails commands can be executed as needed. In this case, and assuming that the current current BigBlueButton server is going to be enabled.
|
166
|
263
|
|
167
|
264
|
```
|
168
|
265
|
bundle exec rake servers
|
169
|
266
|
bundle exec rake servers:enable["SERVER_ID_AS SHOWN"]
|
170
|
267
|
```
|
171
|
268
|
|
172
|
|
-For more information on what rake commands can be executed, see scalelite documentation.
|
|
269
|
+For more information on what rake commands can be executed, see [scalelite documentation](https://github.com/blindsidenetworks/scalelite).
|
|
270
|
+
|
|
271
|
+<a name="rolling-out-updates"/>
|
|
272
|
+
|
|
273
|
+#### 4.2. Rolling-out updates
|
|
274
|
+
|
|
275
|
+Scalelite is constantly updated. Either because of bug fixes or improvements. It is recommended to keep the deployment updated with the latest image available, which corresponds to the latest stable release.
|
|
276
|
+
|
|
277
|
+Those updates can be performed manually (recommended for a production alike environment) or automatically.
|
|
278
|
+
|
|
279
|
+<a name="rolling-out-updates-manual"/>
|
|
280
|
+
|
|
281
|
+##### 4.2.1. Manual updates
|
|
282
|
+
|
|
283
|
+Simply run the `deploy.sh` script included under `scripts`.
|
|
284
|
+
|
|
285
|
+```
|
|
286
|
+cd <YOUR ROOT>/scalelite-run
|
|
287
|
+sudo .scripts/deploy.sh
|
|
288
|
+```
|
173
|
289
|
|
174
|
|
-### Special cases
|
|
290
|
+<a name="rolling-out-updates-automatic"/>
|
175
|
291
|
|
176
|
|
-#### Build your own image
|
|
292
|
+##### 4.2.2. Automatic updates and auto-start
|
|
293
|
+
|
|
294
|
+Use the scripts provided.
|
|
295
|
+
|
|
296
|
+```
|
|
297
|
+sudo ln -s /home/ubuntu/scalelite-run/scripts/deploy.sh /usr/local/bin/scalelite-deploy
|
|
298
|
+sudo cp /home/ubuntu/scalelite-run/scripts/scalelite-auto-deployer.service /etc/systemd/system/scalelite-auto-deployer.service
|
|
299
|
+sudo cp /home/ubuntu/scalelite-run/scripts/scalelite-auto-deployer.timer /etc/systemd/system/scalelite-auto-deployer.timer
|
|
300
|
+sudo systemctl daemon-reload
|
|
301
|
+sudo systemctl enable scalelite-auto-deployer.service
|
|
302
|
+sudo systemctl enable scalelite-auto-deployer.timer
|
|
303
|
+sudo systemctl start scalelite-auto-deployer.timer
|
|
304
|
+```
|
|
305
|
+
|
|
306
|
+<a name="distributed-deployment"/>
|
|
307
|
+
|
|
308
|
+## II. Distributed Deployment
|
|
309
|
+
|
|
310
|
+On a real production environment Scalelite should be deployed using distributed services in the cloud (or virtual private cloud) through a cloud computing provider like [AWS](https://aws.amazon.com/), [Google Cloud](https://cloud.google.com/), [Azure](https://azure.microsoft.com/en-ca/), [Digital Ocean](https://www.digitalocean.com/), [Alibaba Cloud](https://www.alibabacloud.com/), etc.
|
|
311
|
+
|
|
312
|
+Contact us at [Blindside Networks Contact](https://blindsidenetworks.com/contact/) getting recommendations on best practices with any of those cloud providers.
|
|
313
|
+
|
|
314
|
+<a name="special-cases"/>
|
|
315
|
+
|
|
316
|
+## III. Special cases
|
|
317
|
+
|
|
318
|
+<a name="building-docker-image"/>
|
|
319
|
+
|
|
320
|
+### Building Docker image
|
177
|
321
|
|
178
|
322
|
If no access to the DockerHub registry is available, it is still possible to build the image. Either by running `docker build` where scalelite code is placed, or using the build script provided in this repo at `scripts/build.sh`. The only advantage of using the script is that the last commit is included as the build number.
|
179
|
323
|
|
|
@@ -191,28 +335,63 @@ cd <YOUR ROOT>/scalelite
|
191
|
335
|
|
192
|
336
|
Keep in mind that the docker-compose.yml script makes use of some other configuration files that are mounted inside the containers. If any modification to nginx is needed it has to be done on the sites.template file. Also, whatever name is chosen for the image should match the one used in docker-compose.yml.
|
193
|
337
|
|
194
|
|
-#### Setup SSL certificate from a CA other than letsencrypt
|
|
338
|
+<a name="removing-ssl-certificate"/>
|
195
|
339
|
|
196
|
|
-For adding an SSL certificate from an CA other than letsencrypt,
|
|
340
|
+### Removing SSL Certificate
|
197
|
341
|
|
198
|
|
-1. DO NOT execute the `./init-letsencrypt.sh` script
|
|
342
|
+DO NOT execute the `./init-letsencrypt.sh` script
|
199
|
343
|
|
200
|
|
-2. Place the SSL Certificate, Intermediate Certificate (or Bundle with both of them if you have it) and Private Key files inside `nginx/ssl` as fullchain.pem and privkey.pem.
|
201
|
|
-E.g.
|
202
|
|
-```
|
203
|
|
-cd ~/
|
204
|
|
-cat your_domain_name.crt Intermediate.crt >> bundle.crt
|
205
|
|
-cp bundle.crt <YOUR ROOT>/scalelite/nginx/ssl/fullchain.pem
|
206
|
|
-cp private.key <YOUR ROOT>/scalelite/nginx/ssl/privkey.pem
|
207
|
|
-```
|
208
|
|
-
|
209
|
|
-3. Edit the template for nginx.
|
|
344
|
+Edit the template for nginx.
|
210
|
345
|
```
|
211
|
346
|
cd <YOUR ROOT>/scalelite
|
212
|
347
|
vi nginx/sites.template
|
213
|
348
|
```
|
214
|
|
-Comment the lines referencing the letsencrypt Certificate and uncomment the other two
|
215
|
|
-
|
216
|
|
-4. Comment out in `docker-compose.yml` the certbot container.
|
217
|
|
-
|
218
|
|
-5. Start the containers as usual.
|
|
349
|
+Comment out all the lines from 13 to 34. The sites.template file should look like this:
|
|
350
|
+
|
|
351
|
+```
|
|
352
|
+...
|
|
353
|
+listen [::]:80;
|
|
354
|
+
|
|
355
|
+# location /.well-known/acme-challenge/ {
|
|
356
|
+# root /var/www/certbot;
|
|
357
|
+# }
|
|
358
|
+#
|
|
359
|
+# location / {
|
|
360
|
+# return 301 https://$host$request_uri;
|
|
361
|
+# }
|
|
362
|
+#}
|
|
363
|
+#
|
|
364
|
+#server {
|
|
365
|
+# server_name $NGINX_HOSTNAME;
|
|
366
|
+#
|
|
367
|
+# listen 443 ssl;
|
|
368
|
+# listen [::]:443;
|
|
369
|
+#
|
|
370
|
+# ## Configuration for Letsencrypt SSL Certificate
|
|
371
|
+# ssl_certificate /etc/letsencrypt/live/$NGINX_HOSTNAME/fullchain.pem;
|
|
372
|
+# ssl_certificate_key /etc/letsencrypt/live/$NGINX_HOSTNAME/privkey.pem;
|
|
373
|
+#
|
|
374
|
+# ## Configuration for SSL Certificate from a CA other than Letsencrypt
|
|
375
|
+# #ssl_certificate /etc/ssl/fullchain.pem;
|
|
376
|
+# #ssl_certificate_key /etc/ssl/privkey.pem;
|
|
377
|
+
|
|
378
|
+ location / {
|
|
379
|
+...
|
|
380
|
+```
|
|
381
|
+
|
|
382
|
+Comment out in `docker-compose.yml` the certbot container. After that, it should look like this:
|
|
383
|
+
|
|
384
|
+```
|
|
385
|
+...
|
|
386
|
+## Configuration for Letsencrypt SSL Certificate
|
|
387
|
+## comment out when using an SSL Certificate from a CA other than Letsencrypt
|
|
388
|
+# certbot:
|
|
389
|
+# image: certbot/certbot
|
|
390
|
+# volumes:
|
|
391
|
+# - ./data/certbot/conf:/etc/letsencrypt
|
|
392
|
+# - ./data/certbot/www:/var/www/certbot
|
|
393
|
+# entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
|
394
|
+...
|
|
395
|
+```
|
|
396
|
+
|
|
397
|
+Start the containers as usual.
|