-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
1532 lines (1076 loc) · 159 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>What is ContinuousPipe? on ContinuousPipe Docs</title>
<link>/docs/index.xml</link>
<description>Recent content in What is ContinuousPipe? on ContinuousPipe Docs</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-gb</language>
<copyright>Released under the MIT license</copyright>
<atom:link href="/docs/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Accounts: How do I create a billing profile?</title>
<link>/docs/faq/how-do-I-create-a-billing-profile/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/faq/how-do-I-create-a-billing-profile/</guid>
<description><p>To create a billing profile you will first need to log into the <a href="https://your-ui.example.com/">ContinuousPipe console</a>. You then need to navigate to the Account section using the sub menu in the top right corner.</p>
<p><img src="/docs/docs/images/faq/billing-account-menu.png" alt="" /></p>
<p>Within the account section, select the &ldquo;Billing&rdquo; tab. You will need to select how many users you would like to subscribe. The number of users is effectively the number of people who will have GitHub or Bitbucket accounts that will be pushing to repositories set up in a ContinuousPipe.</p>
<p><img src="/docs/docs/images/faq/billing-create-subscription.png" alt="" /></p>
<p>If you click on &ldquo;Subscribe&rdquo; a window will open to <a href="https://recurly.com/">Recurly</a>, which is a third party payment subscription handler. Follow the instructions to complete payment.</p>
<p><img src="/docs/docs/images/faq/billing-recurly-interface.png" alt="" /></p>
<p>You can also adjust the number of users up or down at this stage:</p>
<p><img src="/docs/docs/images/faq/billing-adjust-users.png" alt="" /></p>
<p>After payment is completed, the &ldquo;Billing&rdquo; tab in the ContinuousPipe account section should now display subscription information.</p>
<p><img src="/docs/docs/images/faq/billing-display-subscription.png" alt="" /></p>
</description>
</item>
<item>
<title>General: What are the ContinuousPipe images?</title>
<link>/docs/faq/what-are-the-continuous-pipe-images/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/faq/what-are-the-continuous-pipe-images/</guid>
<description><p>ContinuousPipe provides images for many common technologies that you may need to use in your application infrastructure.</p>
<p>Some examples are:</p>
<ul>
<li><a href="https://quay.io/repository/continuouspipe/php7.1-nginx">PHP with Nginx</a></li>
<li><a href="https://quay.io/repository/continuouspipe/php7.1-apache">PHP with Apache</a></li>
<li><a href="https://quay.io/repository/continuouspipe/mysql8.0">MYSQL</a></li>
<li><a href="https://quay.io/repository/continuouspipe/redis3">Redis</a></li>
<li><a href="https://quay.io/repository/continuouspipe/solr6">Solr</a></li>
<li><a href="https://quay.io/repository/continuouspipe/varnish4">Varnish</a></li>
</ul>
<p>The full range of images can be seen at <a href="https://quay.io/organization/continuouspipe">https://quay.io/organization/continuouspipe</a>.</p>
<p>The Docker configuration used to create the images can be seen at <a href="https://github.com/continuouspipe/dockerfiles">https://github.com/continuouspipe/dockerfiles</a>.</p>
<p>Any of the images can be used by referencing them in your <code>Dockerfile</code>:</p>
<pre><code>FROM quay.io/continuouspipe/php7.1-apache:stable
</code></pre>
<p>The benefit of using ContinuousPipe images are that they have been created according to best practices on security and performance. For example, the Apache and Nginx server images are automatically configured to use HTTPS only websites and install self signed SSL certificate on container start. More information about the specific setup of each image is provided in the README for each image within <a href="https://github.com/continuouspipe/dockerfiles">https://github.com/continuouspipe/dockerfiles</a>.</p>
<p>ContinuousPipe images are also compatible with the <a href="/docs/docs/remote-development/getting-started/">remote development</a> functionality without any additional configuration.</p>
</description>
</item>
<item>
<title>General: What are the ContinuousPipe demo sites?</title>
<link>/docs/faq/what-are-the-continuous-pipe-demo-sites/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/faq/what-are-the-continuous-pipe-demo-sites/</guid>
<description><p>ContinuousPipe provides some sample applications for common frameworks:</p>
<ul>
<li><a href="https://github.com/continuouspipe/demo-symfony">Symfony</a></li>
<li><a href="https://github.com/continuouspipe/demo-laravel">Laravel</a></li>
<li><a href="https://github.com/continuouspipe/demo-drupal7">Drupal 7</a></li>
<li><a href="https://github.com/continuouspipe/demo-drupal8">Drupal 8</a></li>
<li><a href="https://github.com/continuouspipe/demo-magento1">Magento 1</a></li>
<li><a href="https://github.com/continuouspipe/demo-magento2">Magento 2</a></li>
</ul>
<p>They can be used to get an environment running quickly or as a basis for further adaptation to suit the needs of your own organisation.</p>
<p>The demo sites are built on top of <a href="/docs/docs/faq/what-are-the-continuous-pipe-images/">ContinuousPipe images</a> so they take advantage of their security and performance best practices.</p>
</description>
</item>
<item>
<title>Console: Where can I get a ContinuousPipe API key?</title>
<link>/docs/faq/where-can-I-get-a-continuous-pipe-api-key/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/faq/where-can-I-get-a-continuous-pipe-api-key/</guid>
<description>
<h2 id="continuouspipe-api-keys">ContinuousPipe API Keys</h2>
<p>ContinuousPipe API keys can be used with the <code>cp-remote</code> tool in <a href="/docs/docs/remote-development/working-with-different-environments/#interactive-mode">interactive mode</a> to access a bash terminal on a deployed container.</p>
<h2 id="creating-a-continuouspipe-api-key">Creating a ContinuousPipe API Key</h2>
<p>You can generate a new API key in the account section of the console: <a href="https://your-api.example.com/account/api-keys">https://your-api.example.com/account/api-keys</a>.</p>
<p>To create a new API key, enter a description in the &ldquo;New key&rdquo; form:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/account-api-key-new.png" />
</figure>
<p>The new key will then be visible in list of keys:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/account-api-key-view.png" />
</figure>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you have already built a remote development environment using <code>cp-remote init &lt;token&gt;</code> an API key will already have been generated for you and stored in the global configuration file <code>~/.cp-remote/config.yml</code>.</p>
</div>
</description>
</item>
<item>
<title>Console: Where can I view container logs and events?</title>
<link>/docs/faq/where-can-I-view-container-logs-and-events/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/faq/where-can-I-view-container-logs-and-events/</guid>
<description>
<h2 id="container-logs">Container Logs</h2>
<p>When a container is deployed, Kubernetes generates log and event information, which is useful for debugging when your deployments are failing. ContinuousPipe gives you access to this information in the console without having to access the container directly.</p>
<h2 id="viewing-the-container-logs-from-the-tide-log-screen">Viewing the Container Logs From the Tide Log Screen</h2>
<p>You can view the container logs and events from the tide log screen of a flow.</p>
<p>First expand the tab for the container (referred to as component) you want to review, then click the hamburger icon of the container in the bottom right corner:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/flow-tide-logs-open-cp-logs.png" />
</figure>
<p>By default you will see the &ldquo;LOGS&rdquo; tab which displays a real time view of the container logs:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/flow-tide-logs-view-cp-logs.png" />
</figure>
<p>If you click on the &ldquo;EVENTS&rdquo; tab you will see a list of events associated with the container deployment:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/flow-tide-logs-view-cp-events.png" />
</figure>
<h2 id="viewing-the-container-logs-from-the-environment-screen">Viewing the Container Logs From the Environment Screen</h2>
<p>You can also view the container logs and events from the environment screen of a flow.</p>
<p>Click on the environment to expand it, then click the hamburger icon for the container (referred to as component) you want to review:</p>
<figure class="three-quarter-width">
<img src="/docs/docs/images/faq/flow-environment-open-cp-logs.png" />
</figure>
</description>
</item>
<item>
<title>Configuration Files</title>
<link>/docs/configuration/configuration-files/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/configuration/configuration-files/</guid>
<description>
<p>There are three main configuration files that are needed to build a Docker image and set up ContinuousPipe deployments:</p>
<pre><code>.
├── Dockerfile
├── continuous-pipe.yml
└── docker-compose.yml
</code></pre>
<h2 id="docker-build-configuration">Docker Build Configuration</h2>
<p>The <code>Dockerfile</code> contains a series of commands that are combined to build a Docker image. See <a href="https://docs.docker.com/engine/reference/builder/">https://docs.docker.com/engine/reference/builder/</a> for full documentation.</p>
<h2 id="docker-compose-configuration">Docker Compose Configuration</h2>
<p>The file <code>docker-compose.yml</code> contains YAML configuration for the services, networks and volumes of a Docker image. See <a href="https://docs.docker.com/compose/compose-file/">https://docs.docker.com/compose/compose-file/</a> for full documentation.</p>
<h2 id="continuouspipe-configuration">ContinuousPipe Configuration</h2>
<p>The ContinuousPipe configuration is represented as a YAML file. The final configuration is the result of a merger of these different optional configuration sources:</p>
<ul>
<li>The YAML stored on CP when <a href="/docs/docs/quick-start/configuring-a-flow/">configuring a flow</a></li>
<li>The YAML file named <code>continuous-pipe.yml</code> in your code repository</li>
<li>The YAML file named <code>continuous-pipe.[branch].yml</code> in your code repository</li>
</ul>
<h3 id="tasks">Tasks</h3>
<p>The main objects of this configuration file are the <code>tasks</code>.</p>
<p>Each task has a name, so will sometimes be referred to as a &ldquo;named task&rdquo;. Tasks will run sequentially in the order they are defined.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>It is recommended that all tasks are named as some features rely on this to make task information available to other tasks.</p>
</div>
<p>In the following example, you can see that we define <code>build</code>, <code>deploy</code>, and <code>run</code> tasks named <code>images</code>, <code>deployment</code>, and <code>migrations</code> respectively. They will operate in this order when a tide is run.</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">tasks</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">images</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">build</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
<span style="color: #ae81ff">deployment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deploy</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
<span style="color: #ae81ff">migrations</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">run</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
</pre></div>
<p>You will learn more about each task in the <a href="/docs/docs/configuration/tasks/">tasks overview section</a>.</p>
<h3 id="variables">Variables</h3>
<p>You can avoid copying and pasting by using variables inside your configuration files. The following example shows you how to prevent putting values inside your <code>continuous-pipe.yml</code> by using variables that are defined in the configuration stored in ContinuousPipe when <a href="/docs/docs/quick-start/configuring-a-flow/">configuring a flow</a>.</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e"># configuration in ContinuousPipe</span>
<span style="color: #ae81ff">environment_variables</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #f8f8f2">{</span> <span style="color: #f8f8f2">name:</span> <span style="color: #f8f8f2">CLUSTER,</span> <span style="color: #f8f8f2">value:</span> <span style="color: #f8f8f2">my-production-cluster</span> <span style="color: #f8f8f2">}</span>
<span style="color: #75715e"># configuration in continuous-pipe.yml</span>
<span style="color: #ae81ff">tasks</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
<span style="color: #ae81ff">deployment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deploy</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">${CLUSTER}</span>
<span style="color: #75715e"># ...</span>
</pre></div>
<p>Once the configuration files are merged, the variables are resolved. That means that the final configuration will contain the <code>my-production-cluster</code> value at the <code>cluster</code> key of the deployment task.</p>
<h3 id="conditional-variables">Conditional Variables</h3>
<div class="admonition note">
<p class="admonition-title">Reference</p>
<p>Conditions use the <a href="http://symfony.com/doc/current/components/expression_language/syntax.html">Symfony expression language</a>.</p>
</div>
<p>If you need to change the value of the cluster, for instance depending on the branch name, you can use conditions:</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">environment_variables</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #f8f8f2">{</span> <span style="color: #f8f8f2">name:</span> <span style="color: #f8f8f2">CLUSTER,</span> <span style="color: #f8f8f2">condition:</span> <span style="color: #e6db74">&#39;code_reference.branch</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">in</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">[&quot;production&quot;,</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">&quot;uat&quot;]&#39;</span><span style="color: #f8f8f2">,</span> <span style="color: #f8f8f2">value:</span> <span style="color: #f8f8f2">my-production-cluster</span> <span style="color: #f8f8f2">}</span>
<span style="color: #f8f8f2">-</span> <span style="color: #f8f8f2">{</span> <span style="color: #f8f8f2">name:</span> <span style="color: #f8f8f2">CLUSTER,</span> <span style="color: #f8f8f2">condition:</span> <span style="color: #e6db74">&#39;code_reference.branch</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">not</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">in</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">[&quot;production&quot;,</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">&quot;uat&quot;]&#39;</span><span style="color: #f8f8f2">,</span> <span style="color: #f8f8f2">value:</span> <span style="color: #f8f8f2">my-development-cluster</span> <span style="color: #f8f8f2">}</span>
</pre></div>
<p>The <code>condition</code> value is an expression. It has access to the tide related context object <code>code_reference</code>.</p>
<p>The <code>code_reference</code> context object contains the following properties:</p>
<table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>branch</code></td>
<td>string</td>
<td>The name of the branch</td>
</tr>
<tr>
<td><code>sha1</code></td>
<td>string</td>
<td>The SHA1 of the given commit</td>
</tr>
</tbody>
</table>
<h3 id="default-variables">Default Variables</h3>
<p>You can use a <code>defaults</code> section to avoid variable duplication across tasks.</p>
<p>The following example shows a <code>cluster</code> variable being defined in two separate tasks:</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">tasks</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">initialise</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">run</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">my-cluster</span>
<span style="color: #75715e"># ...</span>
<span style="color: #ae81ff">deployments</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deploy</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">my-cluster</span>
<span style="color: #75715e"># ...</span>
</pre></div>
<p>This can be rewritten using a <code>defaults</code> section as follows:</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">defaults</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">my-cluster</span>
<span style="color: #ae81ff">tasks</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">initialise</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">run</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
<span style="color: #ae81ff">deployments</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deploy</span><span style="color: #f8f8f2">:</span>
<span style="color: #75715e"># ...</span>
</pre></div>
<p>The default cluster variable will now be used for both tasks instead.</p>
</description>
</item>
<item>
<title>ContinuousPipe</title>
<link>/docs/basics/continuous-pipe/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/basics/continuous-pipe/</guid>
<description>
<h2 id="what-is-continuouspipe">What is ContinuousPipe?</h2>
<p>ContinuousPipe is a system for continuous automated deployment of multiple environments with simple configuration. It utilises Docker and Kubernetes to automatically deploy new environments, dramatically speeding up your feedback loop and cutting lead time.</p>
<h2 id="technology-stack">Technology Stack</h2>
<p>ContinuousPipe allows you to deploy your <a href="/docs/docs/basics/concepts-build-concepts/">Docker application</a> on any <a href="/docs/docs/basics/concepts-deployment-concepts/">Kubernetes cluster</a>.</p>
<figure class="diagram technology-stack">
<img src="/docs/docs/images/basics/cp-technology-stack.png" />
</figure>
<h2 id="getting-started">Getting Started</h2>
<p>To get started with ContinuousPipe you will need the following:</p>
<ul>
<li>A <a href="https://github.com/">GitHub</a> or <a href="https://bitbucket.org/">Bitbucket</a> account to host your project</li>
<li>A Docker registry account e.g. <a href="https://docker.io">docker.io</a> or <a href="https://quay.io">quay.io</a></li>
<li>A Kubernetes cluster e.g. <a href="https://cloud.google.com/container-engine/">GCE</a>, <a href="https://aws.amazon.com/">AWS</a> or <a href="https://azure.microsoft.com/en-au/">Azure</a></li>
</ul>
<h2 id="customizable-workflow">Customizable Workflow</h2>
<p>The <a href="/docs/docs/basics/workflow-principles/">customizable workflow</a> allows you to integrate developers, QA and product owners to produce super-fast feedback cycles on a feature-by-feature basis.</p>
</description>
</item>
<item>
<title>Creating a Project</title>
<link>/docs/quick-start/creating-a-project/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/quick-start/creating-a-project/</guid>
<description><p>When you log in for the first time you will see the project overview screen, which will be empty. You&rsquo;ll be prompted to create a new project.</p>
<p><img src="/docs/docs/images/quick-start/project-overview-no-project.png" alt="" /></p>
<p>To create a project, just click the &ldquo;CREATE A PROJECT&rdquo; button in the top right of the interface.</p>
<p>You will then be asked to enter the following:</p>
<ul>
<li><strong>Name</strong> - A name for your project</li>
<li><strong>Unique Identifier</strong> - An identifier for your project, which needs to not be in use by anyone else.</li>
</ul>
<p>The project will not be created until a unique identifier is found. You will be told if the identifier is already in use when you click &ldquo;CREATE&rdquo;.</p>
<p>The new project will now be visible in the project overview screen.</p>
<p><img src="/docs/docs/images/quick-start/project-overview-new-project.png" alt="" /></p>
</description>
</item>
<item>
<title>Getting Started</title>
<link>/docs/remote-development/getting-started/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/remote-development/getting-started/</guid>
<description>
<p>ContinuousPipe can be used as a remote development environment using the <code>cp-remote</code> command line tool. It helps to create, build and destroy remote environments and keep files in sync with the local filesystem.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>You will need the following:</p>
<ul>
<li>A ContinuousPipe hosted project with the GitHub or Bitbucket, Docker and Kubernetes integration set up</li>
<li>The project checked out locally</li>
<li><code>rsync</code> installed locally</li>
<li>Optionally, a <a href="https://keen.io">keen.io</a> write token, project id and event collection name if you want to log usage stats</li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If the GitHub or Bitbucket repository is not the origin of your checked out project then you will need to add a <a href="https://help.github.com/articles/adding-a-remote/">Git remote</a> for that repository.</p>
</div>
<h2 id="installation">Installation</h2>
<h3 id="osx-64-bit">OSX (64-bit):</h3>
<p>If you use <a href="https://brew.sh/">Homebrew</a>, you can install <code>cp-remote</code> via:</p>
<pre><code>brew install continuouspipe/tools/cp-remote
</code></pre>
<p>Otherwise you can install it manually via:</p>
<pre><code>sudo curl https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/darwin-amd64/cp-remote.tar.gz &gt; cp-remote.tar.gz
tar -xzvf cp-remote.tar.gz;
mv cp-remote /usr/local/bin/cp-remote
</code></pre>
<p><strong>Dependencies:</strong> You need to have <code>git</code>, and <code>rsync</code> installed and available in the shell where <code>cp-remote</code> runs.</p>
<h3 id="linux-64-bit">Linux (64-bit):</h3>
<pre><code>sudo curl https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/linux-amd64/cp-remote.tar.gz &gt; cp-remote.tar.gz
tar -xzvf cp-remote.tar.gz;
mv cp-remote /usr/local/bin/cp-remote
</code></pre>
<h3 id="linux-32-bit">Linux (32-bit):</h3>
<pre><code>sudo curl https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/linux-386/cp-remote.tar.gz &gt; cp-remote.tar.gz
tar -xzvf cp-remote.tar.gz;
mv cp-remote /usr/local/bin/cp-remote
</code></pre>
<p><strong>Dependencies:</strong> You need to have <code>git</code>, and <code>rsync</code> installed and available in the shell where <code>cp-remote</code> runs.</p>
<h3 id="windows-64-bit">Windows (64-bit):</h3>
<ul>
<li>Download <a href="https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/windows-amd64/cp-remote.zip">https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/windows-amd64/cp-remote.zip</a></li>
<li>Extract <code>cp-remote.zip</code></li>
<li>Move <code>cp-remote.exe</code> into your project folder</li>
</ul>
<h3 id="windows-32-bit">Windows (32-bit):</h3>
<ul>
<li>Download <a href="https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/windows-386/cp-remote.zip">https://inviqa-cp-remote-client-environment.s3-eu-west-1.amazonaws.com/latest/windows-386/cp-remote.zip</a></li>
<li>Extract <code>cp-remote.zip</code></li>
<li>Move <code>cp-remote.exe</code> into your project folder</li>
</ul>
<p><strong>Dependencies:</strong> You need to have <code>git</code>, and <code>cwRsync</code> installed and available in your environment <code>PATHS</code> variable.</p>
<h2 id="quick-start">Quick Start</h2>
<p>The quick start guide gives an overview of how to get running with remote development:</p>
<ul>
<li><a href="/docs/docs/quick-start/remote-development-configuring-your-repository/">Remote Development: Configuring Your Repository</a></li>
<li><a href="/docs/docs/quick-start/remote-development-creating-a-remote-environment/">Remote Development: Creating a Remote Environment</a></li>
<li><a href="/docs/docs/quick-start/remote-development-using-a-remote-environment/">Remote Development: Using a Remote Environment</a></li>
</ul>
<h2 id="data-sharing">Data Sharing</h2>
<p><strong>ContinuousPipe receives usage and diagnostic information for each cp-remote command executed. This allows errors to be detected and fixed as soon as possible.</strong></p>
<p>Summary of information received:</p>
<ul>
<li>The <code>cp-remote</code> version number</li>
<li>The operating system and system architecture (Linux, Windows or Mac)</li>
<li>The command name including arguments (excluding the init token)</li>
<li>The duration of the command</li>
<li>The success/failure code of the command</li>
<li>Some configuration settings (username, flow id, cluster id, environment id, remote branch name, service name, Kubernetes cluster user and address)</li>
<li>Any file names configured to be ignored (if present)</li>
<li>Any error stack (if present)</li>
</ul>
</description>
</item>
<item>
<title>Getting Started with Laravel</title>
<link>/docs/guides/laravel/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>/docs/guides/laravel/</guid>
<description>
<h2 id="introduction">Introduction</h2>
<p>In this tutorial we are going to setup a new Laravel project, run it within Docker using one of ContinuousPipe’s base Dockerfiles, then finally push our project to our GitHub repo where ContinuousPipe will build our project and deploy on Google Container Engine. Once we are happy our project is building successfully we will then use ContinuousPipe to manage our cloud based development environment with the <code>cp-remote</code> CLI tool.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Before getting started you will need the following -</p>
<ul>
<li>A <a href="https://github.com/">GitHub</a> or <a href="https://bitbucket.org/">Bitbucket</a> account to host your Laravel project</li>
<li>A <a href="https://continuouspipe.github.io/">ContinuousPipe</a> account</li>
<li>A Kubernetes cluster e.g. <a href="https://aws.amazon.com/">AWS</a>, <a href="https://cloud.google.com/container-engine/">GCE</a> or <a href="https://azure.microsoft.com/en-au/">Azure</a></li>
<li>A Docker Registry account e.g. <a href="https://docker.io">docker.io</a> or <a href="https://quay.io">quay.io</a></li>
</ul>
<h2 id="setting-up-laravel">Setting up Laravel</h2>
<p>The easiest way to install Laravel is with the Laravel installer, if you don’t have this you can simply follow the instructions to use composer instead. For simplicity we will use the Laravel installer.</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span>$ laravel new demo-laravel
</pre></div>
<p>Since we used the Laravel installer, a <code>.env</code> file has been created for us and an application key has been set i.e.</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #f8f8f2">APP_KEY</span><span style="color: #f92672">=</span>base64:OQ8H9vjocvQh284ojDBrODQ2HkrgWGDvdLCaQniHz0M<span style="color: #f92672">=</span>
</pre></div>
<p>During our deployments, Laravel needs this key after the composer install runs due to the post-install composer hook. Unfortunately we will not have a <code>.env</code> file set at this point so the easiest way to by pass this would be to set a default <code>APP_KEY.</code> Within <code>config/app.php</code> change line 106</p>
<p>from -</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #e6db74">&#39;key&#39;</span> <span style="color: #f92672">=&gt;</span> <span style="color: #a6e22e">env</span><span style="color: #f8f8f2">(</span><span style="color: #e6db74">&#39;APP_KEY&#39;</span><span style="color: #f8f8f2">),</span>
</pre></div>
<p>to -</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #e6db74">&#39;key&#39;</span> <span style="color: #f92672">=&gt;</span> <span style="color: #a6e22e">env</span><span style="color: #f8f8f2">(</span><span style="color: #e6db74">&#39;APP_KEY&#39;</span><span style="color: #f8f8f2">,</span> <span style="color: #e6db74">&#39;base64:OQ8H9vjocvQh284ojDBrODQ2HkrgWGDvdLCaQniHz0M=&#39;</span><span style="color: #f8f8f2">),</span>
</pre></div>
<p>We will overwrite the default key during deployments.</p>
<p>Since we are going to configure our application to use redis for our cache and session storage we need to add the package <code>predis/predis</code> to our project.</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span>$ composer require predis/predis
</pre></div>
<h2 id="configuring-continuouspipe">Configuring ContinuousPipe</h2>
<p>Before we can push any code to our repository, we need to ensure that the ContinuousPipe console is properly configured. Please refer to the ContinuousPipe Quick Start guide to setup your <a href="/docs/docs/quick-start/creating-a-project/">project</a>, <a href="/docs/docs/quick-start/configuring-a-cluster/">cluster</a>, <a href="/docs/docs/quick-start/configuring-a-registry/">registry</a> and create your first <a href="/docs/docs/quick-start/creating-a-flow/">flow</a>.</p>
<p>One last thing we need to do before we can begin using ContinuousPipe is configure which cluster we will use. You are free to configure as many clusters as you wish, in fact, its a good idea to have a separate cluster from production as you would for development and testing.</p>
<p>For now we have only got one cluster configured in ContinuousPipe. Lets assign that cluster name “main-cluster” to an environment variable which can be used with our build and deployment tasks.</p>
<p>From within the flow, click on configuration in the sidebar, create a new environment variable named <code>CLUSTER</code> with a value to match what you set as your cluster name/identifier. I have set my cluster name as <code>main-cluster</code>. Finally save the configuration.</p>
<p><img src="/docs/docs/images/guides/laravel/flow-variables-configuration.png" alt="Flow Configuration" /></p>
<h3 id="adding-docker-configuration">Adding Docker configuration</h3>
<p>Lets start by configuring our <code>Dockerfile</code>. We are going to use one of the <a href="/docs/docs/faq/what-are-the-continuous-pipe-images/">ContinuousPipe images</a> as our base. In reality, you would want to create a new base image that would extend this image to give you the ability to add other services, such as your NodeJS dependencies often used for the frontend build tools i.e. webpack</p>
<blockquote>
<p><strong>Dockerfile</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #66d9ef">FROM</span><span style="color: #e6db74"> quay.io/continuouspipe/php7-nginx:stable</span>
COPY ./tools/docker/usr/ /usr/
USER build
<span style="color: #75715e"># Add the application</span>
COPY . /app
<span style="color: #66d9ef">WORKDIR</span><span style="color: #e6db74"> /app</span>
USER root
<span style="color: #75715e"># Install dependencies</span>
ARG <span style="color: #f8f8f2">APP_ENV</span><span style="color: #f92672">=</span>
<span style="color: #66d9ef">RUN</span> chown -R build:build /app <span style="color: #f92672">&amp;&amp;</span> <span style="color: #ae81ff">\</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> -n <span style="color: #e6db74">&quot;</span><span style="color: #f8f8f2">$APP_ENV</span><span style="color: #e6db74">&quot;</span> <span style="color: #f92672">]</span><span style="color: #f8f8f2">;</span> <span style="color: #66d9ef">then</span> <span style="color: #ae81ff">\</span>
bash /app/tools/docker/setup/install.sh<span style="color: #f8f8f2">;</span> <span style="color: #ae81ff">\</span>
<span style="color: #66d9ef">fi</span>
</pre></div>
</blockquote>
<p>You will notice from the second line of our Dockerfile that it will copy <code>tools/docker/usr/</code> to <code>/usr/</code> This is put in place by the inheritance of the configuration from our base image. Its parent image, <a href="https://github.com/continuouspipe/dockerfiles/tree/master/ubuntu/16.04#default-environment-variables">Ubuntu Base</a> allows us to inject custom environment variables into our container at build time. This allows us to easily manipulate how the build is configured. For example, we can use these to define our web directory which is used to set the nginx vhost <code>root</code> configuration.</p>
<h3 id="setting-additional-docker-required-files">Setting additional Docker required files</h3>
<p>Lets create a new file in <code>tools/docker/usr/local/bin/supervisor_custom_start-laravel</code> with the following -</p>
<blockquote>
<p><strong>tools/docker/usr/local/bin/supervisor_custom_start-laravel</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e">#!/bin/bash</span>
<span style="color: #75715e"># Bring in the as_code_owner function, to run commands as the user who owns the code.</span>
<span style="color: #75715e"># Usually the &quot;build&quot; user.</span>
<span style="color: #f8f8f2">source</span> /usr/local/share/bootstrap/common_functions.sh
bash /app/tools/docker/setup/install.sh
<span style="color: #75715e"># Create env file if missing</span>
bash /app/tools/docker/setup/setup-dotenv.sh
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;</span><span style="color: #f8f8f2">$REMOTE_ENV</span><span style="color: #e6db74">&quot;</span> <span style="color: #f92672">=</span> <span style="color: #e6db74">&quot;1&quot;</span> <span style="color: #f92672">]</span><span style="color: #f8f8f2">;</span> <span style="color: #66d9ef">then</span>
as_code_owner <span style="color: #e6db74">&quot;php artisan key:generate&quot;</span>
<span style="color: #66d9ef">fi</span>
</pre></div>
</blockquote>
<p>The comments should make it clear what each line does however, there are few additional files included in this script we need to create. First is our <code>install.sh</code> script, this will do our initial folder setup, run composer install and then set the correct file and folder permissions across our project.</p>
<p>The second included script is used to create our <code>.env</code> file from our environment variables. Even though technically Laravel can read our environment variables directly, the file needs to exist to generate a new key as Laravel will save the generated key to this file.</p>
<p>Lets add these files into <code>tools/docker/setup</code> -</p>
<blockquote>
<p><strong>tools/docker/setup/install.sh</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e">#!/bin/bash</span>
<span style="color: #f8f8f2">set</span> -xe
<span style="color: #75715e"># Source variables such as what user the site will be running as</span>
<span style="color: #f8f8f2">source</span> /usr/local/share/bootstrap/setup.sh
<span style="color: #75715e"># Bring in the composer running function</span>
<span style="color: #f8f8f2">source</span> /usr/local/share/php/common_functions.sh
<span style="color: #f8f8f2">APP_PATH</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;/app&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #75715e"># Create missing directories</span>
/app/tools/docker/setup/setup-directories.sh
<span style="color: #75715e"># Install the app</span>
<span style="color: #f8f8f2">cd</span> <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">APP_PATH</span><span style="color: #e6db74">}&quot;</span> <span style="color: #f92672">||</span> <span style="color: #f8f8f2">exit</span> <span style="color: #ae81ff">1</span><span style="color: #f8f8f2">;</span>
run_composer
chown -R <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">CODE_OWNER</span><span style="color: #e6db74">}:${</span><span style="color: #f8f8f2">APP_GROUP</span><span style="color: #e6db74">}&quot;</span> bootstrap/cache/ storage
chmod -R ug+rw,o-w bootstrap/cache/ storage/
chmod +x storage
</pre></div>
<p><strong>tools/docker/setup/setup-dotenv.sh</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e">#!/bin/sh</span>
<span style="color: #f8f8f2">set</span> -xe
<span style="color: #f8f8f2">ENV_FILE</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;/app/.env&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> ! -f <span style="color: #e6db74">&quot;</span><span style="color: #f8f8f2">$ENV_FILE</span><span style="color: #e6db74">&quot;</span> <span style="color: #f92672">]</span><span style="color: #f8f8f2">;</span> <span style="color: #66d9ef">then</span>
touch <span style="color: #e6db74">&quot;</span><span style="color: #f8f8f2">$ENV_FILE</span><span style="color: #e6db74">&quot;</span>
<span style="color: #66d9ef">fi</span>
<span style="color: #f92672">{</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;APP_ENV=${</span><span style="color: #f8f8f2">APP_ENV</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">production</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;APP_KEY=${</span><span style="color: #f8f8f2">APP_KEY</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">base64:OQ8H9vjocvQh284ojDBrODQ2HkrgWGDvdLCaQniHz0M=</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;APP_DEBUG=${</span><span style="color: #f8f8f2">APP_DEBUG</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">false</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;APP_URL=${</span><span style="color: #f8f8f2">APP_URL</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">https://laravel-demo.dev</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_CONNECTION=${</span><span style="color: #f8f8f2">DB_CONNECTION</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">mysql</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_HOST=${</span><span style="color: #f8f8f2">DB_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">database</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_PORT=${</span><span style="color: #f8f8f2">DB_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">3306</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_DATABASE=${</span><span style="color: #f8f8f2">DB_DATABASE</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_USERNAME=${</span><span style="color: #f8f8f2">DB_USERNAME</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;DB_PASSWORD=${</span><span style="color: #f8f8f2">DB_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_DRIVER=${</span><span style="color: #f8f8f2">MAIL_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">smtp</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_HOST=${</span><span style="color: #f8f8f2">MAIL_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">mailtrap.io</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_PORT=${</span><span style="color: #f8f8f2">MAIL_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">2525</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_USERNAME=${</span><span style="color: #f8f8f2">MAIL_USERNAME</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_PASSWORD=${</span><span style="color: #f8f8f2">MAIL_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;MAIL_ENCRYPTION=${</span><span style="color: #f8f8f2">MAIL_ENCRYPTION</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;CACHE_DRIVER=${</span><span style="color: #f8f8f2">CACHE_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;SESSION_DRIVER=${</span><span style="color: #f8f8f2">SESSION_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;QUEUE_DRIVER=${</span><span style="color: #f8f8f2">QUEUE_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">database</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;REDIS_HOST=${</span><span style="color: #f8f8f2">REDIS_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;REDIS_PASSWORD=${</span><span style="color: #f8f8f2">REDIS_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;REDIS_PORT=${</span><span style="color: #f8f8f2">REDIS_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">6379</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f92672">}</span> &gt;&gt; <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">ENV_FILE</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #75715e"># Allow the web server user to read this file in, and the build user to run `php artisan key:generate`</span>
chown <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">CODE_OWNER</span><span style="color: #e6db74">}&quot;</span>:<span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">APP_GROUP</span><span style="color: #e6db74">}&quot;</span> <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">ENV_FILE</span><span style="color: #e6db74">}&quot;</span>
chmod <span style="color: #ae81ff">640</span> <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">ENV_FILE</span><span style="color: #e6db74">}&quot;</span>
</pre></div>
</blockquote>
<p>Included from the <code>install.sh</code> file is -</p>
<blockquote>
<p><strong>tools/docker/setup/setup-directories.sh</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e">#!/bin/sh</span>
<span style="color: #f8f8f2">set</span> -xe
<span style="color: #f8f8f2">APP_PATH</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;/app&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #75715e"># Create new directories</span>
<span style="color: #f8f8f2">PUBLIC_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">APP_PATH</span><span style="color: #e6db74">}/public&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">APP_PATH</span><span style="color: #e6db74">}/storage&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #e6db74">}/framework&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">CACHE_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}/cache&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">VIEWS_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}/views&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #f8f8f2">SESSIONS_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}/sessions&quot;</span><span style="color: #f8f8f2">;</span>
<span style="color: #75715e"># Create missing storage directories</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">PUBLIC_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">CACHE_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">VIEWS_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
mkdir -p <span style="color: #e6db74">&quot;${</span><span style="color: #f8f8f2">SESSIONS_DIR</span><span style="color: #e6db74">}&quot;</span><span style="color: #f8f8f2">;</span>
</pre></div>
</blockquote>
<p>Lets now create our custom environment variables file -</p>
<blockquote>
<p><strong>tools/docker/usr/local/share/env/20-project</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #75715e">#!/bin/bash</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">WORK_DIRECTORY</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">WORK_DIRECTORY</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">/app</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">WEB_DIRECTORY</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">WEB_DIRECTORY</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">WORK_DIRECTORY</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/public</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">WORK_DIRECTORY</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/storage</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">UPLOADS_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">UPLOADS_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/app/public/uploads</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">STORAGE_DIR</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/framework</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">CACHE_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">CACHE_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/cache</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">VIEWS_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">VIEWS_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">FRAMEWORK_DIR</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/views</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">SESSIONS_DIR</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">CACHE_DIR</span><span style="color: #66d9ef">:-</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">SESSIONS_DIR</span><span style="color: #e6db74">}</span><span style="color: #f8f8f2">/sessions</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">APP_ENV</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">APP_ENV</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">production</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">APP_KEY</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">APP_KEY</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">base64:OQ8H9vjocvQh284ojDBrODQ2HkrgWGDvdLCaQniHz0M=</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">APP_DEBUG</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">APP_DEBUG</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">false</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">APP_URL</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">APP_URL</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">https://laravel-demo.dev</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_CONNECTION</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_CONNECTION</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">mysql</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_HOST</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">database</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_PORT</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">3306</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_DATABASE</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_DATABASE</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_USERNAME</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_USERNAME</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">DB_PASSWORD</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">DB_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">laravel</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_DRIVER</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">smtp</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_HOST</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">mailtrap.io</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_PORT</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">2525</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_USERNAME</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_USERNAME</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_PASSWORD</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">MAIL_ENCRYPTION</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">MAIL_ENCRYPTION</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">CACHE_DRIVER</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">CACHE_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">SESSION_DRIVER</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">SESSION_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">QUEUE_DRIVER</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">QUEUE_DRIVER</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">database</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">REDIS_HOST</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">REDIS_HOST</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">redis</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">REDIS_PASSWORD</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">REDIS_PASSWORD</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">null</span><span style="color: #e6db74">}</span>
<span style="color: #f8f8f2">export</span> <span style="color: #f8f8f2">REDIS_PORT</span><span style="color: #f92672">=</span><span style="color: #e6db74">${</span><span style="color: #f8f8f2">REDIS_HOST_PORT</span><span style="color: #66d9ef">:-</span><span style="color: #f8f8f2">6379</span><span style="color: #e6db74">}</span>
</pre></div>
</blockquote>
<p>For the majority of this file we are setting environment variables using the default Laravel variables found in the <code>.env</code> file, with a few extras and one exception. The <code>REDIS_PORT</code> being set is looking for an injected variable <code>REDIS_HOST_PORT</code>. This is to mitigate the issue where <code>SERVICENAME_PORT</code> is a reserved keyword in <code>docker-compose</code> which ultimately sets the <code>redis</code> connection to <code>tcp://ip.ad.dr.ress:port</code></p>
<p>For more information on how the custom environment variables are loaded please refer to the main base image <a href="https://github.com/continuouspipe/dockerfiles/tree/master/ubuntu/16.04#default-environment-variables">readme</a></p>
<p>The only thing left to do for our Docker configuration is to setup our <code>docker-compose.yml</code> file.</p>
<blockquote>
<p><strong>docker-compose.yml</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">version</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&quot;2&quot;</span>
<span style="color: #ae81ff">services</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">web</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">build</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">context</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">.</span>
<span style="color: #ae81ff">args</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">APP_ENV</span>
<span style="color: #ae81ff">links</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">database</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">redis</span>
<span style="color: #ae81ff">expose</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">80</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">443</span>
<span style="color: #ae81ff">ports</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #e6db74">&quot;80:80&quot;</span>
<span style="color: #f8f8f2">-</span> <span style="color: #e6db74">&quot;443:443&quot;</span>
<span style="color: #ae81ff">volumes</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">.:/app</span>
<span style="color: #ae81ff">environment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">APP_USER_LOCAL</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&quot;true&quot;</span>
<span style="color: #ae81ff">database</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">image</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">quay.io/continuouspipe/mysql5.7:stable</span>
<span style="color: #ae81ff">environment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">MYSQL_ROOT_PASSWORD</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">laravel</span>
<span style="color: #ae81ff">MYSQL_DATABASE</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">laravel</span>
<span style="color: #ae81ff">MYSQL_USER</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">laravel</span>
<span style="color: #ae81ff">MYSQL_PASSWORD</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">laravel</span>
<span style="color: #ae81ff">expose</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">3306</span>
<span style="color: #ae81ff">ports</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #e6db74">&quot;3360:3360&quot;</span>
<span style="color: #ae81ff">redis</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">image</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">quay.io/continuouspipe/redis3:stable</span>
<span style="color: #ae81ff">expose</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">6379</span>
<span style="color: #ae81ff">ports</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #e6db74">&quot;6379:6379&quot;</span>
</pre></div>
</blockquote>
<p>Here we have three services, <code>web</code>, <code>database</code> and <code>redis</code>. Our <code>web</code> service is our main service that builds from our Dockerfile previously mentioned. This will link to our <code>database</code> and <code>redis</code> services which use <code>quay.io/continuouspipe/mysql5.7:stable</code> and <code>quay.io/continuouspipe/redis3:stable</code> respectivly. These are just standard <code>redis:3.0</code> and <code>mysql:5.7</code> official images in a simple wrapper that allows a faster patching mechanism.</p>
<p>We are injecting <code>APP_ENV</code> into our web container as a build argument. This will allow <code>composer install</code> to run on <code>docker-compose up</code>. Essentially, this means a developer can simply clone the project repo and start the Docker container and all the setup is handled for them. No more manual steps should be required.</p>
<p>Additionally our web container is exposing both port <code>80</code> and <code>443</code>, this is because our base <a href="https://github.com/continuouspipe/dockerfiles/tree/master/php-nginx">php7-nginx</a> image is creating a self signed SSL certificate and forcing our app to use <code>https://</code> as default.</p>
<p>There is an additional environment variable being set for our <code>web</code> container, <code>APP_USER_LOCAL</code>, which is used to fix volume permission issues.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p><code>APP_USER_LOCAL</code> should only be used in development as using this could cause a security risk. Please see <a href="https://github.com/continuouspipe/dockerfiles/tree/master/ubuntu/16.04#volume-permission-fixes">Volume Permission Fixes</a> for more information</p>
</div>
<p>Docker needs to be able to execute the files we have in <code>tools/docker/setup</code>. Lets make sure that all files have execute permissions -</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span>$ chmod -R +x tools/docker/setup
</pre></div>
<p>We can now start our Docker containers -</p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span>$ docker-compose up
</pre></div>
<p>If everything has gone to plan, we should now see the famous &ldquo;Laravel&rdquo; splash page at <code>https://localhost</code></p>
<p><img src="/docs/docs/images/guides/laravel/laravel-splash.png" alt="Laravel Splash" /></p>
<h3 id="prepare-to-build-on-continuouspipe">Prepare to build on ContinuousPipe</h3>
<p>We configure ContinuousPipe with a <code>continuous-pipe.yml</code> file in the root of our project. This is the main configuration file that defines each of our tasks to be executed. As this configuration file is YAML, please ensure proper indentation is set, otherwise ContinuousPipe will fail to load the configuration file correctly.</p>
<p>First thing we define is some environment variables -</p>
<blockquote>
<p><strong>continuous-pipe.yaml (partial)</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">environment_variables</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">APP_ENV</span>
<span style="color: #ae81ff">value</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&quot;production&quot;</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">REMOTE_ENV</span>
<span style="color: #ae81ff">value</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&quot;1&quot;</span>
</pre></div>
</blockquote>
<p>We are simply setting a the <code>APP_ENV</code> for use within our build and <code>REMOTE_ENV</code> which can be used to distinguish the difference between a local docker build and a ContinuousPipe build. This can be useful when you need to to pull additional assets from 3rd party services or perhaps build the frontend assets in your deployments. For this tutorial, we are using this to allow us to generate a new <code>APP_KEY</code> during the deployment stage.</p>
<p>Next we define our tasks, our first task is building our image -</p>
<blockquote>
<p><strong>continuous-pipe.yaml (partial)</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">tasks</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">images</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">build</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">environment</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">APP_ENV</span>
<span style="color: #ae81ff">value</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">${APP_ENV}</span>
<span style="color: #ae81ff">services</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">web</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">image</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">quay.io/continuouspipe/laravel-demo</span>
</pre></div>
</blockquote>
<p>Here we injecting the <code>APP_ENV</code> build argument, the same as we did for our <code>docker-compose.yml</code> file. We also define the registry repository address where we want to push our freshly built images to.</p>
<p>The next task to run is the <code>infrastructure</code> task -</p>
<blockquote>
<p><strong>continuous-pipe.yaml (partial)</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">infrastructure</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deploy</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">${CLUSTER}</span>
<span style="color: #ae81ff">environment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&#39;&quot;project-key-&quot;</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">~</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">code_reference.branch&#39;</span>
<span style="color: #ae81ff">services</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">database</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">specification</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">volumes</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">type</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">persistent</span>
<span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">database-volume</span>
<span style="color: #ae81ff">capacity</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">5Gi</span>
<span style="color: #ae81ff">storage_class</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">default</span>
<span style="color: #ae81ff">volume_mounts</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">database-volume</span>
<span style="color: #ae81ff">mount_path</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">/var/lib/mysql</span>
<span style="color: #ae81ff">command</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">/usr/local/bin/docker-entrypoint.sh</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">mysqld</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">--ignore-db-dir=lost+found</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">--max_allowed_packet=128M</span>
<span style="color: #ae81ff">ports</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">3306</span>
<span style="color: #ae81ff">resources</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">requests</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cpu</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">50m</span>
<span style="color: #ae81ff">memory</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">250Mi</span>
<span style="color: #ae81ff">limits</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cpu</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">500m</span>
<span style="color: #ae81ff">memory</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">500Mi</span>
<span style="color: #ae81ff">redis</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">deployment_strategy</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">readiness_probe</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">type</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">tcp</span>
<span style="color: #ae81ff">port</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">6379</span>
<span style="color: #ae81ff">specification</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">ports</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">6379</span>
<span style="color: #ae81ff">resources</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">requests</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cpu</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">50m</span>
<span style="color: #ae81ff">memory</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">100Mi</span>
<span style="color: #ae81ff">limits</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cpu</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">250m</span>
<span style="color: #ae81ff">memory</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">250Mi</span>
</pre></div>
</blockquote>
<p>This is where we build our redis and database containers. We define a persistent volume to store our database so we don&rsquo;t need to build again on subsequent deployments. We are also setting the required cluster resources for these containers. Notice we set <code>cluster: ${CLUSTER}</code>. This is pulling the cluster name we previously set in the ContinuousPipe UI under Clusters.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>An important change for each of our tasks is to define the project key. Where I have set an environment name as <code>&quot;project-key-&quot; ~ code_reference.branch</code>, you should replace the <code>project-key</code> with your project name you defined earlier in the ContinuousPipe setup step.</p>
</div>
<p>Our next task in the list is <code>initialization</code> -</p>
<blockquote>
<p><strong>continuous-pipe.yaml (partial)</strong></p>
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span></span><span style="color: #ae81ff">initialization</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">run</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">cluster</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">${CLUSTER}</span>
<span style="color: #ae81ff">environment</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #e6db74">&#39;&quot;project-key-&quot;</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">~</span><span style="color: #f8f8f2"> </span><span style="color: #e6db74">code_reference.branch&#39;</span>
<span style="color: #ae81ff">image</span><span style="color: #f8f8f2">:</span>
<span style="color: #ae81ff">from_service</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">web</span>
<span style="color: #ae81ff">commands</span><span style="color: #f8f8f2">:</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">tools/docker/setup/setup.sh</span>
<span style="color: #ae81ff">environment_variables</span><span style="color: #f8f8f2">:</span> <span style="color: #f8f8f2">&amp;WEB_ENV_VARS</span>
<span style="color: #f8f8f2">-</span> <span style="color: #ae81ff">name</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">APP_ENV</span>
<span style="color: #ae81ff">value</span><span style="color: #f8f8f2">:</span> <span style="color: #ae81ff">${APP_ENV}</span>