Hypernode-docker

in Tools

The official Hypernode Docker image for Magento development is now available. This image can be used to set up a fast and easy local development environment for Hypernode, or as a build machine in a CI environment representative of the production environment. The image contains the exact same packages and configuration as a real Hypernode except for some Docker specific tweaks. By testing and developing against this image you can be sure that when you deploy to a Hypernode in production there will be no surprises because of different software versions or configurations.

About the Hypernode Docker image

We build this image multiple times a day (every time we do a release) by applying our configuration management on the phusion/baseimage-docker ‘fat’ container. By treating the Docker as a lightweight VM instead of as a vehicle for a single process we stay close to what an actual Hypernode actually looks like. No micro-services or a multi-container application, but a single instance with minimal network overhead and all batteries included.

The hypernode-docker image has SSH, PHP, NGINX, MySQL, Redis and Varnish. The biggest difference between a real Hypernode and this container is that this environment does not have an init system. While it is possible to run systemd within a Docker Container if the host is also runs systemd, we choose not to do so to achieve greater compatibility and user-friendliness.

Usage

Start the Docker and logging in

Starting the container

docker pull docker.hypernode.com/byteinternet/hypernode-docker:latest
docker run docker.hypernode.com/byteinternet/hypernode-docker:latest

Get the IP address

# Find the container ID
docker ps <span class="token tag"><span class="token punctuation"><</span>docker <span class="token attr-name">name</span><span class="token punctuation">></span></span>
# Find the IP address of the container
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <span class="token tag"><span class="token punctuation"><</span>the <span class="token attr-name">container</span> <span class="token attr-name">ID</span><span class="token punctuation">></span></span>

Log in to the container:

# SSH into the machine using the retrieved IP address. Example:
ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null app@172.17.0.2
# Or as the root user
ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null root@172.17.0.2

The password is insecure_docker_ssh_password, or use the pregenerated key.

Restarting services

Because systemctl is not available inside the container, the services are started by an init script on container startup. Note that because the systemd unit files are not parsed there could be a slight drift between what commandline flags the processes actually use in production compared to in this contanier.

To restart all services run:

bash /etc/my_init.d/60_restart_services.sh

If you only want to restart a specific service, inspect the restart_services.sh script and kill the screen for the service you want to restart. Then run the corresponding screen command to start the service again.

Starting the container

running the container on the foreground

To start the container in the foreground, run the following command:

$ docker pull docker.hypernode.com/byteinternet/hypernode-docker:latest
$ docker run docker.hypernode.com/byteinternet/hypernode-docker:latest
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/my_init.d/10_login_instructions.sh...
_
/\ /\_ _ _ __ ___ _ __ _ __ ___ __| | ___
/ /_/ / | | | '_ \ / _ \ '__| '_ \ / _ \ / _` |/ _ \
/ __ /| |_| | |_) | __/ | | | | | (_) | (_| | __/
\/ /_/ \__, | .__/ \___|_| |_| |_|\___/ \__,_|\___|
|___/|_|

Host/IP: xxxxx-dummytag-docker.nodes.hypernode.io (172.17.0.3)
Account_id: 666
Release: release-5278-28-ga9d3844 @ 2018-06-05 12:56:34 UTC

Handy commands (more at http://support.hypernode.com):

livefpm (see live PHP status)
tal | pnl (follow live requests)

hypernode-importer (import a Magento shop)
hypernode-image-optimizer (reduce image size)
hypernode-ftp (manage FTP accounts)

magerun list (many useful extensions)

------------------------------------------------------------------------------
The SSH daemon will be up in a couple of seconds, you can login with: ssh -A app@172.17.0.3
*** Running /etc/my_init.d/50_copy_key.sh...
*** Running /etc/my_init.d/50_fix_mailname.sh...
*** Running /etc/my_init.d/51_postfix.sh...
* Starting Postfix Mail Transport Agent postfix
...done.
*** Running /etc/my_init.d/60_restart_services.sh...
Killing old Hypernode services
Killing any old NGINX service
Killing any old Redis service
Killing any old PHP-FPM service
Killing any old MySQL service
Killing any old Mailhog service
Killing any old Varnish service
Giving any old services 5 seconds to stop..
No Sockets found in /var/run/screen/S-root.

Starting new detached hypernode services. See screen -x
Starting NGINX
Starting Redis
Starting PHP
Starting MySQL
Starting Mailhog
Starting Varnish
Giving the new services a couple of seconds to start..
hypernode-docker status: everything ok
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 312

You can now log in with SSH using the IP address seen in the output.

running the container on the background

To start the container in the background, run the following command:

$ docker run -d docker.hypernode.com/byteinternet/hypernode-docker:latest
36532b58822cf27f74234f6afc01db21fca15b480bf43634ae725db35047dc5a

The IP address of the container can then be found with:

$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' 36532b58822cf27f74234f6afc01db21fca15b480bf43634ae725db35047dc5a
172.17.0.3

You can view the logs with docker logs

$ docker logs 36532b58822cf27f74234f6afc01db21fca15b480bf43634ae725db35047dc5a
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/my_init.d/10_login_instructions.sh...
_
/\ /\_ _ _ __ ___ _ __ _ __ ___ __| | ___
/ /_/ / | | | '_ \ / _ \ '__| '_ \ / _ \ / _` |/ _ \
/ __ /| |_| | |_) | __/ | | | | | (_) | (_| | __/
\/ /_/ \__, | .__/ \___|_| |_| |_|\___/ \__,_|\___|
|___/|_|

Host/IP: xxxxx-dummytag-docker.nodes.hypernode.io (172.17.0.3)
Account_id: 666
Release: release-5278-28-ga9d3844 @ 2018-06-05 12:56:34 UTC

Handy commands (more at http://support.hypernode.com):

livefpm (see live PHP status)
tal | pnl (follow live requests)

hypernode-importer (import a Magento shop)
hypernode-image-optimizer (reduce image size)
hypernode-ftp (manage FTP accounts)

magerun list (many useful extensions)

------------------------------------------------------------------------------
The SSH daemon will be up in a couple of seconds, you can login with: ssh -A app@172.17.0.3
*** Running /etc/my_init.d/50_copy_key.sh...
*** Running /etc/my_init.d/50_fix_mailname.sh...
*** Running /etc/my_init.d/51_postfix.sh...
* Starting Postfix Mail Transport Agent postfix
...done.
*** Running /etc/my_init.d/60_restart_services.sh...
Killing old Hypernode services
Killing any old NGINX service
Killing any old Redis service
Killing any old PHP-FPM service
Killing any old MySQL service
Killing any old Mailhog service
Killing any old Varnish service
Giving any old services 5 seconds to stop..
No Sockets found in /var/run/screen/S-root.

Starting new detached hypernode services. See screen -x
Starting NGINX
Starting Redis
Starting PHP
Starting MySQL
Starting Mailhog
Starting Varnish
Giving the new services a couple of seconds to start..
hypernode-docker status: everything ok
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 312

Importing a Magento shop

  1. Add a hosts entry for the Docker
grep -q hypernode.hypernode.local /etc/hosts || echo "172.17.0.2 hypernode.hypernode.local" &gt;&gt; /etc/hosts
  1. Start an SSH agent and add your key
eval $(ssh-agent -s)
ssh-add # Add your keys
  1. Log in to the hypernode-docker container
# Log in with SSH agent forwarding
# The default password is 'insecure_docker_ssh_password', or use the insecure key
ssh -A root@172.17.0.2
  1. Double-check you are in the Docker environment and not the real Hypernode
# This file does not exist on real Hypernodes
app@e4b7d958e69c:~$ ls /etc/hypernode/is_docker
/etc/hypernode/is_docker

5.

Run the hypernode-importer to import a shop from a real Hypernode

hypernode-importer --host <em>yourhypernode</em>.hypernode.io --path /data/web/public --set-default-url
  1. Point your browser to the importer shop
    Go to http://hypernode.hypernode.local/

Switching PHP versions

Unlike the hypernode-vagrant you can not just run hypernode-switch-php to change the PHP version. Because there is no systemctl to manage the services other steps must be performed. To switch to a different PHP version run the following commands:

# Edit /etc/my_init.d/60_restart_services.sh to use the correct PHP
vim /etc/my_init.d/60_restart_services.sh
# Change the enabled PHP
update-alternatives --set php $(which php7.1)
# Restart (all) services
bash /etc/my_init.d/60_restart_services.sh

Adding keys to container

To create a Docker instance of hypernode-docker with your own keys, create a directory with your public key in it and a Dockerfile.

$ ls
key.pub Dockerfile
$ cat Dockerfile
FROM docker.hypernode.com/byteinternet/hypernode-docker:latest
MAINTAINER yourname &lt;example@example.nl&gt;

ADD key.pub /tmp/key.pub
RUN cat /tmp/key.pub &gt; /root/.ssh/authorized_keys &amp;&amp; cat /tmp/key.pub &gt; /data/web/.ssh/authorized_keys &amp;&amp; &amp;&amp; rm -f /tmp/deployment.pub

Then build the Docker with:

docker build -t hypernode-with-keys .

And once finished, start the Docker with:

docker run hypernode-with-keys

Note: remember that you will also need to change the default app and root user passwords if you’re looking to create a secure environment.

Inspecting emails sent from the Docker

Like in the hypernode-vagrant project, all emails are caught and redirected to a MailHog instance. You can visit the mailhog web interface on port 8025. So for example, if the IP of your container is 172.17.0.2 you would be able to access MailHog on http://172.17.0.2:8025/.

Alternatively you could set up a hosts entry like so on the host (not in the Docker):

grep -q hypernode.hypernode.local /etc/hosts || echo "172.17.0.2 hypernode.hypernode.local" &gt;&gt; /etc/hosts

And then visit the MailHog instance on http://hypernode.hypernode.local:8025.

Installing Magento 1

Make sure you have a hosts entry set up:

# Note that you need root to write to /etc/hosts
grep -q hypernode.hypernode.local /etc/hosts || echo "172.17.0.2 hypernode.hypernode.local" &gt;&gt; /etc/hosts

Switch to a Magento 1 compatible PHP version

# Log in as root
$ ssh root@172.17.0.2 -i keys/insecure_key
# Change the PHP service version to 7.0
sed -i 's/7\.1/7.0/g' /etc/my_init.d/60_restart_services.sh
# Update PHP symlinks
update-alternatives --set php $(which php7.0)
# Restart services
bash /etc/my_init.d/60_restart_services.sh
# Log out of the Docker
exit

Log in to the container as the app user:

$ ssh app@172.17.0.2 -i keys/insecure_key

Remove any Magento 2 specific NGINX configuration:

rm -rf /data/web/nginx/magento2.flag

Create a new database:

echo 'create database magento;' | mysql

Install Magento with n98-magerun:

# Write the n98-magerun config file:
cat << EOF > /data/web/.n98-magerun.yaml
commands:
  N98\Magento\Command\Installer\InstallCommand:
    installation:
      defaults:
        currency: EUR
        locale: nl_NL
        timezone: UTC
        use_secure: no
        use_rewrites: yes
        session_save: files
        admin_username: admin
        admin_firstname: Firstname
        admin_lastname: Lastname
        admin_password: thisisanexamplePassword123456
        admin_frontname: example
        admin_email: example@example.com
        encryption_key:
        installation_folder: /data/web/public

    magento-packages:
      - name: byte-mag-mirror-latest
        version: 1.9
        dist:
          url: http://magento.mirror.hypernode.com/releases/magento-latest.tar.gz
          type: tar
        extra:
          sample-data: sample-data-1.9.1.0
EOF

# Install Magento 1
php -d memory_limit=1024M  /usr/local/bin/n98-magerun install --magentoVersionByName=byte-mag-mirror-latest --dbHost=127.0.0.1 --dbUser=app --dbPass=$(cat /data/web/.my.cnf  | grep pass | awk '{print$3}') --dbName=magento --installSampleData=no --useDefaultConfigParams=yes --installationFolder=/data/web/public --baseUrl=http://hypernode.hypernode.local --replaceHtaccessFile=no --no-interaction

0