Docker for Mac has some networking and filesystem limitations as opposed to running Docker on a Linux environment.
This example shows how you could overcome those limitations and use hypernode-docker as a practical development environment on Mac OSX.
After setting this up, your application will be available in a dockerized hypernode environment while still being able to use your IDE's development capability's like code intelligence.
This minimal example follows the same practices used within hypernode-docker-osx development setup but without all the additional scripting and configurations.
We used Docker for mac for this setup. You should have that ready before proceeding.
In addition to the hypernode-docker container we used the following to overcome the limitations:
- Docker-sync (Improves disk performance when mounted / synced)
- docker-compose (for additional configurations, should be part of Docker for mac)
Installing docker-sync
# If you have 'gem' available
gem install docker-sync
# Else, if you have 'brew' available
# https://github.com/EugenMayer/docker-sync/wiki/docker-sync-on-OSX
brew install unison
brew install eugenmayer/dockersync/unoxBesides unison, there are more sync strategies available.
We need the following files to set things up:
- docker-compose.yml
- docker-sync.yml
Copy those files to your project for editing (preferably one directory above your source code)
The minimal setup requires you to specify the path to your source code and optionally change ports if they are not available.
Specify the path to your projects' source code
To have our project synced between the folder in our IDE and hypernode-docker, we have to define the path to the folder we want to sync in 'src', and where we want to sync it to in our hypernode (magento2/public)
# docker-sync.yml
syncs:
myproject-app-sync:
src: './magento' # <<<----- Path to local directory
# docker-compose.yml
volumes:
- app-sync:/data/web/public:nocopy # <<<----- Path to directory in hypernode-docker (currently: /data/web/public)Magento 2 example
# docker-sync.yml
syncs:
myproject-app-sync:
src: './magento' # Local directory
# docker-compose.yml
volumes:
- app-sync:/data/web/magento2:nocopy # <<<---- /data/web/magento2 - create symlinks to public laterYou could also specify an empty directory in 'src' and have the hypernode-importer import the store afterwards.
Handle port conflicts (Optional: if port 80/3306 is not available on your mac)
The hypernode container runs on localhost, if you have a local web server like MAMP on port 80, docker won't start because of a port conflict. Change the conflicting ports to something available in `docker-compose.yml.
# docker-compose.yml
ports:
- '2222:22' # Connect with: ssh app@127.0.0.1 -p 2222
- '8080:80' # Maps port 80 to 8080 -> http://localhost:8080
- '3307:3306'You could also just remove the 3306 port mapping and use SSH tunneling with Sequel Pro instead if you like a MySQL GUI.
You can go to great lengths with a setup like this, In addition to the minimal configurations, you could configure things even further.
Multiple projects
Be aware of port/name conflicts when setting up multiple projects, Use the project name as a prefix. (example: coolstore.shop)
# docker-sync.yml
syncs:
coolstore-app-sync: # Prefixed with project name, matches volume name (must be unique)
src: './magento'
# docker-compose.yml
services:
hypernode-docker:
container_name: coolstore-docker # Use the same project prefix to keep things organised
...
volumes:
- app-sync:/data/web/public:nocopy
...
volumes:
app-sync:
external:
name: 'coolstore-app-sync' # Matches name in docker-sync.ymlAdd development domains to your hosts file
If you want your hypernode-docker instance to respond to something more descriptive than localhost, You should edit your /etc/hosts file with for example: 127.0.0.1 myproject-mydomain.tld
sudo nano /etc/hosts# /etc/hosts
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 myproject-hyperdocker.io # <=== our development domain
Configure your volume sync
docker-sync doesn't have to keep track of all changes that happen in your Magento installation, only the things that matter. With all the caching, compiling and logging Magento does these days docker-sync might be rather busy
and it could be wise to define what should be watched and synced, and what not.
If it's ignored by git, you could exclude it. There are things you maybe don't wan't to exclude like your media/wysiwyg folder if your working with images. Below is an example of how a sync could be configured.
# docker-sync.yml
syncs:
magento2-app-sync:
src: './magento'
sync_excludes: ['vendor', 'var','pub/media/catalog/product/cache','pub/static','pub/media/tmp','dev','generated']
watch_excludes: ['vendor', 'var','pub/media/catalog/product/cache','pub/static','pub/media/tmp','dev','generated','lib','setup','update','.*/.git', '.*/node_modules'] # Only changes in app and media
sync_userid: '1000'
notify_terminal: true
monit_enable: true
monit_interval: 10
monit_high_cpu_cycles: 6For more configuration options, see Docker-sync configurations
When all is configured, It's time to boot our environment.
1. docker-sync start
We have start docker-sync first for our volumes to become available. Head to the directory that contains docker-sync.yml and run:
# Starting docker-sync
# Make sure the directory in 'src' exists or it wil error!
docker-sync startIf the folder you specified in src is empty, it only takes a few seconds. If it's a full Magento installation, the initial sync could take up to a few minutes based on the size. Wait for it to finish, otherwise docker can't find the volume and won't start.
You know it's ready when you see something similar to below.
# ok starting initial sync of myproject-app-sync
# success Sync container started
# success Starting Docker-Sync in the background2. docker-compose up
Open a new terminal / screen session, head to your directory containing the docker-compose.yml and run:
docker-compose upWhen it's done you will see:
myproject-hypernode-docker | *** Booting runit daemon...
myproject-hypernode-docker | *** Runit started as PID 272
Your environment should now be available on the ports you specified.
3. Login with SSH
To login over SSH, use the configured port together with the -p parameter, for example:
# Default password for app/root: insecure_docker_ssh_password
ssh -A app@127.0.0.1 -p 2222(important) Before you shutdown
Shutting down means losing everything that is not in a synced place. For example imported databases, modified nginx files, additional dotfiles etc. Ensure to export your database before shutting down, this allows you to easily import it when you boot it back up. To deal with the loss of these kind of things, you could add extra volume mounts.
The example below adds 2 more mounts, bin (provisioning/ configuration scripts), shared (storing backups, dumps and others). the volumes in the example below don't use docker-sync as they won't be heavily used.
# docker-compose.yml
...
volumes:
- './shared:/data/web/shared' # For database dumps, backups, config files, etc
- './bin:/data/web/bin' # For scripts to help you configure, prepare for shutdown, etc.
- app-sync:/data/web/public:nocopy # docker-sync mount