-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.json
323 lines (323 loc) · 136 KB
/
index.json
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
[
{
"uri": "https://jddoesdev.github.io/docksal-training/introduction/about/",
"title": "About This Training",
"tags": [],
"description": "",
"content": " Introduction This training is designed based on the Docksal Docs with examples and scenarios for using Docksal for local development. This is a hands on training workshop broken down into the following schedule.\n DOCKER OVERVIEW Docker Basics A high-level overview of Docker, how Docker works, and the main components of Docker. Why Containerize? What are the advantages of using containers for development vs local *AMP stacks? Why Use More Than Just Docker? Why should we consider using something more than just Docker to containerize? What are the advantages to using something like Docksal to wrap up all of our Docker functionality? In this section we\u0026rsquo;ll go over how using a dev environment like Docksal makes development easier and faster compared to vanilla Docker. INTRO TO DOCKSAL What\u0026rsquo;s a Docksal? Where did it come from? Was it handed to us by aliens in hopes that it would change the world one local dev environment at a time? Nope, but we will cover where Docksal came from and what differences there are between Docksal and some of the other containerized dev environments out there. Docksal Stacks Let\u0026rsquo;s take a look at what a stack is and why we have them. Docksal System and Default Services We\u0026rsquo;re going to explore some of the services that come with Docksal and where they\u0026rsquo;re used. Boilerplates and Starterkits It\u0026rsquo;s not just for Drupal! Let\u0026rsquo;s explore a few of the available boilerplate projects that are in the Docksal Github Repo What\u0026rsquo;s in the Container? We\u0026rsquo;re going to explore some of the tools that are included with Docksal straight out of the box. Many should feel very familiar. GETTING STARTED Installing Docksal Your First \u0026ldquo;fin\u0026rdquo; Let\u0026rsquo;s make sure everything is installed correctly and that you\u0026rsquo;re able to get Docksal running and see the the system information. Starting a new project We\u0026rsquo;re going to use fin to spin up a boilerplate project and see what happens. Spinning up a Drupal Site We\u0026rsquo;re going to spin up a basic Drupal 8 site using the Docksal Drupal 8 boilerplate and take a look at some of the things that Docksal needs to run within a Drupal codebase. GOING FURTHER Customization How to alter settings and configuration to make our system work how we want it to work. Advanced Customization When a stack only gets you 90% of the way there, you might need just a little more to get you the rest of the way. We\u0026rsquo;ll explore some options for making customizations and tweaking existing services to do what you need them to do. Keep it Local Not all settings need to make it into your repo. In fact, it\u0026rsquo;s better if some don\u0026rsquo;t so that you don\u0026rsquo;t accidentally push an API key into a public repo. We\u0026rsquo;re going to find out how to make sure we keep private stuff on our local environment only. Adding Docksal to an Existing Project Let\u0026rsquo;s take an existing project that we\u0026rsquo;ve been working on and add Docksal to it to mimic our hosting environment. Addons, Addons, Addons Using addons to make your life easier. We\u0026rsquo;ll explore some of the available addons, what they do, and how to install them. Docksal: It\u0026rsquo;s Not Just for Local Anymore Let\u0026rsquo;s explore some other uses for Docksal that aren\u0026rsquo;t your local machine. Docksal can be used for CI builds and sandbox environments. Q \u0026amp; A AND TROUBLESHOOTING Towards the end of the day we\u0026rsquo;ll open up the conversation and see if there are any unanswered questions or issues that are preventing you from using Docksal in your everyday life. "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/installing-docksal/prereqs/",
"title": "Before Installing",
"tags": [],
"description": "",
"content": " Prereqs and System Requirements The prerequisites for installing Docksal are pretty slim, but important.\n All systems 8GB RAM or more Command Line access (Terminal, iTerm, or an IDE terminal) Mac 2010 or newer model Docker for Mac or VirtualBox (NOTE: This training is currently based on using VirtualBox) Linux By default, Apache listens on 0.0.0.0:80 and 0.0.0.0:443. This will prevent Docksal reverse proxy from running properly. You can resolve it an any of the following ways:\n Reconfigure Apache to listen on different host (e.g., 127.0.0.1:80 and 127.0.0.1:443) Reconfigure Apache to listen on different ports (e.g., 8080 and 4433) Stop and disable Apache Check that you have installed and configured:\n curl sudo CPU with SSE4.2 instruction set supported Docker Windows Windows 10 with Windows Subsystem for Linux and CPU with hardware virtualization (VT-x/AMD-V) supported and enabled in BIOS. Ubuntu 18.04 or greater Docker for Windows or VirtualBox (NOTE: This training is currently based on using VirtualBox) "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/customizing/",
"title": "Customizing a Project",
"tags": [],
"description": "",
"content": " Make Our Drupal Project Our Own In the last section, we installed a Drupal site using a boilerplate Composer-based template, but what if we want to make changes to some of our installation settings? In this section we\u0026rsquo;re going to look at a few places where we can customize our project to make it a little more our own.\nLet\u0026rsquo;s start off by making some adjustments within our docksal.env file.\nCustomizing docksal.env The docksal.env file contains environmental variables for Docksal, outside of the project. These are variables that the project looks for when starting up in order to run the correct settings, build the right services, and others. We\u0026rsquo;re going to start by changing our stack to match a production environment.\nIn your favorite text editor or IDE of choice, open ~/projects/docksal-training-projects/.docksal/docksal.env\nThe default settings here are:\nDOCKSAL_STACK=default DOCROOT=web MYSQL_PORT_MAPPING=\u0026#39;0:3306\u0026#39; XDEBUG_ENABLED=0 COMPOSER_MEMORY_LIMIT=-1 NOTE: Comments left out for brevity.\nWe\u0026rsquo;re going to make a couple of changes now. Let\u0026rsquo;s say we\u0026rsquo;re using Pantheon for hosting. In order to mimic the Pantheon production environment, we can change our stack. Change DOCKSAL_STACK=default to DOCKSAL_STACK=pantheon and save the file.\nThis won\u0026rsquo;t do anything until we update our project. We\u0026rsquo;re going to do that using the command fin up.\nIn your terminal, run\n$ fin up This will trigger all of your services to restart and update any that have changed.\nIf we look at the Pantheon stack we\u0026rsquo;ll see that it\u0026rsquo;s different from the default stack in a number of ways. This file can be found at ~/.docksal/stacks/stack-pantheon.yml\nThe Pantheon stack includes:\n Nginx 1.14 MariaDB 10.1 PHP 7.2 Varnish 4.1 Redis 4.0 ApacheSolr 3.6 And these changes will be reflected when you run fin up. Let\u0026rsquo;s look at the output:\ndocksal-training_cli_1 is up-to-date Recreating docksal-training_db_1 ... done Recreating docksal-training_web_1 ... done Creating docksal-training_solr_1 ... done Creating docksal-training_redis_1 ... done Creating docksal-training_varnish_1 ... done Waiting for project stack to become ready... Waiting for project stack to become ready... Project URL: http://docksal-training.docksal As you can see, we\u0026rsquo;ve created a solr, redis, and varnish service in our project now. This gives us access to these services locally to mimic settings we may have on our production server.\nGreat, now let\u0026rsquo;s make some more edits.\nWe\u0026rsquo;re going to enable Xdebug and change our project\u0026rsquo;s domain through docksal.env. Change the line XDEBUG_ENABLED=0 to XDEBUG_ENABLED=1 and add the line VIRTUAL_HOST=mycustomsite.docksal in your docksal.env file.\nSave and run fin up again.\nLet\u0026rsquo;s look at the output:\n$ fin up Starting services... Recreating docksal-training_cli_1 ... Recreating docksal-training_solr_1 ... Recreating docksal-training_cli_1 ... done Recreating docksal-training_solr_1 ... done Recreating docksal-training_web_1 ... done Recreating docksal-training_varnish_1 ... done Waiting for project stack to become ready... Project URL: http://mycustomsite.docksal Notice how our Project URL: has changed to reflect our new domain. Go ahead and visit it to make sure everything is still working.\nCustomizing As a hypothetical, let\u0026rsquo;s say that we want to change the site name on install. We could do this by simply editing .docksal/commands/init-site which makes sense, but alternatively we could add an environment variable to docksal.env and alter init-site once. Let\u0026rsquo;s try it.\n In your text editor, open docksal.env Add the line SITE_NAME=\u0026quot;This Site Has A Different Name\u0026quot; to the bottom of the file. In your text editor, open .docksal/commands/init-site Look for the lines that install Drupal using Drush, around line 89. Change the line that starts with --site-name= to --site-name=\u0026quot;${SITE_NAME}\u0026quot; NOTE: The double-quotes are important here. Save both files. If we were to run fin init now, the site name wouldn\u0026rsquo;t work. That\u0026rsquo;s because, as mentioned before, the init-site script runs inside the cli container. We need to pass this variable so that the cli container has access.\nTo do that, we\u0026rsquo;re going to need to alter the docksal.yml file, but first, what is docksal.yml?\ndocksal.yml is a docker-compose file that defines and helps tie services together. Our default docksal.yml is pretty bare, but it contains something that will help us out. Let\u0026rsquo;s take a look. Open .docksal/docksal.yml. You should see:\nversion: \u0026#34;2.1\u0026#34; services: cli: environment: - COMPOSER_MEMORY_LIMIT This doesn\u0026rsquo;t define any services by itself. Those are defined in the Docksal stacks, but in the processing order, Docksal looks for this file and uses it to alter the default behavior or the current cli service. Right now we\u0026rsquo;re passing in the COMPOSER_MEMORY_LIMIT variable that we have defined in docksal.env.\nTo get access to our new site name, we need to tell Docksal to pass the SITE_NAME variable as well.\n In your text editor open docksal.yml In the environment section, add the line - SITE_NAME NOTE: Indentation of this line must match the indentation of the - COMPOSER_MEMORY_LIMIT line, otherwise the YAML will not work. Save your file Now we\u0026rsquo;re ready to run fin init. After everything has run, visit your site at http://mycustomsite.docksal/ and notice that the site name has changed. Now we can easily change the site name in one spot.\nGoing Further with Customization There are many other customizations that we can do with our docksal.env and docksal.yml files. We can add labels to services which are used to define functionality, we can change domain names, and we can even define our own services and variables to be used for our projects. In the next section we\u0026rsquo;re going to explore some more advanced customizations using the docksal.env and docksal.yml files.\nNOTE: The code for this section can be found in the drupal-site-step-2 branch of [github.com/JDDoesDev/docksal-training-projects].\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/",
"title": "Docker Basics",
"tags": [],
"description": "",
"content": " The examples in this section use docker commands. It is advised that you have your system\u0026rsquo;s native Docker (Docker for Mac, Docker for Windows) installed and running when completing the exercises in this section.\n What is Docker? How Docker Works "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/client/",
"title": "Docker Client",
"tags": [],
"description": "",
"content": " Docker client The Docker client is responsible for everything that containers do. There are a Docker clients available for most common operating systems, including macOS, Windows, and most, if not all Linux distributions. The Docker client can either be on the same host as the daemon, or long-running program, or it can connect to a remote daemon. It also provides the CLI, or command line interface, to start, stop, build, and execute commands within containers.\nThe Docker client is mainly used for pulling images and running them on the host.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/introduction/",
"title": "Introduction",
"tags": [],
"description": "",
"content": " Introduction Thank you for taking the time to read through this training. This training is designed to make Docksal and container-based development more accessible to more people through examples, real world scenarios, and figuring out answers to the tough questions along the way.\nSo, what are we waiting for? Let\u0026rsquo;s do this!\n About This Training Prerequisites "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/introduction/prerequisites/",
"title": "Prerequisites",
"tags": [],
"description": "",
"content": " Before we begin\u0026hellip; While this training is designed for all skill levels, here are a few things that will help you have the most success.\n A basic understanding of programming concepts An understanding of using the command line Having VirtualBox, Docker for Mac, or Docker for Windows installed on your machine prior to training (macOS and Windows users) Having Docker installed on your machine prior to training (Linux users) A Github account Also, this training is written from the standpoint of a Linux and macOS user. Many commands should be similar on the Windows version of Docker, however, it should be said that I\u0026rsquo;m not an expert in Windows and won\u0026rsquo;t be able to offer much in the way of debugging in this training.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/storage/volumes/",
"title": "Volumes",
"tags": [],
"description": "",
"content": " Volumes The advantage to a volume is that it can be easily wrapped up with a container and be portable along with an image, meaning that one could wrap up everything together, the image and the volume, and ship or share it.\nTo create a volume, we need to define it. We do that by either creating it on its own, starting a container with an attached volume, or starting a service with an attached volume. The easiest way is to create it.\n$ docker volume create example\nNow if we look at what volumes are available, using docker volume ls we\u0026rsquo;ll see the volume example listed, however this doesn\u0026rsquo;t do a lot other than reserve some storage on your host for the volume. What we really want to do is have a volume mounted to a container. We do this using the docker run --mount command.\nNOTE: The --mount flag and the -v flags will achieve the same things, but with different syntax. The --mount flag is easier to use and has a clearer syntax, so that\u0026rsquo;s what we\u0026rsquo;ll be using for these examples.\n To start a container with a volume, we\u0026rsquo;ll use the following command:\n$ docker run -i -t \\ --name exampleContainer \\ --mount source=exampleVolume,target=/app \\ ubuntu /bin/bash Let\u0026rsquo;s go over this line by line:\ndocker run -i -t \\ This tells docker that we\u0026rsquo;re going to run a container, we want it to be interactive -i, and we want to be able to use the terminal to interact with it -t.\n --name exampleContainer \\ We\u0026rsquo;re naming our container exampleContainer\n --mount source=exampleVolume,target=/app \\ We\u0026rsquo;re using the volume exampleVolume for this container and mounting it to the /app folder within the container.\n ubuntu /bin/bash Finally, we\u0026rsquo;re using the default ubuntu image and using the Bash shell for interacting with it.\nIf this works, then we should see something that looks like this:\nroot@8bf1f5964b3d:/# Where the string after the root@ will vary based on your hash.\nNow let\u0026rsquo;s try an experiment, shall we? While we\u0026rsquo;re inside this container we just created, we\u0026rsquo;re going to create two files. One in the /app folder, and one in the user folder, in this case /root.\nRun the following commands:\n$ echo \u0026#39;Test volume file\u0026#39; \u0026gt;\u0026gt; /app/test $ echo \u0026#39;Test container file\u0026#39; \u0026gt;\u0026gt; ~/container-test We can check that these files exist by running cat /app/test and cat ~/container-test which should display the expected text.\nNOTE: the ~ in bash is a shortcut to the current user\u0026rsquo;s home folder. For root, this is /root, but for other users it is usually /Users/\u0026lt;my user name\u0026gt;.\n Now, let\u0026rsquo;s exit our container by typing exit. Since we don\u0026rsquo;t have anything running in the container this will cause it to stop.\nRun docker container rm exampleContainer to remove the container.\nFinally, recreate the container using the command from above:\n$ docker run -i -t \\ --name exampleContainer \\ --mount source=exampleVolume,target=/app \\ ubuntu /bin/bash This will get us back into our exampleContainer. Notice that we have a new hash in the command line prompt.\nGo to your /root folder using cd /root or cd ~ and run ls -al to see what files are there. You should see output similar to\nroot@af040d25a903:~# ls -al total 16 drwx------ 2 root root 4096 Oct 10 21:07 . drwxr-xr-x 1 root root 4096 Oct 26 15:43 .. -rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc -rw-r--r-- 1 root root 148 Aug 17 2015 .profile Our test container file is gone forever. This happened because we removed the container and everything in it disappeared.\nNow, go to your /app folder using cd /app and run ls -al to see what files are there. You should see output similar to\nroot@af040d25a903:/app# ls -al total 12 drwxr-xr-x 2 root root 4096 Oct 26 15:32 ./ drwxr-xr-x 1 root root 4096 Oct 26 15:43 ../ -rw-r--r-- 1 root root 17 Oct 26 15:32 test Run cat test and you\u0026rsquo;ll see our Test volume file text from before. Why is this? It\u0026rsquo;s because we mounted a volume to the container in the /app folder. The data from the volume is accessible to the container, but it isn\u0026rsquo;t tied to the container. In fact, it lives on our host machine! We could visit it without even spinning up a container if we wanted to.\nLet\u0026rsquo;s exit this container and remove it. Run exit from the command line of the container and once in your host terminal run docker container rm exampleContainer. We\u0026rsquo;ll also remove the example volume by using docker volume rm exampleVolume.\nNext, we\u0026rsquo;ll learn about the other primary method of persistent storage in Docker: Bind mounts.\nFor further reading on volumes, check out https://docs.docker.com/storage/volumes/\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/overview/",
"title": "What is Docker?",
"tags": [],
"description": "",
"content": " High level overview Linux containers Docker is an Open Source project based on the concept of Linux containers. What does this mean? At a high-level, this means that Docker runs on top of a host machine\u0026rsquo;s operating system kernel. A Linux container is a packaged application that includes everything it needs to run. Since the application is contained within its own container, the application is extremely portable and easily testable. The portability and testability of Linux containers make them extremely useful and valuable to developers and devops specialists alike.\nBut, what\u0026rsquo;s a Docker? Docker provides an environment and workflow for Linux containers. Think of it as a container tummler, or a system for containers that makes things happen. It accommodates the containers, creates a welcoming environment for them, keeps them working in sync, and prevents them from running rampant across your system.\nDocker is available for multiple systems and architectures, including:\n macOS Windows Many Linux distributions AWS Google Cloud Others not listed "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/whats-docksal/",
"title": "What's a Docksal",
"tags": [],
"description": "",
"content": " What is Docksal? Docksal is a containerized development tool that is setup for web application development. Docksal uses Docker and Docker compose to create reusable application development environments that can be shared across all developers, as well as for testing, and even production environments.\nA Brief History of Docksal Docksal began its life as an open sourced development management tool created by FFW known as DRUDE for Drupal Development Environment. The description from the Drude introduction blog post says that it \u0026ldquo;brings together common development tools, minimizes configuration, and ensures environment consistancy everywhere in your continuous integration workflow.\u0026rdquo;\nInitially it was an internal tool, but being the open source advocates that they are, FFW released it into the wild for anyone to use and benefit from.\nAfter a bit of time, it was expanded to include more than just Drupal and the name Drude was no long as valid as it once was. This expansion included out of the box support for \u0026ldquo;WordPress, stand-alone HTML files, or any other PHP project.\u0026rdquo; (FFW Announcing Docksal blog post)\nOver time it\u0026rsquo;s grown into a powerful, robust, and highly configurable development tool used by developers around the world to speed up their development time and help eliminate \u0026ldquo;it worked on my local!\u0026rdquo; issues. At the time of this writing there are 46 contributors to the core Docksal project, and several others who contribute to images, addons, and other aspects of the project.\nWhere Docksal is Now Docksal is currently used by several agencies and development shops as a tool to speed up development, test code rapidly, and deploy with ease. It\u0026rsquo;s become one of the top developer tools, including out of the box support for:\n Drupal 8 Drupal 7 Wordpress Magento Laravel Symfony Skeleton Symfony WebApp Grav CMS Backdrop CMS Hugo Gatsby JS Angular With more being considered all the time.\nHow is Docksal different than X? I would like to preface this with the statement that I have been using only Docksal for the past year, so instead of a comparison between Docksal and other environments, I\u0026rsquo;m going to list some things that separate it from others.\n Switching between Docker modes\nDocksal allows you to easily change between Docker on a Virtual Machine and Docker for Mac /Docker for Windows. This is not a consideration on Linux. Before you call out that we compared containerization and virtualization a few sections ago, please remember this: Docker for Mac / Docker for Windows (let\u0026rsquo;s call it Docker Native from now on) is itself a virtual machine. Docker requires the Linux kernel to function, so any OS that isn\u0026rsquo;t Linux-based is going to require some sort of virtualization.\nWith a simple command you can change from using a VM like VirtualBox to Docker Native or vice versa. This is extremely beneficial because as of the time of this writing, Docker Native can be very, very slow compared to using a VM.\n Docksal is written in Bash\nThis means that on Mac and Linux, no additional software is needed to run Docksal, where others may require Ruby, Nodejs, Python, or others. Because of this, setup time is decreased. On Windows, WSL (Windows Subsystem for Linux) is required, meaning that it does not work older versions of Windows and requires WSL be enabled and Ubuntu be installed to run commands.\nWith the Windows exception, using Bash instead of another language keeps in the spirit of containerization by reducing requirements of the host machine so that development tools are separated from the host machine.\n Docksal is easily configurable\nDocksal exposes many settings so that users can extend existing services or easily create their own based on a number of languages and setups. Within the Docksal repo there are several ready-to-install images that are available on Docker Hub for multiple setups.\nIn addition, creating your own service is relatively straightforward and lets you tie in to the greater application without having to have an extensive knowledge of Docker services and orchestration.\n Out of the Box / Zero Configuration Setup\nSpinning up a container for your project is as simple as installing Docksal with a Bash script, and adding a single folder.\n Configuration for Hosting Providers\nThere are stacks in place to mimic Pantheon and Acquia, two of the more popular Drupal hosting providers. In addition, there are built in commands to use Pantheon\u0026rsquo;s terminus and Platform.sh\u0026rsquo;s platform CLI utilities by default, allowing for easier local development closely coupled with your hosting provider.\n Up next, we\u0026rsquo;re going to take a look at some of the default stacks available out of the box with Docksal. Continue on \u0026gt;\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/existing-project/project-1/",
"title": "Adding Docksal to a Basic Project",
"tags": [],
"description": "",
"content": " Scenario As lead developer on a team you\u0026rsquo;ve run into a lot of issues with your teammates submitting features for code review and you notice that your continuous integration testing fails frequently. When you pull down to test for yourself, you see a lot of code that was deprecated in a previous version of PHP and will break if run on the version of PHP that your hosting provider uses. After some conversations, you find out that one of your teammates is using MAMP while another is using native Apache and PHP 5.6 installed on their system. A third is using a Vagrant setup that hasn\u0026rsquo;t been maintained in over a year.\n This is not an uncommon scenario. While not every team should have a prescribed local dev environment, if time is lost because there are errors affecting deploying code efficiently, then it may be time to consider a strong recommendation.\nLet\u0026rsquo;s look at the following code that is valid in PHP 5.6:\n\u0026lt;?php $string = \u0026#39;foo, bar, baz\u0026#39;; function get_array($string) { $array = split(\u0026#39;, \u0026#39;, $string); return $array; } var_dump(get_array($string)); ?\u0026gt; If we were to run this using a system that has PHP 5.6 installed, which it shouldn\u0026rsquo;t be, the only thing we might see is a deprecation warning.\nDeprecated: Function split() is deprecated in /var/www/public/test.php on line 6 array(3) { [0]=\u0026gt; string(3) \u0026quot;foo\u0026quot; [1]=\u0026gt; string(3) \u0026quot;bar\u0026quot; [2]=\u0026gt; string(3) \u0026quot;baz\u0026quot; } However, the split() PHP function was removed in 7.0. If we try running this same code on a server with PHP 7.0 or greater, we\u0026rsquo;d get this error:\nFatal error: Uncaught Error: Call to undefined function split() in /var/www/public/test.php:6 Stack trace: #0 /var/www/public/test.php(11): get_array('foo, bar, baz') #1 {main} thrown in /var/www/public/test.php on line 6 This can be frustrating to everyone involved as it is a source of the \u0026ldquo;But it worked on my machine!\u0026rdquo; problem. Let\u0026rsquo;s get rid of this problem by adding Docksal to the project repo and allowing everyone else to reap the benefits of using a pre-set local development environment.\nFor this exercise we\u0026rsquo;re going to create a new project and add Docksal to it.\n In our ~/projects/ folder create the add-docksal folder.\n$ cd ~/projects/ $ mkdir add-docksal $ cd add-docksal Create an index.html file.\n$ touch index.html Open this file in your editor and add the following:\n\u0026lt;html\u0026gt; \u0026lt;p\u0026gt;Hello, Docksal!\u0026lt;/p\u0026gt; \u0026lt;/html\u0026gt; From your system\u0026rsquo;s file explorer, open this file with your browser. If we wanted to, we could use an existing stack to setup our virtual hosts, our host file, and our web server. Depending on the existing setup, this could take a bit of time.\n Now that we\u0026rsquo;re able to view the rendered HTML, but if we wanted to start adding in any server-side code, like PHP or NodeJS, we would need to setup the back end of our web stack. Instead we\u0026rsquo;re going to add Docksal to this project. We do that by doing three things.\n Create a docroot folder inside your ~/projects/add-docksal/ folder and move index.html into it.\n$ mkdir docroot $ mv index.html docroot/ Create a .docksal folder in your ~/projects/add-docksal/ folder.\n$ mkdir .docksal Run fin up and watch as your project gets spun up.\n That\u0026rsquo;s literally all you need to do to add Docksal to an existing project. If you look in your ~/project/add-docksal/.docksal/ folder now, you\u0026rsquo;ll notice that Docksal has taken the liberty of adding your docksal.env and docksal.yml files. Inside the docksal.env it tells Docksal to use the default stack.\nAfter our project spins up, we can add the changes to the project to our repo and everyone working on this project now has access to the exact same development environment.\nIf you remember, Docksal looks for your web application files in the docroot folder. This is why we created this folder and moved our index.html file into it before spinning up.\nSummary The process for adding Docksal to an existing project is simple and straightforward. If you have Docksal installed on your system, all that you need to do is add a .docksal folder to your project root and make sure that the files your server needs to render are inside the docroot folder. Once you have these done, all you have to do is run fin up and Docksal takes care of the rest.\nThe finished code for this project is available at https://github.com/JDDoesDev/docksal-training-projects/tree/adding-docksal-project-1.\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/advanced-customizing/",
"title": "Advanced Customizations",
"tags": [],
"description": "",
"content": " Truly Making a Project Custom In the last section we customized a few things to change our domain name and the site name. In this section, we\u0026rsquo;re going to show how to extend a stack, change versions of images, and even customize and extend Docksal images using a Dockerfile.\nIn the following projects, we\u0026rsquo;re going to explore a few scenarios and solutions that can be provided with Docksal. Finished code is available on Github for each scenario, but you\u0026rsquo;ll get the most out of it if you follow them in order and work through them yourself.\n Project 1: Configuring to Match Production Project 2: The Front-end Team Requires a Specific Version of NPM and NodeJS Project 3: Building a Multi-server Project Summary "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/storage/bind-mounts/",
"title": "Bind Mounts",
"tags": [],
"description": "",
"content": " Bind Mounts A bind mount is very similar to a volume, in fact it uses a lot of the same concepts. However, instead of creating a volume with nothing in it, a bind mount binds to a folder on your host machine and mounts it within your container. As we\u0026rsquo;ll find out later, Docksal relies heavily on this concept for local development, but we\u0026rsquo;ll get into that in a bit.\nWhen we set up a bind mount we are doing two things. We\u0026rsquo;re telling our host machine to export the source folder to a container, and we\u0026rsquo;re telling a container to create a matching folder on the container to place that source folder. Essentially we\u0026rsquo;re linking the data from the source, putting in the container where it has the same functionality of a volume, and we\u0026rsquo;ll have access to changes in the data on the host machine within our container.\nThis is useful for shared projects using version control systems like git. In fact, many projects are using this type of workflow to duplicate development environments across many developers so that there are no surprises when deploying to a hosting provider. This workflow usually consists of having a codebase including some sort of Dockerfile or image included. A developer pulls down the codebase and runs the commands to start and run a container. Once the container is running and connected to the bind mount, any changes on the host machine\u0026rsquo;s files will be reflected immediately in the container.\nA bind mount itself is not a volume, but a volume can use a bind mount. Let\u0026rsquo;s try an example.\nFirst, from our host machine, let\u0026rsquo;s create a volume:\n$ docker volume create bindMountTest Now let\u0026rsquo;s take a look to see if our volume exists:\n$ docker volume ls DRIVER VOLUME NAME local bindMountTest Perfect! Now, let\u0026rsquo;s spin up a container using that volume:\n$ docker run -i -t \\ --name bindTest \\ --mount source=bindMountTest,target=/app \\ ubuntu /bin/bash root@3ffc3d80141d:/# For a breakdown of this command, please revisit the volumes section.\nNow that we\u0026rsquo;re in our container we can run ls -al and see a printout of all of our folders within our / or root folder.\nroot@3ffc3d80141d:/# ls -al total 76 drwxr-xr-x 1 root root 4096 Oct 26 18:13 . drwxr-xr-x 1 root root 4096 Oct 26 18:13 .. -rwxr-xr-x 1 root root 0 Oct 26 18:13 .dockerenv drwxr-xr-x 2 root root 4096 Oct 26 18:09 app \u0026lt;--- This is where our bindMountTest volume is mounted. drwxr-xr-x 2 root root 4096 Oct 10 21:07 bin drwxr-xr-x 2 root root 4096 Apr 24 2018 boot drwxr-xr-x 5 root root 360 Oct 26 18:13 dev [The rest of the output is omitted for brevity.] If we cd app we\u0026rsquo;ll see that there\u0026rsquo;s nothing inside this folder, which is fine. We don\u0026rsquo;t have anything in our volume that we\u0026rsquo;re expecting to show up.\nLet\u0026rsquo;s exit our container and remove it.\nroot@3ffc3d80141d:/# exit $ docker container stop bindTest $ docker container rm bindTest Now, let\u0026rsquo;s create some data to test out a bind mount.\nFirst, we\u0026rsquo;re going to need a folder to use as our host data so let\u0026rsquo;s use our ~/projects/docksal-training-docker/ folder from the Images section. If this folder doesn\u0026rsquo;t already exist, create it relative to your home folder.\n$ cd ~ $ mkdir projects/docksal-training-docker $ cd projects/docksal-training-docker Now let\u0026rsquo;s create a file in a new app folder.\n$ mkdir app \u0026amp;\u0026amp; cd app $ pwd /Users/username/projects/docksal-training-docker/app $ touch bind-mount-test $ echo \u0026#34;Testing a bind mount\u0026#34; \u0026gt;\u0026gt; bind-mount-test $ cat bind-mount-test You should see the output Testing a bind mount.\nSince Docker runs system-wide we can run the docker command anywhere, so we\u0026rsquo;ll stay in our docksal-training-docker/app folder for now. Next, we\u0026rsquo;re going to spin up a container using a bind mount. It is much the same as using a volume with two differences:\n You\u0026rsquo;ll notice that we\u0026rsquo;re using a type=bind argument for the command. When spinning up a container, Docker will automatically create a volume if it does not exist. This is not the case if we use a folder for source and the source folder does not exist. We will see an error and the build will fail. Okay, let\u0026rsquo;s spin up a container with a bind mount and see what happens.\n$ docker run -i -t \\ --name bindTest \\ --mount type=bind,source=\u0026#34;$(pwd)\u0026#34;,target=/app \\ ubuntu /bin/bash NOTE: The $(pwd) in the above command references the current directory where the command is run.\n Now, if we go to the /app folder of our container, we should see the file bind-mount-test\nroot@04899aa02741:/app# ls -al total 8 drwxr-xr-x 4 root root 128 Oct 26 20:02 ./ drwxr-xr-x 1 root root 4096 Oct 26 20:00 ../ -rw-r--r-- 1 root root 21 Oct 26 20:02 bind-mount-test Let\u0026rsquo;s see what\u0026rsquo;s in the bind-mount-test file.\nroot@04899aa02741:/app# cat bind-mount-test Testing a bind mount Look at that, we\u0026rsquo;ve brought our file from the host into the container! Wonderful! Now let\u0026rsquo;s do something with it.\nIn a new terminal window on your host machine, let\u0026rsquo;s do echo \u0026quot;And now I'm changed from the host\u0026quot; \u0026gt;\u0026gt; bind-mount-test within our docksal-training-docker/app folder.\n## In the host machine $ cat bind-mount-test Testing a bind mount And now I\u0026#39;m changed from the host Let\u0026rsquo;s go back to our container terminal and see what happened.\n## In the container root@04899aa02741:/app# cat bind-mount-test Testing a bind mount And now I\u0026#39;m changed from the host Outstanding! We now have the ability to change files in the container from our host which means that we can develop on our host and use the power of containers to build and host our code in a repeatable manner.\nThere are a lot more feature of bind mounts and other mounts that are beyond the scope of this training. For further reading please check out the Docker Docks.\nUp next, we\u0026rsquo;re going to take a look at Docker registries.\nYou can view the completed code for this section at https://github.com/JDDoesDev/docksal-training-docker/tree/volumes\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/daemon/",
"title": "Docker Daemon",
"tags": [],
"description": "",
"content": " Docker daemon The Docker daemon is where the magic really starts to happen. This is where applications in containers are able to run, images and containers live, volumes are defined, and networks are connected. The Docker client sends commands to the daemon via REST API calls or direct interaction.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/services/",
"title": "Docksal Services",
"tags": [],
"description": "",
"content": " Project and System Services Docksal services are divided into two groups: Project and System.\nProject Services are services that are defined and run at the project level. This means that you can have multiple instances of a web or cli service running at the same time on for different projects. For example, if we were working on a Drupal site for a client who uses Pantheon for hosting, we would want our web service to run Nginx. However, a ticket comes in from another client on Acquia that needs to be handled in a hurry.\nWe could stop the current project, but if we forget then we\u0026rsquo;re not stuck with Ngnix. We can spin up the Acquia project\u0026rsquo;s Docksal environment and get the proper version of PHP along with Apache that only touches that project\u0026rsquo;s codebase.\nSystem Services are services that are shared between all projects. These include the SSH agent, the DNS service, and the Reverse Proxy service. These are all available to every project and every project uses them.\nLet\u0026rsquo;s explore these services.\nProject Services Project services can be configured on a per-project basis. The three main services are web, db, and cli. However, Docksal ships with a few extras that can be configured to be used with your project. We will explore these extras more in the Docksal Files section.\nThe default stack contains these project services:\n cli\nThe default cli service runs supervisord. This is a client/server system that Docksal uses to control processes on the service. For cli these processes are the daemons php-fpm, which we use for running our PHP scripts, crond, which executes scheduled commands, and sshd, which is used to allow SSH connections.\nIt uses the docksal/cli:2.6-php7.2 image out of the box which contains PHP 7.2, Composer, Drush, Drupal Console, WP-CLI, Terminus, and Platform along with many more. It also has Nodejs v10.15.0, Ruby 2.6.0, Python 2.7.0, and msmtp. These inclusions are useful for having some of the most commonly used languages and compilers/interpreters used in web application development.\n db\nThe default db service runs the mysqld daemon. This allows connections to the database layer and separates the database layer from the CLI layer to simulate a real hosting environment.\nIt uses the docksal/mysql:5.6-1.4 image out of the box with MySQL 5.6.\n web\nThe default web service runs Apache server 2.4. This is responsible for maintaining a web connection and allowing you to connect your browser to your application.\nIt uses the docksal/apache:2.4-2.3 image out of the box.\n System services System services are shared across all Docksal projects. These are reused for a lot of the functionality that makes Docksal works without having to maintain multiple installs of the same software.\nThe default system services:\n docksal-dns\nThis is the service that is responsible for allowing your projects to use custom domain names. It defaults to using the domain project-name.docksal where project-name is the root folder of your project. So if your project lived at /Users/me/projects/cats the domain you would access is cats.docksal. Me-wow!\nIt does rely on an internet connection, but we\u0026rsquo;ll cover how to get around that a bit later.\n docksal-ssh-agent\nThis service allows you to use your host machine\u0026rsquo;s SSH keys within your projects. This is handy for pulling databases from hosting providers or using git commands within the container. Without this, you would have to add a key to the container every time you spun it up and make sure that it matches the keys on whatever external services you use that require SSH authentication.\n docksal-vhost-proxy\nThis service allows multiple domain names to be routed to the appropriate containers. This allows us to have several projects running, each with a custom domain, and have them routed to the correct web service based on the host name.\n In addition, networking, shared volumes, and other functionality we will cover later are part of the system services.\nSummary Project and system services allow our projects to remain separate from each other, but to share quite a bit of \u0026ldquo;under the hood\u0026rdquo; functionality across the board. Project services are spun up on a per project level, whereas system services are running at all times and used by all projects.\nNext, we\u0026rsquo;ll explore some of the starter-kits that are available with Docksal.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/",
"title": "How Docker Works",
"tags": [],
"description": "",
"content": " What\u0026rsquo;s the whale behind the curtain doing? Docker components Docker is built on multiple components:\n Docker Client Docker Daemon Docker Images Docker Containers Docker Storage Docker Services Docker Registries "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/installing-docksal/installation/",
"title": "Installation",
"tags": [],
"description": "",
"content": " Steps To Install Docksal Now that we have everything in place to install Docksal, let\u0026rsquo;s do just that.\nDocksal\u0026rsquo;s installer requires administrator access for some tasks to run. It adds commands to /usr/local/bin, edits a few secured files, and performs mounts, which may all require an elevated level of access.\n macOS with VirtualBox This runs Docker inside a Virtual Machine with VirtualBox.\n Install VirtualBox (a prerequisite) If a notice appears to enable the Kernel extension, allow it\nSystem Preferences \u0026gt; Security \u0026amp; Privacy. If there is no notice, then it\u0026rsquo;s already enabled.\n Install Docksal by opening a terminal and running\n$ bash \u0026lt;(curl -fsSL https://get.docksal.io) macOS with Docker for Mac Install Docker for Mac (a prerequisite) Start Docker for Mac and wait until the animation stops and/or the Docker menu says \u0026ldquo;Docker is running Install Docksal by opening a terminal and running\n$ DOCKER_NATIVE=1 bash \u0026lt;(curl -fsSL https://get.docksal.io) Linux Ubuntu, Mint, Debian, Fedora, CentOS, and derivatives are all supported. Check get.docker.com to see if you can install Docker.\n Be sure that your system is prepared for Docksal and that you checked the prerequisites before attempting to install. Install Docksal by opening a terminal and running\n$ DOCKER_NATIVE=1 bash \u0026lt;(curl -fsSL https://get.docksal.io) "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/",
"title": "Intro to Docker",
"tags": [],
"description": "",
"content": " Intro to Docker An overview of what Docker is and how to use it.\n Docker Basics Why Containerize? Beyond Docker "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/why-containerize/",
"title": "Why Containerize?",
"tags": [],
"description": "",
"content": " Containers vs Local Dev Environments vs Virtual Machines For the purposes of this portion of the training, a \u0026ldquo;Local Dev Environment\u0026rdquo; refers to anything that lives on your computer\u0026rsquo;s storage. Meaning MAMP, WAMP, local PHP, Apache, etc.\nThe key advantages to containerization are:\n Reusability Portability Configurability Reusability Local dev environments \u0026ndash; Require additional setup for each project. This means that a developer using one of the *AMP stacks or local services need to make sure that when they are working on a project, their settings match where the project will be hosted. Changing these settings can be time consuming and tedious. Virtual Machines \u0026ndash; Reusable, but they are far more resource intensive than containerization because they create an entire virtual machine, representing everything from the hardware, kernel, software, drivers, and every other aspect of a machine with each new virtual machine that is spun up. Multiple VMs on a single computer can take up a large chunk of resources. Containerized dev environments \u0026ndash; Can be reused on multiple systems, for multiple users, and for multiple projects. This means that no matter where a project is loaded, it will have the same setup as everywhere else from the initial install. Configuration time is minimal compared to other setups. Portability Local dev environments \u0026ndash; Usually not portable at all. They require setup on each machine where a project will live. Virtual Machines \u0026ndash; Portable, but different virtual machine setups can require that a developer download additional tools depending on which virtualized environment is being used in the project. Containerized dev environments \u0026ndash; Completely portable and only require that a developer have Docker installed on their system, eliminating the need to keep multiple VM tools up to date or multiple versions of the same service in your host machine\u0026rsquo;s storage. Configurability Local dev environments \u0026ndash; Traditionally difficult to configure on a per-project basis. Virtual Machines \u0026ndash; Highly configurable, but time consuming to remove and recreate a VM with changed settings. Containerized dev environments \u0026ndash; Highly configurable and fast to update, often only taking seconds to recreate an environment, even after significant changes since only the affected containers need to be updated and not the entire project. "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/existing-project/project-2/",
"title": "Adding Docksal to a Drupal Project",
"tags": [],
"description": "",
"content": " Scenario You have several clients and projects that you do work for. You\u0026rsquo;ve been using a custom AMP (Apache, MySQL, PHP) stack, but you\u0026rsquo;re frustrated with having to change PHP versions for each client project. You\u0026rsquo;ve decided to use Docksal for a local development environment, but you don\u0026rsquo;t want to lose all of the work you\u0026rsquo;ve done.\n Let\u0026rsquo;s take a moment to consider what we definitely need for our site to work on a Docksal project.\n Apache, MySQL, PHP A database connection Drush Composer A database backup The starting code for this project is available at https://github.com/JDDoesDev/docksal-training-projects/tree/adding-docksal-project-2-start\n The first thing we need is a backup of our database. How we do this depends on how your project is setup.\nOption 1: Sync from production\nIf your project is already hosted and you have Drush aliases setup to your production site, you\u0026rsquo;ll be able to import the database by using a command like drush sql-sync @remote @local depending on your Drush aliases.\nOption 2: Create a local dump\nIf your project is only local and you don\u0026rsquo;t have a remote to sync from, you can create a database dump by using drush sql:dump before shutting down your existing project and importing after we get setup.\n Next, we need to add Docksal to our project. Assuming that we\u0026rsquo;re working in our ~/projects/docksal-training-projects folder on the branch adding-docksal-project-2-start we\u0026rsquo;ll need to create the .docksal folder.\n$ mkdir .docksal Now we have Docksal as part of our project, but we\u0026rsquo;re missing a few things. For one, we don\u0026rsquo;t have anything telling Drupal where to find the database. This usually lives in docroot/sites/default/settings.php.\n It is normally considered bad practice and insecure to include your live settings.php file in the repo, however this demo does not contain any sensitive data or real passwords.\n We don\u0026rsquo;t want to override our production settings with our Docksal settings, so we\u0026rsquo;re going to create a docksal.settings.php file that we will conditionally require in our settings.php\n$ cd docroot/sites/default/ $ touch docksal.settings.php Open this file in your text editor.\n Add Docksal required settings to your docksal.settings.php.\n\u0026lt;?php // Don\u0026#39;t forget the opening php tag # Docksal DB connection settings. $databases[\u0026#39;default\u0026#39;][\u0026#39;default\u0026#39;] = [ \u0026#39;database\u0026#39; =\u0026gt; \u0026#39;default\u0026#39;, \u0026#39;username\u0026#39; =\u0026gt; \u0026#39;user\u0026#39;, \u0026#39;password\u0026#39; =\u0026gt; \u0026#39;user\u0026#39;, \u0026#39;host\u0026#39; =\u0026gt; \u0026#39;db\u0026#39;, \u0026#39;driver\u0026#39; =\u0026gt; \u0026#39;mysql\u0026#39;, ]; The following is for Drupal 8 only. If you are using Drupal 7 then replace $settings with $conf in the following lines.\n# Workaround for permission issues with NFS shares in Vagrant $settings[\u0026#39;file_chmod_directory\u0026#39;] = 0777; $settings[\u0026#39;file_chmod_file\u0026#39;] = 0666; Reset your permissions on your docroot/sites/default/files folder to make sure your files are accessible to your containerized project.\nFrom your docroot/sites/default folder run the following:\n$ chmod -R +rwX files This command uses chmod to change the mode of the files and folders. -R is for recursive. The additional flags are r for \u0026lsquo;read\u0026rsquo;, w for \u0026lsquo;write\u0026rsquo;, and X indicates to make folders or directories executable/searchable (notice the capital X instead of x). This sets the folders to 777 or rwx and files to 666 or rw.\n Tell Drupal where to find our docksal.settings.php file.\nTo do this we have a couple of options. We can either uncomment the section at the bottom of the default settings.php file\nif (file_exists($app_root . \u0026#39;/\u0026#39; . $site_path . \u0026#39;/settings.local.php\u0026#39;)) { include $app_root . \u0026#39;/\u0026#39; . $site_path . \u0026#39;/settings.local.php\u0026#39;; } and replace settings.local.php with docksal.settings.php, but this will cause some issues if we forget to ignore our docksal.settings.php file in version control.\nMy preferred method is to use the following snippet:\n// Signals that this is operating in a Docksal environment and should include // default Docksal settings. if (getenv(\u0026#39;PROJECT_ROOT\u0026#39;) \u0026amp;\u0026amp; file_exists($app_root . \u0026#39;/\u0026#39; . $site_path . \u0026#39;/docksal.settings.php\u0026#39;)) { require $app_root . \u0026#39;/\u0026#39; . $site_path . \u0026#39;/docksal.settings.php\u0026#39;; } The reason I prefer this snippet is because instead of just checking if the file docksal.settings.php exists, it also checks to see if the PROJECT_ROOT environmental variable exists, which it always will in a Docksal project, and then includes docksal.settings.php.\n Start Docksal with fin project start\nTroubleshooting Tip\nIf you\u0026rsquo;ve been working in this folder on other projects from this training, you may run into an issue where the volumes are confused. If you try to run a command and get an error saying that the file cannot be found or similar, then you may need to do the following steps to clear any existing volumes and containers:\n Run fin project remove Run fin system restart Run fin project start If you cloned this project from version control, install the composer dependencies.\n$ fin composer install Create the default database for our project.\n$ fin db create default Visit your site at docksal-training-projects.docksal\n If all went well, you should see the default install page. At this point we would import our database from our dump using fin db import [file] or from our production server using fin drush.\nThe finished code for this project is available at https://github.com/JDDoesDev/docksal-training-projects/tree/adding-docksal-project-2-finish\n Summary By using the default stack that Docksal imports to an empty .docksal folder, we have our Apache, MySQL, and PHP installed in our project. We told Drupal where to find our database, and composer and Drush are installed in our project by Docksal by default.\nAdding Docksal to an existing Drupal project takes a few extra steps, but is pretty straightforward. With some practice you\u0026rsquo;ll know what steps to take without having to refer to this training. You could even automate the process by creating your own fin init script to build the site, import the database from production, import config, and create the correct settings files. Next up we\u0026rsquo;re going to explore some of the many addons that are available through Docksal.\nTroubleshooting Some common issues when moving from a locally hosted project using WAMP, MAMP, or other containerized environments:\nConflicting Ports Resetting Docksal services... * proxy docker: Error response from daemon: driver failed programming external connectivity on endpoint docksal-vhost-proxy (a7addf7797e6b0aec8e3e810c11775eb77508c9079e375c083b3650df2dff9a2): Error starting userland proxy: listen tcp 0.0.0.0:443: listen: address already in use. If Apache is running, it listens on the same ports (80, 443) as Docksal. Solve this by stopping Apache or reconfiguring Apache ports.\nIf Apache is not running, there may be some conflicts between Docksal and another local dev system. Run run lsof -PiTCP -sTCP:LISTEN and see what is using port 80 or port 443 and stop that process.\nFor other troubleshooting tips, visit the Troubleshooting section of the Docksal docs.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/beyond-docker/",
"title": "Beyond Docker",
"tags": [],
"description": "",
"content": " Why should we use more than just Docker? Considerations when using vanilla Docker Docker is great in itself, but it can take some time to learn and to figure out the best ways to do things for your project(s). When beginning a new project that will use Docker there are several decisions to make:\n Will I need services or a single container? Will I need to build a custom Dockerfile? How will I connect my services? How will I interact with my application? What kind of storage will I use? What extras do I need to add into the stock container? Which images will work best for what I want to do? Does it make more sense to have a single image? How will I make changes if the requirements change? A tool like Docksal and others take all of this into consideration and wrap it up into something that can be easily installed, easily configured, easily deployed, easily shared, and most importantly easily used.\nLet\u0026rsquo;s look back on our Docker Basics Section and see what setting up a project can entail.\n Find a base image Add steps in a Dockerfile Build the image Decide if using a volume, bind mount, or something different Spin up the container Verify everything works Ensure everything is setup so that we don\u0026rsquo;t lose data if we stop the container These steps are not difficult with some practice, but there are many tools that eliminate this setup, allowing you to begin development faster and taking a lot of the guesswork out of spinning up your application.\nAdvantages to a tool that uses Docker With a tool like Docksal, most of the setup is taken out of the equation and you can begin developing faster. Often times, most commands are wrapped up in a handy command so that long commands like docker container exec my_container bash -lc \u0026quot;/var/www/vendor/bin/drush en stage_file_proxy\u0026quot; can be handled in a more intuitive and less verbose manner.\nIn addition, tools like Docksal take all the guesswork out of deciding whether your application should exist in a single container or across multiple services that work together. They handle the orchestration between services out of the box so that you can get straight to developing.\nThese tools are often developed, maintained, and contributed to by many developers who are passionate about the project and want to build on it to see it grow. This means that if you\u0026rsquo;re running into a problem, there\u0026rsquo;s a good chance that others have already run into the same problem and there will be an answer waiting for you. Unfortunately, rolling a custom solution does not give you the same advantages and you\u0026rsquo;re potentially stuck with a community of one.\nTo see a partial list of contributors to the Docksal project, visit the Credits page of the Docksal docs.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/images/",
"title": "Docker Images",
"tags": [],
"description": "",
"content": " Images Images are blueprints for containers. An image itself is often defined by no more than a single file, usually some form of a Dockerfile. This file gives the image instructions on what it needs to be run. Let\u0026rsquo;s put together our own image.\nOn your host machine create a Dockerfile in ~/projects/docksal-training-docker\n$ cd ~ $ mkdir projects/docksal-training-docker $ cd docksal-training-docker $ touch Dockerfile Open up that new file in your favorite text editor and add the following:\nFROMubuntuRUN echo \u0026#34;Hello, world!\u0026#34; This file is using another image ubuntu and building off of that to create its own image. The only thing this image will do is create a container using Docksal\u0026rsquo;s CLI image and then echo the words Hello, world! in the build output. Nothing too fancy, but there is a lot going on here.\nLet\u0026rsquo;s build this simple image and see what happens:\n$ docker build --tag \u0026#34;image-example:1.0.0\u0026#34; \u0026#34;$(pwd)\u0026#34; Sending build context to Docker daemon 50.44MB Step 1/2 : FROM ubuntu ---\u0026gt; bb4c72e4b656 Step 2/2 : RUN echo \u0026#34;Hello, world!\u0026#34; ---\u0026gt; Using cache ---\u0026gt; d2c00859cae2 Successfully built d2c00859cae2 Successfully tagged image-example:1.0.0 NOTE: In the previous command the \u0026quot;$(pwd)\u0026quot; is a bash scripting method that takes the output of the pwd command and returns it as a string to print. This creates a reference to the current folder.\n Doesn\u0026rsquo;t seem like a lot, but let\u0026rsquo;s break down the command and output.\n$ docker build --tag \u0026#34;image-example:1.0.0\u0026#34; \u0026#34;$(pwd)\u0026#34; This tells Docker we\u0026rsquo;re building an image with a tag of image-example:1.0.0 and that we want to use the Dockerfile in the current folder. Notice that we don\u0026rsquo;t need to include Dockerfile in the command.\nSending build context to Docker daemon 50.44MB Remember how we talked about the Docker client primarily communicating with the Docker daemon? That is what this line is representing.\nStep 1/2 : FROM ubuntu ---\u0026gt; bb4c72e4b656 Step 2/2 : RUN echo \u0026#34;Hello, world!\u0026#34; ---\u0026gt; d2c00859cae2 Each step in the Dockerfile creates a new layer of the image with a snapshot of each instruction saved. If for some reason the build doesn\u0026rsquo;t work, then you can debug using the hash generated by each step. The FROM is pulling the parent image, in this case ubuntu, into the current image. While RUN is running a command on that image and saving the output in the next layer.\nSuccessfully built d2c00859cae2 Successfully tagged image-example:1.0.0 This output gives us a unique identifier of our image and a human-readable name so that we can work with it a bit easier. Now this image is built and ready to be used to create a container.\nIf this were your first time building this image, you would see a lot of status indicators that look like this:\n177e7ef0df69: Already exists 9bf89f2eda24: Already exists 350207dcf1b7: Already exists a8a33d96b4e7: Already exists 82350ee8f11f: Pulling fs layer 2d9047762251: Pulling fs layer 196d943fac59: Pulling fs layer ff00d78cbcf3: Pulling fs layer 8b971b61b7b6: Pulling fs layer 337d6d904976: Downloading [===========\u0026gt; ] 7.646MB/12.49MB 20c027cb1a77: Waiting ba27c2e2de1c: Waiting What this is doing is following the instructions provided by the Dockerfile to build an image. From our two-line Dockerfile, we\u0026rsquo;re pulling instructions in from another Dockerfile and from another until we reach the base file, most likely ending up at scratch, a base image provided on Docker Hub created with the sole purpose of having a starting point for completely custom images.\nDocker is smart enough to use caching to prevent having to re-download images every time a container is spun up, which is one of the reasons it\u0026rsquo;s so quick to load.\nSo now we have an image, but it\u0026rsquo;s not doing us a lot of good. So, what\u0026rsquo;s next?\nDocker Containers\nYou can view the completed code for this section at https://github.com/JDDoesDev/docksal-training-docker/tree/images\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/stacks/",
"title": "Docksal Stacks",
"tags": [],
"description": "",
"content": " Stacks in Docksal What is a stack? In Docksal, the concept of a \u0026ldquo;stack\u0026rdquo; is a collection of configurations or services put together to create a reusable application. They are built in yml files, and stored within the Docksal folder at ~/.docksal/stacks/. A stack yml file is the equivalent to a docker-compose.yml file in that it defines services to be used for an application.\nLet\u0026rsquo;s examine the Docksal default stack:\n# Basic LAMP stack # - Apache 2.4 # - MySQL 5.6 # - PHP 7.2 version: \u0026#34;2.1\u0026#34; services: # http(s)://VIRTUAL_HOST web: extends: file: ${HOME}/.docksal/stacks/services.yml service: apache depends_on: - cli db: extends: file: ${HOME}/.docksal/stacks/services.yml service: mysql cli: extends: file: ${HOME}/.docksal/stacks/services.yml service: cli You can see that there are three services defined as part of the default stack. When we use this stack for our application, we get a web service, a db service, and a cli service. As we learned about in the services section, these services are images that are built together as part of a larger application.\nOne thing to notice is that there isn\u0026rsquo;t a lot going on here. In fact, it seems oddly simple for something so powerful. Let\u0026rsquo;s dive into how Docker and Docksal take this file and convert it into a full application.\nFirst we\u0026rsquo;re going to look at what comes before the services\nversion: \u0026#34;2.1\u0026#34; services: The important line here is version: \u0026quot;2.1\u0026quot;. This line tells Docker which Docker Compose API we\u0026rsquo;re running against so that even if Docker is upgraded, our application will not break. Take note of the version here when defining your own services, as some commands may not be available in the version we\u0026rsquo;re using for Docksal.\nNow let\u0026rsquo;s examine the web service in the default stack.\nFirst off, the web service is where our webserver lives. In the default stack, we\u0026rsquo;re using Apache. All web requests are sent through this service and all rendering happens here as well.\nNow the stack:\nservices: # http(s)://VIRTUAL_HOST web: extends: file: ${HOME}/.docksal/stacks/services.yml service: apache depends_on: - cli Let\u0026rsquo;s examine this in chunks:\nweb: Here we\u0026rsquo;re naming our service. This could literally be anything, but it makes sense to name it descriptively.\nextends: file: ${HOME}/.docksal/stacks/services.yml service: apache In this section we\u0026rsquo;re telling Docker Compose where to find the actual configuration. Docksal places all of the common services inside a file at ${HOME}/.docksal/stacks/services.yml. Each of those services are named and available to be used by other files. As you can see here, we\u0026rsquo;re taking the service apache from ${HOME}/.docksal/stacks/services.yml and loading it into our application.\ndepends_on: - cli Finally, we\u0026rsquo;re making sure that the cli service is started before this one. This is because the our web service needs the cli service to be running so that it can function properly.\nNow let\u0026rsquo;s look at what\u0026rsquo;s in the apache service in ${HOME}/.docksal/stacks/services.yml\nservices: # Web: Apache apache: hostname: web image: ${WEB_IMAGE:-docksal/apache:2.4-2.3} volumes: - project_root:/var/www:ro,nocopy # Project root volume (read-only) labels: - io.docksal.virtual-host=${VIRTUAL_HOST},*.${VIRTUAL_HOST},${VIRTUAL_HOST}.* - io.docksal.cert-name=${VIRTUAL_HOST_CERT_NAME:-none} - io.docksal.project-root=${PROJECT_ROOT} - io.docksal.permanent=${SANDBOX_PERMANENT:-false} environment: - APACHE_DOCUMENTROOT=/var/www/${DOCROOT:-docroot} - APACHE_FCGI_HOST_PORT=cli:9000 - APACHE_BASIC_AUTH_USER - APACHE_BASIC_AUTH_PASS dns: - ${DOCKSAL_DNS1} - ${DOCKSAL_DNS2} There\u0026rsquo;s a lot more going on here than in default-stack.yml, right? Let\u0026rsquo;s break this service down a bit to explore what\u0026rsquo;s going on.\napache: hostname: web image: ${WEB_IMAGE:-docksal/apache:2.4-2.3} We are defining a hostname for our service and calling it web. Again, the name is arbitrary for the file, but it is important for the way Docksal works. We\u0026rsquo;re also defining which image our service is going to be built on.\nTake notice of the bash scripting that is being used here: ${WEB_IMAGE:-docksal/apache:2.4-2.3}\nThis is looking for an environment variable by the name of WEB_IMAGE, and if it doesn\u0026rsquo;t exist, then load the default. We\u0026rsquo;ll talk more about configuring environment variables in an upcoming section.\nThis line is the equivalent of running a docker run command with arguments and flags. Let\u0026rsquo;s build that command: docker run --name apache --hostname web docksal/apache:2.4-2.3. If you were to run that command, you would get a simple Apache container, but it wouldn\u0026rsquo;t be a part of our application.\nvolumes: - project_root:/var/www:ro,nocopy # Project root volume (read-only) Even though it says volumes, don\u0026rsquo;t be fooled. This is creating a bind mount from the project_root volume to the folder /var/www within the container. We\u0026rsquo;re also telling Docker that it\u0026rsquo;s read-only (ro) and we don\u0026rsquo;t need to copy anything to the container, just create pointers to the files there (nocopy).\nWe\u0026rsquo;re using something called \u0026ldquo;Named Volumes\u0026rdquo; here, which makes it easier to configure the bind mount as well as inspect the bind mount from the command line.\nlabels: - io.docksal.virtual-host=${VIRTUAL_HOST},*.${VIRTUAL_HOST},${VIRTUAL_HOST}.* - io.docksal.cert-name=${VIRTUAL_HOST_CERT_NAME:-none} - io.docksal.project-root=${PROJECT_ROOT} - io.docksal.permanent=${SANDBOX_PERMANENT:-false} Labels are specific to Compose projects. These are key value pairs that are used for orchestration of the application\u0026rsquo;s services. For example, the line - io.docksal.virtual-host=${VIRTUAL_HOST},*.${VIRTUAL_HOST},${VIRTUAL_HOST}.* is used to create a label that Docksal uses to tell the web service which domains it should be listening for while it\u0026rsquo;s running.\nenvironment: - APACHE_DOCUMENTROOT=/var/www/${DOCROOT:-docroot} - APACHE_FCGI_HOST_PORT=cli:9000 - APACHE_BASIC_AUTH_USER - APACHE_BASIC_AUTH_PASS The environment section passes environment variables into the service. These can be set elsewhere, as part of the host machine\u0026rsquo;s environment, or in this section. As you can see, the APACHE_DOCUMENTROOT variable is being set in the service definition, whereas APACHE_BASIC_AUTH_USER is being passed from host to service.\ndns: - ${DOCKSAL_DNS1} - ${DOCKSAL_DNS2} Finally, the dns section is telling the web service what DNS service to use. These variables are set at runtime.\nSummary Docksal stacks make it extremely easy to get working with minimal, even zero configuration. With the default stacks that are packaged with Docksal, we can have a robust development environment running without having to worry about setting up PHP, Apache, MySQL, or others. Simply start Docksal in your project and begin developing.\nUp next, we\u0026rsquo;re going to learn about the services that make Docksal work. Continue on \u0026gt;\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/",
"title": "Intro to Docksal",
"tags": [],
"description": "",
"content": " Intro to Docksal An overview of the basics of Docksal and how use it.\n What\u0026#39;s a Docksal Docksal Services Docksal Stacks Boilerplates and Starter-kits What\u0026#39;s in the Container? "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/first-fin/",
"title": "Starting the System",
"tags": [],
"description": "",
"content": " Installation Complete. Prepare for Something Amazing! Now that we\u0026rsquo;ve installed Docksal, let\u0026rsquo;s get it running.\nRun the following in your terminal:\n$ fin system start Behind the Scenes When you run fin system start the first time, a few things are happening behind the scenes.\nFor starters, you are initializing the Docksal application. If this is your first time, it will begin by downloading all of the required images from the registry and spin up the services. Because Docksal shares some services across every project, these services are not reliant on having a project started.\nThe services we\u0026rsquo;re starting up are:\n docksal-ssh-agent docksal-dns docksal-vhost-proxy They are responsible for making sure that your application has SSH access, can route requests to the correct project, and can resolve the *.docksal domain locally.\nExamining our System fin sysinfo is one of the most important commands and utilities we have at our disposal. It tells us almost everything we need to know about our system, including what might be going wrong with it.\nLet\u0026rsquo;s take a look at the output of fin sysinfo to see what information we have access to.\n$ ❯ fin sysinfo ███ OS Darwin Mac OS X 10.14.6 Darwin DorfMBP 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64 ███ ENVIRONMENT MODE : VirtualBox VM DOCKER_HOST : tcp://192.168.64.100:2376 DOCKSAL_NFS_PATH : /Users/jamesflynn/git NFS EXPORTS: # \u0026lt;ds-nfs docksal /Users/jamesflynn/git 192.168.64.1 192.168.64.100 -alldirs -maproot=0:0 # ds-nfs\u0026gt; ███ FIN fin version: 1.86.2 ███ DOCKER COMPOSE EXPECTED VERSION: 1.23.2 docker-compose version 1.23.2, build 1110ad01 docker-py version: 3.6.0 CPython version: 3.6.6 OpenSSL version: OpenSSL 1.1.0h 27 Mar 2018 ███ DOCKER EXPECTED VERSION: 18.09.2 Client: Docker Engine - Community Version: 18.09.2 API version: 1.39 Go version: go1.10.8 Git commit: 6247962 Built: Sun Feb 10 04:12:39 2019 OS/Arch: darwin/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.2 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 04:20:28 2019 OS/Arch: linux/amd64 Experimental: false ███ DOCKER MACHINE EXPECTED VERSION: 0.16.1 docker-machine version 0.16.1, build cce350d7 NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS docksal * virtualbox Running tcp://192.168.64.100:2376 v18.09.2 ███ DOCKSAL: PROJECTS project STATUS virtual host project root ███ DOCKSAL: VIRTUAL HOSTS ███ DOCKSAL: DNS Successfully requested http://dns-test.docksal ███ DOCKER: RUNNING CONTAINERS CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f95a1d600dbe docksal/ssh-agent:1.2 \u0026#34;docker-entrypoint.s…\u0026#34; 3 days ago Up 3 days (healthy) docksal-ssh-agent f5d581ad9436 docksal/dns:1.1 \u0026#34;docker-entrypoint.s…\u0026#34; 3 days ago Up 3 days (healthy) 192.168.64.100:53-\u0026gt;53/udp docksal-dns de0e1729e381 docksal/vhost-proxy:1.5 \u0026#34;docker-entrypoint.s…\u0026#34; 3 days ago Up 3 days (healthy) 192.168.64.100:80-\u0026gt;80/tcp, 192.168.64.100:443-\u0026gt;443/tcp docksal-vhost-proxy ███ DOCKER: NETWORKS NETWORK ID NAME DRIVER SCOPE f0767638af16 _default bridge local 909d942fc925 bridge bridge local 37afaa2911ed host host local 86dbe729b8fc none null local ███ VIRTUALBOX EXPECTED VERSION: 5.2.26 5.2.26r128414 ███ DOCKSAL MOUNTS ███ HDD Usage Filesystem Size Used Available Use% Mounted on /dev/sda1 46.1G 4.4G 39.3G 10% /mnt/sda1 Instead of going over each item in depth, we\u0026rsquo;ll briefly cover the sections.\n OS - The current host machine OS and relevant information. ENVIRONMENT - Info about the current Docker system. FIN - The version of fin that we\u0026rsquo;re using. DOCKER COMPOSE - Current version of Docker Compose DOCKER - Current version of Docker Engine and Docker\u0026rsquo;s host and client. DOCKER MACHINE - Current version of Docker Machine. DOCKSAL: PROJECTS - A list of projects Docksal knows about. DOCKSAL: VIRTUAL HOSTS - A list of the virtual hosts Docksal is watching for. DOCKSAL: DNS - Output indicating whether or not the DNS service is working. DOCKER: RUNNING CONTAINERS - What containers/services are currently active. DOCKER: NETWORKS - The current networks Docksal is handling. VIRTUALBOX - The running version of VirtualBox (if applicable). DOCKSAL MOUNTS - Current mounted volumes. HDD Usage - How much disk storage Docksal is currently eating up. This information is extremely useful when debugging a project, if something isn\u0026rsquo;t working quite right, or if there are questions about your configurations.\nSummary We\u0026rsquo;ve installed and started Docksal, checked our system, and explored how to inspect our system with a single command. Up next, we\u0026rsquo;re going to spin up a project and explore how to work within our new environment.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/keep-it-local/",
"title": "Using Local Files",
"tags": [],
"description": "",
"content": " Keeping it Local Introduction There are a lot of times when certain information should not be put into version control. For example, API keys, sensitive user information, variables that change depending on who\u0026rsquo;s using the repo, etc. For this, Docksal has local files available.\nBy default, Docksal operates in local mode. There is an environment variable set, DOCKSAL_ENVIRONMENT=local, that gives your projects access to some new files that you can keep outside of version control. Docksal will look for versions of docksal.env and docksal.yml that have the pattern docksal-${DOCKSAL_ENVIRONMENT} for their filenames and it will use them in addition to docksal.env and docksal.yml.\nThe loading order for the config files is:\n ~/.docksal/docksal.env ~/.docksal/stacks/volumes-*.yml ~/.docksal/stacks/stack-*.yml ${PROJECT_ROOT}/.docksal/docksal.yml ${PROJECT_ROOT}/.docksal/docksal.env ${PROJECT_ROOT}/.docksal/docksal-${DOCKSAL_ENVIRONMENT}.yml ${PROJECT_ROOT}/.docksal/docksal-${DOCKSAL_ENVIRONMENT}.env As the next file loads, it overrides any matching settings in the previous file. So if your ~/.docksal/docksal.env contained:\nFOO=\u0026#34;foo\u0026#34; BAR=\u0026#34;bar\u0026#34; BAZ=\u0026#34;baz\u0026#34; and your ${PROJECT_ROOT}/.docksal/docksal.env contained:\nFOO=\u0026#34;foo too\u0026#34; your project would end up with:\nFOO=\u0026#34;foo too\u0026#34; BAR=\u0026#34;bar\u0026#34; BAZ=\u0026#34;baz\u0026#34; Remember, they only add or override settings. They will not remove them.\nA Local File Scenario - docksal-local.env You are a member of a team using Docksal across multiple developers. The hosting provider requires that your requests to sync your database contain an API key in the request. Every member of the team has a different API key and for security, you do not want to let anyone\u0026rsquo;s key get into the repo. This key will be used in a custom command to trigger a sync.\n Going with what we\u0026rsquo;ve learned so far, this would probably make a great environment variable, so let\u0026rsquo;s create our docksal-local.env file. We\u0026rsquo;ll use our existing docksal-training-projects folder for this, so in a terminal or text editor get into the .docksal folder and create docksal-local.env.\n$ cd ~/projects/docksal-training-projects $ cd .docksal $ touch docksal-local.env Now open this file and let\u0026rsquo;s add in our API key and our associated user name. In your text editor open docksal-local.env and add the following.\nSECRET_API_KEY=12345678 SECRET_USERNAME=my-secure-name Now save this file. We have our secure info, but we want to make sure this doesn\u0026rsquo;t get into version control. Since we\u0026rsquo;re using git for this training, we\u0026rsquo;re going to put this file in our project\u0026rsquo;s .gitignore file.\nIn your editor, open up .gitignore in your project\u0026rsquo;s root folder and add the following line to the bottom.\ndocksal-local.* This will cover both docksal-local.yml and docksal-local.env and prevent them both from being tracked in version control.\nWe also need to run fin project restart for the changes to take effect. Any time we change an environment variable it\u0026rsquo;s safer to run fin project restart instead of fin up.\nA Local File Scenario - docksal-local.env You are a member of a team using Docksal across multiple developers. You\u0026rsquo;ve been tasked with prepping your project for an upgrade from an end of life version of PHP to a current version. Everyone else on your team is using PHP 5.6, but it\u0026rsquo;s time to get ready for the current version. You need to be able to test code, even as it changes from other developers, to make sure it\u0026rsquo;s ready for the upgrade.\n In order to do this, we\u0026rsquo;re going to use docksal-local.yml to override the image that we\u0026rsquo;re using for our cli service, so let\u0026rsquo;s create our docksal-local.yml file. We\u0026rsquo;ll use our existing docksal-training-projects folder for this, so in a terminal or text editor get into the .docksal folder and create docksal-local.yml.\n$ cd ~/projects/docksal-training-projects $ cd .docksal $ touch docksal-local.yml Open this file and override the image.\nversion: \u0026#34;2.1\u0026#34; services: cli: image: \u0026#34;docksal/cli:2.9-php7.3\u0026#34; This is all you need. Everything else will be kept from the other service definitions. You would then save this file and run fin up to get your version of the cli image with the current version of PHP. Since we added docksal-local.* to .gitignore this file won\u0026rsquo;t be tracked and nobody else will be affected.\nSharing Just Enough It may not be apparent to everyone on your team that you need to create the docksal-local.env file for your project, and it can be a hassle to have to explain it again and again. One common practice is to keep a sanitized example file in the repo with instructions. Usually this is named something like example.docksal-local.env and looks similar to this:\n## Copy this file to docksal-local.env and update the values to your own ## username and API key SECRET_API_KEY= SECRET_USERNAME= This file is not read by Docksal, does not keep any sensitive data, and can be kept in your version control without security concerns.\nYou could do the same with an example.docksal-local.yml file as well.\n## To test the codebase against PHP 7.3, copy this file to docksal-local.yml and ## restart your project. version: \u0026#34;2.1\u0026#34; services: cli: image: \u0026#34;docksal/cli:2.9-php7.3\u0026#34; Summary Not everything needs to be shared in the repo. Whether it\u0026rsquo;s a custom override for your specific needs or sensitive information that shouldn\u0026rsquo;t be in a public place, the local configuration overrides make it easier for you to keep the project shared, but keep your custom settings to yourself.\nThe example files for this section can be found at https://github.com/JDDoesDev/docksal-training-projects/tree/local-files\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/existing-project/",
"title": "Adding Docksal to an Existing Project",
"tags": [],
"description": "",
"content": " It\u0026rsquo;s Okay if You Didn\u0026rsquo;t Start a Project with Docksal Adding Docksal to your existing projects is a relatively straightforward process. Just because you didn\u0026rsquo;t begin developing with Docksal doesn\u0026rsquo;t mean that you can\u0026rsquo;t use it going forward.\nIn this section we\u0026rsquo;re going to explore a few ways to add Docksal to your existing web projects.\n Adding Docksal to a Basic Project Adding Docksal to a Drupal Project "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/new-project/",
"title": "Beginning with a Boilerplate",
"tags": [],
"description": "",
"content": " Starting Easy The easiest way to start a project with Docksal is to create a new one from a boilerplate. In this lesson we\u0026rsquo;re going to use one of the existing starter projects to spin up a web application with just a few keystrokes.\nDo You Want to Build a Project? We\u0026rsquo;re going to begin by entering our terminal and going to a project folder. For demonstration purposes, I\u0026rsquo;m going to use ~/projects/, but you\u0026rsquo;re free to use whatever folder works for you. In upcoming lessons we will be pulling projects down from Github, but for this one we\u0026rsquo;re going to use what\u0026rsquo;s already in the system.\n Open your terminal and go to your project folder.\n$ cd ~/projects Enter the command:\n$ fin project create This will bring up a series of prompts to build our project.\n At the first prompt, we\u0026rsquo;ll name our project my-first-docksal-application\n1. Name your project (lowercase alphanumeric, underscore, and hyphen): my-first-docksal-application This will bring up a prompt to choose a type of project. We\u0026rsquo;re going to start with a static HTML site.\n1. What would you like to install? PHP based 1. Drupal 8 2. Drupal 8 (Composer Version) 3. Drupal 7 4. Wordpress 5. Magento 6. Laravel 7. Symfony Skeleton 8. Symfony WebApp 9. Grav CMS 10. Backdrop CMS Go based 11. Hugo JS based 12. Gatsby JS 13. Angular HTML 14. Static HTML site Enter your choice (1-14): 14 Next, we\u0026rsquo;ll be able to verify our setup with the following prompt:\nProject folder: /Users/my.username/projects/my-first-docksal-project Project software: Plain HTML Project URL: http://my-first-docksal-project.docksal Do you wish to proceed? [y/n]: y After confirming, our services will be created and our application will be running.\nNOTE: If you haven\u0026rsquo;t run anything in Docksal on your system yet, you will see some images download. This is normal.\nStarting services... Creating network \u0026#34;my-first-docksal-project_default\u0026#34; with the default driver Creating volume \u0026#34;my-first-docksal-project_cli_home\u0026#34; with default driver Creating volume \u0026#34;my-first-docksal-project_project_root\u0026#34; with local driver Creating volume \u0026#34;my-first-docksal-project_db_data\u0026#34; with default driver Creating my-first-docksal-project_cli_1 ... done Creating my-first-docksal-project_web_1 ... done Connected vhost-proxy to \u0026#34;my-first-docksal-project_default\u0026#34; network. Waiting for project stack to become ready... Project URL: http://my-first-docksal-project.docksal Done! Visit http://my-first-docksal-project.docksal Next, we\u0026rsquo;re going to visit our newly created site by opening http://my-first-docksal-project.docksal in our browser. Not very much there, but as you can see, an entire web server is now running without having to configure any Apache, PHP, or any other part of a server stack.\n Let\u0026rsquo;s examine our app: my-first-docksal-project ├── .docksal │ ├── docksal.env │ └── docksal.yml └── docroot └── index.html As you can see, only three files on our system make up the basis for an entire web application, albeit a simple one. Behind the scenes, our Docksal system has created multiple new services, connected to existing ones, and mounted volumes for storage so that it can interact with the files on our host machine.\nBringing the App Down Because we may not want our app running for various reasons, we\u0026rsquo;re going to stop it and remove it from the system.\n Stop the services by running fin project stop\n$ fin project stop This will stop the containers and services, but they will still be present on our system in an inactive state.\n Now let\u0026rsquo;s clean up by removing the services and volumes that Docksal created for this project by running fin project remove\n$ fin project remove ALERT: Removing containers and volumes of my-first-docksal-project Continue? [y/n]: y Removing containers... Stopping my-first-docksal-project_web_1 ... done Stopping my-first-docksal-project_cli_1 ... done Removing my-first-docksal-project_web_1 ... done Removing my-first-docksal-project_cli_1 ... done Removing network my-first-docksal-project_default Removing volume my-first-docksal-project_cli_home Removing volume my-first-docksal-project_project_root Removing volume my-first-docksal-project_db_data Volume docksal_ssh_agent is external, skipping This stops and cleans out all of the services and volumes specific to this project. Look at the last line in the output, though.\nVolume docksal_ssh_agent is external, skipping Why isn\u0026rsquo;t this volume being stopped and cleared out? Well, it\u0026rsquo;s for one of our shared services that is used by all Docksal projects on your system. If we had multiple projects and Docksal removed this while another project was running, then it could cause serious issues with your workflow.\nSummary Creating an application with its own code, domain, and server in Docksal is simple. With the available boilerplates we have our choice of over a dozen starting points. In the next section we\u0026rsquo;re going to spin up a fully functional Drupal site and look at some of the customizations Docksal does to run your applications.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/starter-kits/",
"title": "Boilerplates and Starter-kits",
"tags": [],
"description": "",
"content": " Start Developing Faster Docksal ships with many different starter-kits out of the box to allow you to spin up a new project rapidly. In addition, the Docksal repo has many other starter-kits available for download or to extend in your own Dockerfile. In this section we\u0026rsquo;re going to examine a few and see how to use them.\nDefault Starter-kits As noted in the \u0026ldquo;What\u0026rsquo;s Docksal?\u0026rdquo; section, there are several starter-kits that you can use to create a project.\nThey are:\n Drupal 8 Drupal 7 Wordpress Magento Laravel Symfony Skeleton Symfony WebApp Grav CMS Backdrop CMS Hugo Gatsby JS Angular In addition, here are some of the other services that are available on Docksal\u0026rsquo;s Github:\n backstopjs bats behat blog blt-docksal boilerplate-bedrock boilerplate-blt boilerplate-nodejs ci-agent circleci-orbs docker-machine-smb docker-ngrok electron-app-alpha qa-suite service-jenkins service-jenkins-slave service-juniper-vpn service-socat service-solr service-varnish webui Many of these were submitted by the community to the Docksal project and have become available thanks to open-source.\nSummary Docksal\u0026rsquo;s ecosystem is made richer by starter-kits and boilerplate projects available to its framework. This shows how configurable and customizable it can be, along with allowing developers to take advantage of the work that has already been done in order to rapidly spin up applications for development.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/containers/",
"title": "Docker Containers",
"tags": [],
"description": "",
"content": " Docker Containers In our high level overview we talked briefly about Linux containers, and that\u0026rsquo;s what Docker is all about: Containers.\nA container is a self-contained application that runs on a shared kernel. Docker containers are no different. When you run an image, you are creating a container that has followed all of the instructions in your Dockerfile to become an application. This can be something as small as a line of code that spouts out Hello, world! to a fully functional operating system with everything one may need to develop a complex application in a compiled language and test it.\nSome things to note:\n A container is not permanent: If a container is removed, all data that is not in the image is destroyed. A container is portable: By sharing an image or a Dockerfile to build an image, a container can be recreated identically anywhere Docker can be found. A container is only as powerful as its host: It wouldn\u0026rsquo;t be a good idea to try running a containerized version of a graphical operating system on a Raspberry Pi. A container is limited by what is in the image: There will be no more or no less functionality than what is in the Dockerfile or image definition. In contrast to a Virtual Machine, a container is much smaller and easier to spin up, often in a matter of seconds.\nFrom Image to Container In the previous section we talked about images and how they form the blueprints for containers by following the instructions within a Dockerfile or similar. Now we\u0026rsquo;re going to run a few examples of spinning up containers.\nLet\u0026rsquo;s take the image we created in our last step and spin up a container. From within the ~/projects/docksal-training-docker/ folder we used in the last step we\u0026rsquo;re going to now run the container.\nEnter the following in your terminal:\n$ docker run -i -t \\ --name=test_container \\ image-example:1.0.0 /bin/bash This will start the container and allow us to use the command line from within the container. Go ahead and poke around a bit. It\u0026rsquo;s a fully functional Ubuntu install within a container on your host machine that took only a few seconds to setup!\nWhen you\u0026rsquo;re done, you can exit the container by entering exit at the command line. This will also stop the container.\nUp next, we\u0026rsquo;re going to explore storage options for containers.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/",
"title": "Getting Started",
"tags": [],
"description": "",
"content": " Time to Get Hands On Steps to install Docksal on your machine.\n Before Installing Installation Starting the System Beginning with a Boilerplate Installing a Drupal Site "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/addons/",
"title": "Addons",
"tags": [],
"description": "",
"content": " Using Docksal addons to make development easier We touched on creating your own commands in Advanced Customizations: Project 3, however many frequently used commands have been contributed to the Docksal project in the form of addons.\nList of current addons Name Description Requirements adminer Adminer database management tool MySQL andock Andock makes it dead simple to get Docksal environments up on your server. Docksal artisan Runs Laravel\u0026rsquo;s Artisan command in cli. Requires artisan pre-installed inside cli. Laravel, Artisan blt Acquia BLT tool launcher (requires BLT installation) Drupal codeclimate CodeClimate code quality tool mailhog Mailhog e-mail capture service for current project phpcs PHP Code Sniffer and Code Beautifier phpunit Creates a phpunit.xml file and runs PHPUnit tests Drupal pma PhpMyAdmin database management tool MySQL redis Add Redis to current project sequelpro Launches SequelPro with the connection information for current project. macOS simpletest Runs SimpleTest tests in Drupal 7 and 8 Drupal solr Apache Solr search service for current project uli Generate one time login url for current site Drupal All of these are available to install and use to make development a little quicker and easier. Let\u0026rsquo;s install an addon.\nWe\u0026rsquo;re going to install uli which is a wrapper for the Drupal Drush command drush uli.\n$ fin addon install uli This will download the file to your .docksal/addons folder and make it available to your project.\nTo run any addon, you just need to run fin [addon name]. For example:\n$ fin uli Additionally, since Docksal is an open source project, you can create your own addons and submit them back to the project. Say you have a command that speeds up your process and you think others may benefit from it. To contribute back, you would do the following:\n Fork the addons repo from https://github.com/docksal/addons Create a feature branch Add your addon into your fork of the repo Update the repo\u0026rsquo;s README.md file with your addon a description and any requirements Submit a pull request against the Docksal addons repo with a description of what your addon does and how it\u0026rsquo;s beneficial Summary Addons are generally community contributed commands that have been submitted to the Docksal project for the greater good of all users. You can use existing addons or submit your own back to the project. The process for installing an addon is simple and after an addon is in your project, you are free to tweak it to your own needs.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/storage/",
"title": "Docker Storage",
"tags": [],
"description": "",
"content": " Docker Storage As mentioned in our containers section, a container is volatile. This means that if you stop a container, you lose everything that\u0026rsquo;s not in the image the next time you start it back up. This can be painful if you\u0026rsquo;re working on a containerized project that might take more than a day. Especially if your computer decides to update and reboot without warning.\nDocker gets around this by using volumes and bind mounts. A volume is persistent storage for a Docker container, whereas a bind mount is \u0026ldquo;binding\u0026rdquo; a directory on your host machine to a container.\n Volumes Bind Mounts "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/",
"title": "Going Further",
"tags": [],
"description": "",
"content": " Doing more with docksal We\u0026rsquo;re going to get into some more advanced use cases with using Docksal.\n Customizing a Project Advanced Customizations Project 1: Configuring to Match Production Project 2: The Front-end Team Requires a Specific Version of NPM and NodeJS Project 3: Building a Multi-server Project Summary Using Local Files Adding Docksal to an Existing Project Adding Docksal to a Basic Project Adding Docksal to a Drupal Project Addons Other Docksal uses "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/getting-started/installing-drupal/",
"title": "Installing a Drupal Site",
"tags": [],
"description": "",
"content": " Let\u0026rsquo;s Do Something a Little More Advanced Now we\u0026rsquo;re going to take an existing repo, pull it down, and spin up a fully functioning Drupal site. To do this, we\u0026rsquo;re going to be using a modified fork of the Docksal Composer-based Drupal 8 repo.\nSetting up for the project To begin, we need to clone the git repository, or \u0026ldquo;repo\u0026rdquo;, at https://github.com/JDDoesDev/docksal-training-projects/. We\u0026rsquo;ll do this in the projects folder we used in the last section.\n$ cd ~/projects $ git clone [email protected]:JDDoesDev/docksal-training-projects.git $ cd docksal-training-projects $ git checkout drupal-site-step-1 Here we\u0026rsquo;re pulling the repo and checking out the Step 1 branch, where we\u0026rsquo;re going to begin working on the project.\nSpinning Up Drupal NOTE: There is a possibility that the default settings may not provision enough memory or CPU power in your virtual machine for some steps of the next section. If your build fails, then consult the Troubleshooting portion of this section.\n Now that we\u0026rsquo;ve cloned the repo we\u0026rsquo;re going to run a command we haven\u0026rsquo;t talked about yet: fin init\nBefore we run that, a little info on what fin init is and what it does. fin init is a custom command that is not part of the core Docksal package. Instead, it is customized on a project by project basis, and sometimes is not required. The purpose of fin init is usually to completely start or restart a project from a clean state.\nThis means that when you run fin init, it will remove all existing project containers and volumes, recreate them, and run any other functions defined within the script.\nLet\u0026rsquo;s run fin init and see what happens.\n$ fin init The output should start with\nStep 1 Initializing stack... Removing containers... Removing network docksal-training_default WARNING: Network docksal-training_default not found. Removing volume docksal-training_cli_home WARNING: Volume docksal-training_cli_home not found. Removing volume docksal-training_project_root WARNING: Volume docksal-training_project_root not found. Removing volume docksal-training_db_data WARNING: Volume docksal-training_db_data not found. Volume docksal_ssh_agent is external, skipping The WARNING: lines let us know that the project does not already exist, but it also points out that we\u0026rsquo;re attempting to remove the current containers as part of the fin init process.\nIf all runs according to plan you will see Composer do some things, Docksal do some things, and Drupal do some things, eventually ending with\n[notice] Starting Drupal installation. This takes a while. [success] Installation complete. User name: admin User password: 2kEpnqm4dh real 26.55 user 9.47 sys 3.42 Open http://docksal-training.docksal in your browser to verify the setup. Look for admin login credentials in the output above. DONE! Completed all initialization steps. Let\u0026rsquo;s visit our newly created Drupal site at http://docksal-training.docksal and see what we have.\nIf everything went as expected, then you should see a vanilla Drupal 8 site with no content. However, there were a few things that needed to happen for us to get this spun up and functioning. If you\u0026rsquo;ve ever installed a Drupal site, you know that ordinarily we need to alter some database settings and customize other settings for Drupal to install. Let\u0026rsquo;s take a look at where these things happened with Docksal.\nExamining fin init The fin init command exists in two pieces, both of which are inside the .docksal/commands folder.\nThe files are init and init-site\n.docksal ├── commands │ ├── init │ └── init-site When you put a file in the .docksal/commands folder, it tells Docksal that you want to make whatever is inside that file available as a command to this project, and this project only. The commands should be written as Bash scripts and it should be understood that the commands, by default, will be run from outside the container. This means that if you want something to happen inside the container, you need to wrap it in the fin command.\nInside our .docksal/commands/init file we\u0026rsquo;ll notice a few things:\nFirst, our shebang:\n#!/usr/bin/env bash If you\u0026rsquo;re unfamiliar, a shebang tells our system what it should use to run the remainder of the file. In this case, it\u0026rsquo;s being told to run the file as interpreted by bash.\nFurther down, there are two commands that are being run: fin project reset -f and fin init-site.\n fin project reset -f does exactly what it says it does. It resets the project to a clean state by removing all containers and volumes and restarting them.\n fin init-site begins the script defined at .docksal/commands/init-site\n Examining fin init-site The opening of .docksal/commands/init-site looks similar to .docksal/commands/init, but there is one line that makes a major difference:\n#: exec_target = cli This tells Docksal that we will be running the commands inside the cli container and commands don\u0026rsquo;t need to be wrapped in fin. This is extremely important to remember when customizing our project with our own commands.\nThe rest of the init-site file is comprised of the steps needed to install Drupal, including:\n Running composer install Copying our custom settings.php and settings.local.php to web/sites/default/ Fixing permissions Installing Drupal using Drush At the end of this script, it outputs how long it took to run, the URL of the new project, and the generated username and password combination. The username and password will be output during fin init a few lines above the end.\nIt will look something like:\n[notice] Starting Drupal installation. This takes a while. [success] Installation complete. User name: admin User password: When you\u0026rsquo;re finished exploring your new install, remember to shut it down using fin project stop.\nSummary In this section we pulled a customized Drupal 8 boilerplate from a git repo and spun it up on our local dev environment with one command, fin init. We also tested that our site exists by visiting the generated URL. We should have an understanding of what fin init is for and how to use it to start or restart a project from a clean state.\nWe also examined how fin init uses init-site to build a project and the steps it goes through, including telling Docksal to run the commands within the cli container.\nNext, we\u0026rsquo;re going to customize our install and our site to make it a little less default.\nTroubleshooting It is likely that your fin init may fail due to a Composer memory error. If you see output similar to the following:\nThe following exception is caused by a lack of memory or swap, or not having swap configured Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details [ErrorException] proc_open(): fork failed - Cannot allocate memory That means you\u0026rsquo;ll need to add some resources to your virtual machine.\n Run fin system stop to shut down the VM. Open your VirtualBox application. Highlight the docksal machine, making sure it is in a Powered off state. Select \u0026ldquo;Settings\u0026rdquo;. Under \u0026ldquo;System \u0026gt; Motherboard\u0026rdquo; increase the memory to 4096 MB Under \u0026ldquo;System \u0026gt; Processor\u0026rdquo; increase the CPUs to 4 Go back to your terminal and run fin system start Retry fin init "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docksal/in-the-container/",
"title": "What's in the Container?",
"tags": [],
"description": "",
"content": " Docksal Gives You Multiple Developer Tools Out of the Box As briefly mentioned in a previous section, Docksal ships with many developer tools to make developing with several common frameworks easier. The default cli service image has several without any extra configuration needed.\nTools that come with Docksal Behat - a tool for testing using human-readable language Composer - a tool for managing PHP packages Drupal Console - a Drupal CLI tool Drush - a Drupal CLI tool Acquia Drush Commands - custom Drush commands to work with Acquia ngrok - a utility for sharing local applications over the internet PHP Code Sniffer - a PHP linting and error checking tool PHPMyAdmin - a web-based GUI for interacting with databases Pantheon (Terminus) - Pantheon\u0026rsquo;s CLI tool Platform.sh - Platform.sh\u0026rsquo;s CLI tool SASS and Compass - tools for compiling SASS WP-CLI - a CLI tool for interacting with WordPress sites Xdebug - a PHP debugging utility Others are available as services With some configuration, many services can be added to your application, including:\n Apache Solr Code Server Elastic Search Memcached Redis Varnish Summary Docksal gives you several helpful utilities right out of the box that allow you to interact with your application. With some configuration, others can easily be added in.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/services/",
"title": "Docker Services",
"tags": [],
"description": "",
"content": " Docker Services Sometimes it makes sense to wrap up a few containers to work together. For example, if we don\u0026rsquo;t want to put too much on a single container to handle a database, a web server, networking, etc. we can create services in place of standard containers. Docksal relies on services extensively to create various stacks.\nServices are often part of a larger application whereas containers usually stand on their own. One of the main advantages of services compared to containers is that the pieces can easily be swapped out. Let\u0026rsquo;s say that we wanted to move hosting providers for our web application. Provider A uses Apache and PHP 7.1 and provider B uses Nginx and PHP 7.3. We could just push everything up to provider B and hope it works, but with services we can create a custom local environment that matches everything on provider B and make the changes locally. This way we can feel confident when we deploy, knowing that our application works well inside the hosting environment.\nMany of the functions of services are beyond the scope of this section of the training, however a few things that should be noted are:\n Docker services are defined individually as part of a larger application. Docker services are structured in Dockerfiles, however they are managed by docker-compose, a utility that interacts with an entire application rather than a single container Applications that use services are defined in a *.yml file, often named docker-compose.yml with several services defined along with settings and information to help everything run together. The Docker docs have many examples of using services and it\u0026rsquo;s something that we will cover more in the Configuring Docksal section later.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/not-just-for-local/",
"title": "Other Docksal uses",
"tags": [],
"description": "",
"content": " Docksal can be used in scenarios other than local development One common use for Docksal outside of local development is for running CI (continuous integration) tasks with services like TravisCI, CircleCI, or Bitbucket Pipelines.\nWhy would you want to use Docksal for CI? You might want to use Docksal for CI for the same reasons that you use Docksal for local development.\n It reproduces many aspects of the production server It\u0026rsquo;s fast to spin up and tear down It can be extremely verbose in output, helping you track down where issues are How to use Docksal for CI Depending on which service you\u0026rsquo;re using for your CI, the steps may be a little different, but the outcome is the same. We\u0026rsquo;re not going to cover setting up CI with your project\u0026rsquo;s repo in this training, but we will cover how to use Docksal in that service.\nWe\u0026rsquo;re going to use TravisCI for our scenario here.\nIn TravisCI, we are given a blank slate to work with, meaning we can set it up however we want and run whatever commands are needed in order for the project to spin up and run tests. Travis, like many CI services, runs commands based off of a YAML file. We\u0026rsquo;re only going to cover TravisCI from a very high level as it pertains to using Docksal for CI.\nLet\u0026rsquo;s take a look at a very basic .travis.yml file using Docksal and break it down:\nsudo: required language: generic dist: xenial services: - docker install: - bash \u0026lt;(curl -fsSL https://get.docksal.io) - fin version - fin sysinfo before_script: - travis_retry fin init script: - fin tests Let\u0026rsquo;s take a look at what this does:\nsudo: required language: generic dist: xenial TravisCI makes sudo available to our CI environment. This is needed for some of the commands the Dockerfile runs. TravisCI is told to use the generic language which covers what we need to run the commands we\u0026rsquo;re going to run. TravisCI installs the xenial distribution of Ubuntu. services: - docker install: - bash \u0026lt;(curl -fsSL https://get.docksal.io) - fin version - fin sysinfo We tell TravisCI to install Docker as a required service. We tell TravisCI to install Docksal. Check that Docksal is installed by running fin version and fin sysinfo.\nIf either of these commands fail, then we get a failed build and we\u0026rsquo;ll have to look into it. If they succeed, then we can continue on.\n before_script: - travis_retry fin init script: - fin tests fin init runs to spin up our project. If it fails during this step, our build fails and we need to find out why. NOTE: We prefixed this with travis_retry. This is a wrapper that will retry the following command 3 times before failing. Useful in the event that the healthcheck gets hung up or composer has issues. The actual script to be run is fin tests which would be a custom command that defines tests to be run for a site. These can be PHPUnit, Behat, Cypress, Backstop, or any other type. Usually the command would be a wrapper for fin exec phpunit... or similar. Customizing for CI If we wanted, we could create a custom command to run specifically for CI. This may be called init-ci and contain steps that are only important to testing or deploying within a CI environment.\nWe could also setup custom Docksal variables and services in docksal-ci.env and docksal-ci.yml by setting the DOCKSAL_ENVIRONMENT=ci environmental variable.\nLet\u0026rsquo;s say that even though you\u0026rsquo;re using a host like Acquia and the Acquia stack on local, you don\u0026rsquo;t need everything installed. You could probably do without Varnish, Memcache, and Solr. We could adjust these for the build by creating docksal-ci.env and docksal-ci.yml.\nFirst, we would add\nenv: global: - DOCKSAL_ENVIRONMENT=ci to .travis.yml.\nThen create our docksal-ci.env file\n$ cd .docksal $ touch docksal-ci.env Open this file and add\nDOCKSAL_STACK=\u0026#34;default\u0026#34; At this time, we don\u0026rsquo;t need to change our PHP version or anything, so we won\u0026rsquo;t create docksal-ci.yml.\nSummary Docksal can be used for more than just local development. It can be used for CI and deployments and configured to run almost anything that you might need in a CI environment. Another use case is for setting up a sandbox environment on a server to test feature or show off projects. You can read more about that in the blog post Installing Docksal on a remote server.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/intro-docker/docker-basics/docker-components/registries/",
"title": "Docker Registries",
"tags": [],
"description": "",
"content": " Docker Registries A registry is where images are stored. The most common of these is Docker Hub. This is normally where custom Dockerfiles pull images down from to build custom images. Docker Hub allows you to search for both official and unofficial images to be used in your projects, extended into custom images, or studied to see how the whale sausage is made.\nNOTE: The trainers do not condone the hunting of whales for the making of whale sausage. Whales are beautiful, endangered creatures.\n It is possible to add custom registries or even private registries to your Docker setup, but that is outside the scope of this training. Please consult the Docker docs\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/advanced-customizing/project-1/",
"title": "Project 1: Configuring to Match Production",
"tags": [],
"description": "",
"content": " Scenario For this project, we\u0026rsquo;re going to use the following scenario:\nYour client has a site on Acquia using PHP 7.3. You know that the default Docksal Acquia stack uses PHP 7.2, but you want to match environments. How do you do this?\n Choose the right stack We\u0026rsquo;re going to start by configuring Docksal to use the Acquia stack. In your docksal.env file, find the line DOCKSAL_STACK=pantheon and change it to DOCKSAL_STACK=acquia.\nConfigure the docroot Acquia projects require that the Drupal installation live in docroot instead of web. This is the default webroot for Docksal, but to remain verbose we\u0026rsquo;re going to change the environment variable. Find the line DOCROOT=web and change it to DOCROOT=docroot\nUpdate docroot and composer.json Since our projects have been using the web folder for the docroot so far, we need to rename it. This is most easily accomplished in an IDE or in your system\u0026rsquo;s version of a file explorer, however you can do this on a macOS or Linux terminal by using the mv command. mv web docroot. In addition, we also need to update our composer.json file to point to the correct folders.\nIn composer.json, in the extra.installer-paths section, you need to change all instances of web/ to docroot/. Example: \u0026quot;web/core\u0026quot;: [\u0026quot;type:drupal-core\u0026quot;], becomes \u0026quot;docroot/core\u0026quot;: [\u0026quot;type:drupal-core\u0026quot;],\nConfigure the PHP version The PHP version is defined in the cli service. The default image for the cli service is docksal/cli:2.6-php7.2. We can change this in docksal.env by adding the following variable: CLI_IMAGE=docksal/cli:2.9-php7.3. This is the latest version of this image tagged with PHP 7.3.\nInside ~/.docksal/stacks/services.yml the cli section runs logic for the image version: image: ${CLI_IMAGE:-docksal/cli:2.6-php7.2} which checks to see if the CLI_IMAGE environment variable is set, and if not, uses the default.\nUpdate your project The easiest way to do this is to run fin up, however if you have not initialized your project yet, you should run fin init. For this exercise we\u0026rsquo;re going to run fin init.\nRun fin init and watch as the images that aren\u0026rsquo;t on your system are pulled down and your project spins up using PHP 7.3.x.\nThe completed code for Project 1 can be found at https://github.com/JDDoesDev/docksal-training-projects/tree/adv-cust-project-1\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/advanced-customizing/project-2/",
"title": "Project 2: The Front-end Team Requires a Specific Version of NPM and NodeJS",
"tags": [],
"description": "",
"content": " Scenario For this project, we\u0026rsquo;re going to use the following scenario:\nThe front-end team is using a theme that is shared across multiple projects as a starter-kit. In order to reduce compatibility errors, they have requested that the Docksal setup accounts for this by locking to a specific version of NodeJS and NPM so that they don\u0026rsquo;t have to completely overhaul the NPM dependencies.\n To accomplish this, we\u0026rsquo;re going to do a couple of things in order to lock a version of NodeJS and NPM.\nLock the versions in a custom Dockerfile We\u0026rsquo;re going to create a custom Dockerfile that extends the default cli image within our project.\n Create the Dockerfile at .docksal/services/cli/Dockerfile Extend the current image by starting the file with\nFROMdocksal/cli:2.9-php7.3 This tells Docksal that we\u0026rsquo;re still going to use this image, but we\u0026rsquo;re doing something more with it.\n Change the Dockerfile user so that settings aren\u0026rsquo;t changed as root\nUSERdocker Run commands that will install and lock the version of NodeJS and NPM.\nRUN set -e; \\ # Note the \u0026#39;;\u0026#39; and the \u0026#39;\\\u0026#39;. # Initialize the user environment (this loads nvm) . $HOME/.profile; \\ # Install the necessary nodejs version and remove the unnecessary version nvm install 8.11.0; \\ nvm alias default 8.11.0; \\ nvm use default; \\ nvm uninstall 10.16.3; \\ # Install packages npm install -g [email protected]; \\ # Cleanup nvm clear-cache \u0026amp;\u0026amp; npm cache clear --force; \\ # Fix npm complaining about permissions and not being able to update sudo rm -rf $HOME/.config Notice that every command in the RUN directive is followed with ; \\ except the last line. This is because RUN directives are concatinated into a single line when run.\nWe\u0026rsquo;re sourcing the ~/.profile file and getting our NVM (Node Version Manager) alias early on so that we can choose our version. In this case, we\u0026rsquo;re using 8.11.0. Following that, we set this version as our default.\nNext, we install our locked version of NPM, clean up our caches, and then run some permission fixes, but we\u0026rsquo;re not done yet.\n Return control to the root user.\nUSERroot Our completed Dockerfile should look like this\nFROM docksal/cli:2.9-php7.3 USER docker # Install additional global npm dependencies RUN set -e; \\ # Initialize the user environment (this loads nvm) . $HOME/.profile; \\ # Install the necessary nodejs version nvm install 8.11.0; \\ nvm alias default 8.11.0; \\ nvm use default; \\ nvm uninstall 10.16.3; \\ # Install packages npm install -g [email protected]; \\ # Cleanup nvm clear-cache \u0026amp;\u0026amp; npm cache clear --force; \\ # Fix npm complaining about permissions and not being able to update sudo rm -rf $HOME/.config USER root Call the custom Dockerfile In docksal.yml we\u0026rsquo;re going to define our cli service.\n Open .docksal/docksal.yml Add the following to the cli: section:\ncli: image: ${COMPOSE_PROJECT_NAME_SAFE}_cli build: services/cli This names the image based on our project\u0026rsquo;s name and then tells Docksal where to find the file we\u0026rsquo;re going to build the new image from.\n Update the project Instead of running fin init here, we\u0026rsquo;re going to run fin up. Keep an eye on the output as the new image is built.\n$ fin up Starting services... Building cli Step 1/4 : FROM docksal/cli:2.9-php7.3 ---\u0026gt; bef7b0b7014f Step 2/4 : USER docker ---\u0026gt; Using cache ---\u0026gt; d563a10b8db0 Step 3/4 : RUN set -e; . $HOME/.profile; nvm install 8.11.0; nvm alias default 8.11.0; nvm use default; npm install -g [email protected]; nvm clear-cache \u0026amp;\u0026amp; npm cache clear --force; sudo rm -rf $HOME/.config ---\u0026gt; Running in d503e299f557 /bin/sh: 39: /home/docker/.profile: [[: not found Downloading and installing node v8.11.0... Downloading https://nodejs.org/dist/v8.11.0/node-v8.11.0-linux-x64.tar.xz... ######################################################################## 100.0% Computing checksum with sha256sum Checksums matched! Now using node v8.11.0 (npm v5.6.0) default -\u0026gt; 8.11.0 (-\u0026gt; v8.11.0) Now using node v8.11.0 (npm v5.6.0) Uninstalled node v10.16.3 /home/docker/.nvm/versions/node/v8.11.0/bin/npx -\u0026gt; /home/docker/.nvm/versions/node/v8.11.0/lib/node_modules/npm/bin/npx-cli.js /home/docker/.nvm/versions/node/v8.11.0/bin/npm -\u0026gt; /home/docker/.nvm/versions/node/v8.11.0/lib/node_modules/npm/bin/npm-cli.js + [email protected] added 247 packages, removed 41 packages and updated 129 packages in 25.413s nvm cache cleared. npm WARN using --force I sure hope you know what you are doing. Removing intermediate container d503e299f557 ---\u0026gt; 4d9ec2ec20f4 Step 4/4 : USER root ---\u0026gt; Running in 70ebd3d709ff Removing intermediate container 70ebd3d709ff ---\u0026gt; 1c70700b6839 Successfully built 1c70700b6839 Successfully tagged my-first-docksal-project_cli:latest Every step in the Dockerfile is tagged in the image with a hash.\nStep 1/4 : FROM docksal/cli:2.9-php7.3 ---\u0026gt; bef7b0b7014f The hash bef7b0b7014f indicates a layer of the image. If something were to break when building the image, this gives us a point of reference to examine the image and see what happened. As you can see, our image built successfully and our system now has the correct versions of NodeJS and NPM installed. We can check this by running the following:\n$ fin exec node -v v8.11.0 $ fin exec npm -v 6.1.0 Now our front-end team has the version they need installed, and everyone is happy.\nThe completed code for Project 2 can be found at https://github.com/JDDoesDev/docksal-training-projects/tree/adv-cust-project-2\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/advanced-customizing/project-3/",
"title": "Project 3: Building a Multi-server Project",
"tags": [],
"description": "",
"content": " Scenario For this lesson we\u0026rsquo;re going to look at the following scenario:\nA client wants a decoupled solution to be hosted on two servers. The Drupal side will be hosted on Acquia and the front-end side will be hosted on a different server. The project is going to use GatsbyJS for the front-end.\n Now, we can build off our last step by continuing to grow our docksal.yml and docksal.env files. We\u0026rsquo;re also going to add in some custom commands to make our life a little bit easier in the long run.\nLet\u0026rsquo;s start off by listing what we\u0026rsquo;re going to needing for this project:\n A Drupal installation on an Acquia Stack Multiple domains Two different simulated servers The ability to connect the two servers NodeJS npm Gatsby CLI Now, we could simulate the different servers by simply using multiple VirtualHosts in Apache, but that\u0026rsquo;s not really simulating separate servers. Instead, it\u0026rsquo;s using the same web server to host projects in different locations. To overcome this, we\u0026rsquo;re going to simulate by keeping the Gatsby web server in its own service, separate from the Drupal site.\nHowever, we can still use a shared codebase so that we only need to maintain a single git repo.\nLet\u0026rsquo;s get started:\nCreate a Custom Gatsby Service - Dockerfile To do this we\u0026rsquo;re going to use both a custom Dockerfile and edit our docksal.yml. Let\u0026rsquo;s begin by creating the custom Dockerfile.\n Create the file .docksal/services/gatsby/Dockerfile We\u0026rsquo;re going to extend the default Docksal CLI image so start the file with:\nFROMdocksal/cli:2.9-php7.3 We want to run all of our installations as our default container user \u0026ldquo;docker\u0026rdquo; so we need to make sure to switch users in the Dockerfile.\nUSERdocker Now we want to ensure that the commands run in Bash instead of the default shell. We need to tell the image to build that way.\nSHELL [\u0026#34;/bin/bash\u0026#34;, \u0026#34;-c\u0026#34;] This tells Docker to build this layer of the image as though it were in a Bash shell. The flag -c tells it to get ready for the command.\n This next section should look pretty familiar. We\u0026rsquo;re going to tell the image to add in a locked version of NodeJS, a locked version of NPM, and this time we\u0026rsquo;re adding in Gatsby CLI.\nRUN set -e; \\ # Initialize the user environment (this loads nvm) source $HOME/.profile; \\ # Install the necessary nodejs version nvm install 10.15.0; \\ nvm alias default 10.15.0; \\ nvm use default; \\ # Install packages npm install -g [email protected]; \\ npm install -g gatsby-cli; \\ # Cleanup nvm clear-cache \u0026amp;\u0026amp; npm cache clear --force; \\ # Fix npm complaining about permissions and not being able to update sudo rm -rf $HOME/.config; The biggest changes here from our last project are that we\u0026rsquo;re locking NodeJS at 10.15.0, we\u0026rsquo;re installing npm 6.4.1, and we\u0026rsquo;re installing Gatsby CLI.\n We need to return to the default shell and switch back to the root user.\nSHELL [\u0026#34;/bin/sh\u0026#34;, \u0026#34;-c\u0026#34;]USERroot Just like our earlier SHELL directive, we\u0026rsquo;re running the command to change back to sh, the default shell, and then switching to the root user for further commands.\n Finally, we need to tell our service to expose the port that the development server for Gatsby runs on. In this case, 8000.\nEXPOSE8000 The final Dockerfile should look like this:\nFROMdocksal/cli:2.9-php7.3USERdockerSHELL [\u0026#34;/bin/bash\u0026#34;, \u0026#34;-c\u0026#34;]# Install additional global npm dependenciesRUN set -e; \\ # Initialize the user environment (this loads nvm) source $HOME/.profile; \\ # Install the necessary nodejs version nvm install 10.15.0; \\ nvm alias default 10.15.0; \\ nvm use default; \\ # Install packages npm install -g [email protected]; \\ npm install -g gatsby-cli; \\ # Cleanup nvm clear-cache \u0026amp;\u0026amp; npm cache clear --force; \\ # Fix npm complaining about permissions and not being able to update sudo rm -rf $HOME/.config;SHELL [\u0026#34;/bin/sh\u0026#34;, \u0026#34;-c\u0026#34;]USERrootEXPOSE8000 Save the Dockerfile and close it out.\nCreate a Custom Gatsby Service - docksal.yml Now that we have our Dockerfile created, we need to tell Docksal to use it when putting together the application. For that, we need to open .docksal/docksal.yml and make some changes.\nRemember, indentation matters in a YAML file.\n In our docksal.yml file we\u0026rsquo;re going to define a new service. This will go under the parent services and should have the same indentation as our customized cli service. We\u0026rsquo;re going to name this service gatsby.\nversion: \u0026#34;2.1\u0026#34; services: cli: ... gatsby: In order to function within our application, there are a few things that we need to pass to the gatsby service. The host user ID, the host group ID, and the DNS information. We can pass the host user and group IDs through the environment component and the DNS settings through the DNS component.\ngatsby: environment: - HOST_UID - HOST_GID dns: - ${DOCKSAL_DNS1} - ${DOCKSAL_DNS2} The DOCKSAL_DNS1 and DOCKSAL_DNS2 variables are defined in the fin binary based on the local IP address of the Docksal VM and the remote DNS server 8.8.8.8\n Now we need to tell Docksal a little more about our service. We\u0026rsquo;re going to do this by defining the hostname, the image name, and where to build the image from. We can do this by adding a few more items to our docksal.yml. For consistency with other services, we\u0026rsquo;re going to place these immediately following the gatsby: declaration.\ngatsby: hostname: gatsby image: ${COMPOSE_PROJECT_NAME_SAFE}_gatsby build: ${PROJECT_ROOT}/.docksal/services/gatsby environment: ... The hostname is what we can use to identify this service without having to type the entire service name out.\nAlso, notice that we did not include Dockerfile in our build. This is on purpose because Docker knows we\u0026rsquo;re looking for a Dockerfile.\n It\u0026rsquo;s time to tell Docksal what domain to use for this service. We\u0026rsquo;re going to do this by using labels. We\u0026rsquo;ll be using the io.docksal.virtual-host, io.docksal.virtual-port, and io.docksal.cert-name labels for this.\nOne thing to note is that when we run the command to start the development server for Gatsby, it\u0026rsquo;s going to start a NodeJS process so the domain will point directly to this service and load what is being served by NodeJS.\nAdd the following below your build: line:\nlabels: - io.docksal.virtual-host=gatsby.${VIRTUAL_HOST} - io.docksal.virtual-port=8000 - io.docksal.cert-name=${VIRTUAL_HOST_CERT_NAME:-none} These set the domain, which will be gatsby.mycustomsite.docksal, the port that this domain will point to, and the cert name if we want or need to simulate an SSL environment.\n Next, we need to tell the service where it should look for files to mount a volume. We\u0026rsquo;ll do this using volumes: and point specifically to the gatsby folder.\nBelow your labels put in the volumes: information\nvolumes: - ${PROJECT_ROOT}/gatsby:/var/www/gatsby - ${SSH_AUTH_SOCK:-docksal_ssh_agent}:${SSH_AUTH_SOCK:-/.ssh-agent}:ro We\u0026rsquo;re pointing this service to create an unnamed volume mounted to our gatsby folder that will exist as /var/www/gatsby within the container. We\u0026rsquo;re also passing along our SSH keys in case we need them for anything.\n Now some final touches to make life easier. We\u0026rsquo;re going to add in a working_dir that makes it easier for us to run commands in our container, and a little environment variable that allows for us to watch for file changes, which is very handy when working with something using any kind of live-reload functionality.\nWe do this because the NFS bind we\u0026rsquo;re using for our volumes does not track file changes and send notifications. Instead, we\u0026rsquo;re using Chokidar, an NPM package that simulates filesystem events.\nAdd the following to your docksal.yml:\nenvironment: - HOST_UID - HOST_GID - CHOKIDAR_USEPOLLING=1 # \u0026lt;== New Line working_dir: /var/www/gatsby # \u0026lt;== New Line Our docksal.env should look like this now:\nversion: \u0026#34;2.1\u0026#34; services: cli: image: ${COMPOSE_PROJECT_NAME_SAFE}_cli build: ${PROJECT_ROOT}/.docksal/services/cli environment: - COMPOSER_MEMORY_LIMIT - SITE_NAME gatsby: hostname: gatsby image: ${COMPOSE_PROJECT_NAME_SAFE}_gatsby build: ${PROJECT_ROOT}/.docksal/services/gatsby labels: - io.docksal.virtual-host=gatsby.${VIRTUAL_HOST} - io.docksal.virtual-port=8000 - io.docksal.cert-name=${VIRTUAL_HOST_CERT_NAME:-none} - io.docksal.shell=bash volumes: - ${PROJECT_ROOT}/gatsby:/var/www/gatsby - ${SSH_AUTH_SOCK:-docksal_ssh_agent}:${SSH_AUTH_SOCK:-/.ssh-agent}:ro environment: - HOST_UID - HOST_GID - CHOKIDAR_USEPOLLING=1 working_dir: /var/www/gatsby dns: - ${DOCKSAL_DNS1} - ${DOCKSAL_DNS2} But don\u0026rsquo;t close it out yet. There\u0026rsquo;s a bit more to do here.\n Add a Custom Web Service for the Static Build In order to fully simulate a two server setup, we want to let our Gatsby static site have its very own web server. We\u0026rsquo;re going to do this by creating a custom web service that will handle the requests to the static site and route them to the Gatsby service and volume.\n Start by creating another service in your docksal.yml file. Call it gatsby_web. This should be the same indentation as your other services.\ngatsby_web: We\u0026rsquo;re going to use the docksal/apache:2.4-2.3 image for this so let\u0026rsquo;s add that image to our service.\ngatsby_web: image: docksal/apache:2.4-2.3 Next, tell Apache where to point the webserver by creating a volume for the server.\ngatsby_apache: image: docksal/apache:2.4-2.3 volumes: - ${PROJECT_ROOT}/gatsby:/var/www/gatsby We need to set an environment variable to tell apache where the docroot of our project is, otherwise it defaults to /var/www/docroot. We\u0026rsquo;ll set that next.\nenvironment: - APACHE_DOCUMENTROOT=/var/www/gatsby/public Finally, we\u0026rsquo;re going to assign the domain using a label, much like we did with our gatsby service.\nlabels: - io.docksal.virtual-host=static.${VIRTUAL_HOST} Our new service should look like:\ngatsby_apache: image: docksal/apache:2.4-2.3 volumes: - ${PROJECT_ROOT}/gatsby:/var/www/gatsby environment: - APACHE_DOCUMENTROOT=/var/www/gatsby/public labels: - io.docksal.virtual-host=static.${VIRTUAL_HOST} We are not going to cover building a decoupled project here, but to test this you could create an index.html inside the gatsby\\public folder, run fin project start because fin up may not capture all of your changes, and visit static.mycustomsite.docksal to see it load.\n Create a custom command to run commands inside our new service It should be noted that normal fin exec commands will not run anything inside this service. If you need to run a command in a custom cli-type service, you\u0026rsquo;ll need to add a few things to the command or create a custom command. An example of this would be running gatsby develop. Also, running fin bash will not get you into the service. For both of these commands you need to tell Docksal which service you are addressing.\nFor fin exec we\u0026rsquo;ll need the --in flag, and for fin bash we need to add the service name as an argument.\nExample:\n$ fin exec --in=gatsby gatsby develop or\n$ fin bash gatsby If you run these commands now, you may notice some things. One, the fin exec example doesn\u0026rsquo;t work, and two, the fin bash example gets you to a sh shell instead of bash.\nBy default, only the cli and db services have access to bash with fin exec. To get around this we need to wrap our commands with a few things. First we need to tell Docksal what user we want to run the commands as. Remember, when we created our Dockerfiles we created the user docker. Now we need to tell Docksal to run the command with this user and we do so by passing a variable to the command.\nExample:\n$ container_user=\u0026#34;-u docker\u0026#34; fin exec --in=gatsby The container_user variable is used in the fin binary to add arguments to the Docker commands that make Docksal work, which is why it\u0026rsquo;s -u docker and not just docker.\nHowever, this does not give us access to the bash shell. What we need to do is tell Docksal to run this command in bash. We do that by actually executing the bash executable.\n$ container_user=\u0026#34;-u docker\u0026#34; fin exec --in=gatsby bash -lc \u0026#34;gatsby develop\u0026#34; The command here is telling fin to execute, in the container gatsby the bash executable. We pass in the -l flag to act as though it were invoked by a login shell, which gives us access to the aliases and commands in the .bash_profile and the -c flag to let bash know that we\u0026rsquo;re giving it a command to run. Finally, we\u0026rsquo;re giving it the command \u0026quot;gatsby develop\u0026quot;.\nThis can be a bit unwieldy to type so we could create an alias for it, but to make it reusable for others who may be working on this project, we want to add it to the repo somehow. We can do this by defining a custom command.\n In your .docksal/commands folder create the file gatsby-develop. Go back to your project root, ~/projects/docksal-training-projects/, and create this file.\n$ cd .docksal/commands $ touch gatsby-develop $ chmod +x gatsby-develop In this example we create the file and then we make it executable by running chmod +x. This is necessary for it to run as a command, although Docksal is smart enough to try and fix it for you if you forget.\n In your editor, open this file up and let\u0026rsquo;s add some things to it.\nSince it\u0026rsquo;s a bash script, we need our shebang:\n#!/usr/bin/env bash We also need our command:\ncontainer_user=\u0026#34;-u docker\u0026#34; fin exec --in=gatsby bash -lc \u0026#34;gatsby develop\u0026#34; Now save this file and go back to your project root.\n Run the new command:\n$ fin gatsby-develop Docksal will now pass in the command to the service and attempt to run gatsby develop, however it will error because we never installed Gatsby in this exercise.\n Create a command to shell into your gatsby service\n We also want an entry point so that we can run more than just one command. For our default cli service, we can just run fin bash, but that will not work for our custom gatsby service. Instead, we\u0026rsquo;re going to create the gatsby-bash command.\n In your .docksal/commands folder create the file gatsby-bash.\nGo back to your project root, ~/projects/docksal-training-projects/, and create this file.\n$ cd .docksal/commands $ touch gatsby-bash $ chmod +x gatsby-bash In your editor, open this file up and create the command.\nSince it\u0026rsquo;s a bash script, we need our shebang:\n#!/usr/bin/env bash We also need our command:\ncontainer_user=\u0026#34;-u docker\u0026#34; fin exec --in=gatsby bash -il This time we\u0026rsquo;re not passing a command, but we\u0026rsquo;re using the -i flag instead of the -c flag. The -i flag indicates that we want to run this as an interactive shell and we also want it to have all of the commands from our .bash_profile file.\nNow save this file and go back to your project root.\n From your project root run the new command:\n$ fin gatsby-bash You will now be inside your service, able to run any commands available to your project.\ndocker@gatsby:/var/www/gatsby$ Remember, you can exit out of your service by running the exit command to get back to your host machine\u0026rsquo;s command line.\n The completed code for Project 3 can be found at https://github.com/JDDoesDev/docksal-training-projects/tree/adv-cust-project-3\n "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/going-further/advanced-customizing/summary/",
"title": "Summary",
"tags": [],
"description": "",
"content": " Summary In this section we went through many of the advanced customizations we can do with Docksal services using docksal.yml, docksal.local, and even a couple of custom Dockerfiles. We created a two server application, changed hosting providers, wrote our own fin commands, and locked down versions of certain tools to keep our team happy. As you can see, Docksal is an extremely flexible and powerful tool.\nNext, we\u0026rsquo;re going to look into using local files for settings and variables that should not live in the repo.\n"
},
{
"uri": "https://jddoesdev.github.io/docksal-training/categories/",
"title": "Categories",
"tags": [],
"description": "",
"content": ""
},
{
"uri": "https://jddoesdev.github.io/docksal-training/amp/",
"title": "Modern Local Development With Docksal",
"tags": [],
"description": "",
"content": " Welcome! "
},
{
"uri": "https://jddoesdev.github.io/docksal-training/tags/",
"title": "Tags",
"tags": [],
"description": "",
"content": ""
}]