Make sure you have already installed vagrant and virtual-box
mohammedrafi@NOC-RAFI:~$ mkdir practise && cd practise
mohammedrafi@NOC-RAFI:~/practise$
mohammedrafi@NOC-RAFI:~/practise$ vim Vagrantfile
VAGRANTFILE_API_VERSION = “2”
$bootstrap=<<SCRIPT
apt-get update
apt-get -y install wget
wget -qO- https://get.docker.com/ | sh
gpasswd -a vagrant docker
service docker restart
SCRIPT
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = “ubuntu/trusty64”
config.vm.network “private_network”, ip: “192.168.33.10”
config.vm.provider “virtualbox” do |vb|
vb.customize [“modifyvm”, :id, “–memory”, “1024”]
end
config.vm.provision :shell, inline: $bootstrap
end
mohammedrafi@NOC-RAFI:~/practise$ vagrant up
Bringing machine ‘default’ up with ‘virtualbox’ provider…
==> default: Importing base box ‘ubuntu/trusty64’…
==> default: Matching MAC address for NAT networking…
==> default: Checking if box ‘ubuntu/trusty64’ is up to date…
==> default: A newer version of the box ‘ubuntu/trusty64’ is available! You currently
==> default: have version ‘20170424.0.0’. The latest is version ‘20170811.0.1’. Run
==> default: `vagrant box update` to update.
==> default: Setting the name of the VM: practise_default_1503821207852_39192
==> default: Clearing any previously set forwarded ports…
==> default: Clearing any previously set network interfaces…
==> default: Preparing network interfaces based on configuration…
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports…
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running ‘pre-boot’ VM customizations…
==> default: Booting VM…
==> default: Waiting for machine to boot. This may take a few minutes…
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest…
default: Removing insecure key from the guest if it’s present…
default: Key inserted! Disconnecting and reconnecting using new SSH key…
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM…
==> default: Configuring and enabling network interfaces…
==> default: Mounting shared folders…
default: /vagrant => /home/mohammedrafi/practise
==> default: Running provisioner: shell…
default: Running: inline script
mohammedrafi@NOC-RAFI:~/practise$ vagrant ssh
vagrant@vagrant-ubuntu-trusty-64:~$ cat /etc/os-release
NAME=”Ubuntu”
VERSION=”14.04.5 LTS, Trusty Tahr”
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME=”Ubuntu 14.04.5 LTS”
VERSION_ID=”14.04″
HOME_URL=”http://www.ubuntu.com/”
SUPPORT_URL=”http://help.ubuntu.com/”
BUG_REPORT_URL=”http://bugs.launchpad.net/ubuntu/”
vagrant@vagrant-ubuntu-trusty-64:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:73:9e:83 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe73:9e83/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:c0:2b:e4 brd ff:ff:ff:ff:ff:ff
inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fec0:2be4/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:78:d4:c7:e3 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
vagrant@vagrant-ubuntu-trusty-64:~$ service docker status
docker start/running, process 5715
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -t -i ubuntu:14.04 /bin/bash
Unable to find image ‘ubuntu:14.04’ locally
14.04: Pulling from library/ubuntu
48f0413f904d: Pull complete
2bd2b2e92c5f: Pull complete
06ed1e3efabb: Pull complete
a220dbf88993: Pull complete
57c164185602: Pull complete
Digest: sha256:6a3e01207b899a347115f3859cf8a6031fdbebb6ffedea6c2097be40a298c85d
Status: Downloaded newer image for ubuntu:14.04
root@d576280af11a:/#
You see that Docker pulled the Ubuntu:14.04 image composed of several layers, and you got a session as root within a container. The prompt gives you the ID of the container.
vagrant@vagrant-ubuntu-trusty-64:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
vagrant@vagrant-ubuntu-trusty-64:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d576280af11a ubuntu:14.04 “/bin/bash” About a minute ago Exited (0) 6 seconds ago compassionate_galileo
Running a Docker Container in Detached Mode
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -d -p 1234:1234 python:2.7 python -m SimpleHTTPServer 1234
Unable to find image ‘python:2.7’ locally
2.7: Pulling from library/python
ad74af05f5a2: Pull complete
2b032b8bbe8b: Pull complete
a9a5b35f6ead: Pull complete
3245b5a1c52c: Pull complete
032924b710ba: Pull complete
fd37168d02bb: Pull complete
8804355f8371: Pull complete
a19b278d4ccd: Pull complete
Digest: sha256:2cba1410697972e0148cbc547ac39e89ff85240f0d4d07db58091bc46e0ed0f2
Status: Downloaded newer image for python:2.7
1acc1263f6b53f25258fe3f0f1849b393719709557847d04fb8547c817f7416b
vagrant@vagrant-ubuntu-trusty-64:~$
vagrant@vagrant-ubuntu-trusty-64:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1acc1263f6b5 python:2.7 “python -m SimpleH…” 4 minutes ago Up 4 minutes 0.0.0.0:1234->1234/tcp infallible_brattain
Use the create , start , stop , kill , and rm commands of the Docker CLI.
Docker Image with a Dockerfile
A Dockerfile is a text file that describes the steps that Docker needs to take to prepare an image—including installing packages, creating directories, and defining environment variables, among other things.
Create the following text file named Dockerfile in an empty working directory:
vagrant@vagrant-ubuntu-trusty-64:~$ vim Dockerfile
FROM busybox
ENV foo=bar
Then to build a new image called busybox2, you use the docker build command like so:
docker build -t busybox2 .
vagrant@vagrant-ubuntu-trusty-64:~$ docker build -t busybox2 .
Sending build context to Docker daemon 13.31kB
Step 1/2 : FROM busybox
latest: Pulling from library/busybox
add3ddb21ede: Pull complete
Digest: sha256:b82b5740006c1ab823596d2c07f081084ecdb32fd258072707b99f52a3cb8692
Status: Downloaded newer image for busybox:latest
—> d20ae45477cb
Step 2/2 : ENV foo bar
—> Running in 9586e12112e9
—> 62b708e0e76d
Removing intermediate container 9586e12112e9
Successfully built 62b708e0e76d
Successfully tagged busybox2:latest
vagrant@vagrant-ubuntu-trusty-64:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox2 latest 62b708e0e76d 8 minutes ago 1.13MB
busybox latest d20ae45477cb 3 days ago 1.13MB
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -it busybox2
/ # env |grep foo
foo=bar
vagrant@vagrant-ubuntu-trusty-64:~$ docker run busybox2 env |grep foo
foo=bar
Run WordPress in a Single Container
Use Supervisor to monitor and run both MySQL and HTTPD. Supervisor is not an init system, but is meant to control multiple processes and is run like any other program.
To run WordPress, you will need to install MySQL, Apache 2 (i.e., httpd ), and PHP, and grab the latest WordPress release. You will need to create a database for WordPress.
vagrant@vagrant-ubuntu-trusty-64:~$ vim Dockerfile
FROM ubuntu:14.04
RUN apt-get update && apt-get -y install apache2 php5 php5-mysql supervisor wget
RUN echo ‘mysql-server mysql-server/root_password password root’ | debconf-set-selections && echo ‘mysql-server mysql-server/root_password_again password root’ | debconf-set-selections
RUN apt-get install -qqy mysql-server
RUN wget http://wordpress.org/latest.tar.gz && tar xzvf latest.tar.gz && cp -R ./wordpress/* /var/www/html && rm /var/www/html/index.html
RUN (/usr/bin/mysqld_safe &); sleep 5; mysqladmin -u root -proot create wordpress
COPY wp-config.php /var/www/html/wp-config.php
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
EXPOSE 80
CMD [“/usr/bin/supervisord”]
vagrant@vagrant-ubuntu-trusty-64:~$ vim supervisord.conf
[supervisord]
nodaemon=true
[program:mysqld]
command=/usr/bin/mysqld_safe
autostart=true
autorestart=true
user=root
[program:httpd]
command=/bin/bash -c “rm -rf /run/httpd/* && /usr/sbin/apachectl -D FOREGROUND”
vagrant@vagrant-ubuntu-trusty-64:~$ vim wp-config.php
/**
* The base configurations of the WordPress.
*
* This file has the following configurations: MySQL settings, Table Prefix,
* Secret Keys, and ABSPATH. You can find more information by visiting
* {@link http://codex.wordpress.org/Editing_wp-config.php Editing wp-config.php}
* Codex page. You can get the MySQL settings from your web host.
*
* This file is used by the wp-config.php creation script during the
* installation. You don’t have to use the web site, you can just copy this file
* to “wp-config.php” and fill in the values.
*
* @package WordPress
*/
// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define(‘DB_NAME’, ‘wordpress’);
/** MySQL database username */
define(‘DB_USER’, ‘root’);
/** MySQL database password */
define(‘DB_PASSWORD’, ‘root’);
/** MySQL hostname */
define(‘DB_HOST’, ‘localhost’);
/** Database Charset to use in creating database tables. */
define(‘DB_CHARSET’, ‘utf8’);
/** The Database Collate type. Don’t change this if in doubt. */
define(‘DB_COLLATE’, ”);
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define(‘AUTH_KEY’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_KEY’, ‘put your unique phrase here’);
define(‘LOGGED_IN_KEY’, ‘put your unique phrase here’);
define(‘NONCE_KEY’, ‘put your unique phrase here’);
define(‘AUTH_SALT’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_SALT’, ‘put your unique phrase here’);
define(‘LOGGED_IN_SALT’, ‘put your unique phrase here’);
define(‘NONCE_SALT’, ‘put your unique phrase here’);
/**#@-*/
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each a unique
* prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = ‘wp_’;
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*/
define(‘WP_DEBUG’, false);
/* That’s all, stop editing! Happy blogging. */
/** Absolute path to the WordPress directory. */
if ( !defined(‘ABSPATH’) )
define(‘ABSPATH’, dirname(__FILE__) . ‘/’);
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . ‘wp-settings.php’);
vagrant@vagrant-ubuntu-trusty-64:~$ docker build -t wordpress .
c69811d4e993
Step 2/10 : RUN apt-get update && apt-get -y install apache2 php5 php5-mysql supervisor wget
—> Using cache
—> e60dd8009735
Step 3/10 : RUN echo ‘mysql-server mysql-server/root_password password root’ | debconf-set-selections && echo ‘mysql-server mysql-server/root_password_again password root’ | debconf-set-selections
—> Using cache
—> 7fdf6f470aa2
Step 4/10 : RUN apt-get install -qqy mysql-server
—> Using cache
—> 66a3a4462138
Step 5/10 : RUN wget http://wordpress.org/latest.tar.gz && tar xzvf latest.tar.gz && cp -R ./wordpress/* /var/www/html && rm /var/www/html/index.html
—> Using cache
—> 37772ea1e4b4
Step 6/10 : RUN (/usr/bin/mysqld_safe &); sleep 5; mysqladmin -u root -proot create wordpress
—> Using cache
—> 04cf1e84fd24
Step 7/10 : COPY wp-config.php /var/www/html/wp-config.php
—> 714039437acb
Removing intermediate container 55c236462fc8
Step 8/10 : COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
—> 3cc59b6f5fa1
Removing intermediate container bd300e4f8cec
Step 9/10 : EXPOSE 80
—> Running in 05fb5fb0f058
—> 37ab444b93b3
Removing intermediate container 05fb5fb0f058
Step 10/10 : CMD /usr/bin/supervisord
—> Running in 7733ace6279b
—> 576eb043a6f8
Removing intermediate container 7733ace6279b
Successfully built 576eb043a6f8
Successfully tagged wordpress:latest
vagrant@vagrant-ubuntu-trusty-64:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress latest 576eb043a6f8 41 seconds ago 466MB
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -d -p 80:80 wordpress
37130c1afeed71132444f23b3b3923732ca032934c4e650d472acb66ede3263a
https://github.com/how2dock/docbook/tree/master/ch01/supervisor
Backing Up a Database Running in a Container
vagrant@vagrant-ubuntu-trusty-64:~$ docker run –name mysqlwp -e MYSQL_ROOT_PASSWORD=wordpressdocker -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpresspwd -v /home/docker/mysql:/var/lib/mysql -d mysql
da575a84ea6a187bd989409f4db3e45b4cb9268b249c121eb306a9e95075264b
vagrant@vagrant-ubuntu-trusty-64:~$ ls
Dockerfile supervisord.conf wp-config.php
vagrant@vagrant-ubuntu-trusty-64:~$ docker exec mysqlwp mysqldump –all-databases –password=wordpressdocker > wordpress.backup
mysqldump: [Warning] Using a password on the command line interface can be insecure.
vagrant@vagrant-ubuntu-trusty-64:~$ ls
Dockerfile supervisord.conf wordpress.backup wp-config.php
Copying Data to and from Containers
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -d –name testcopy ubuntu:14.04 sleep 360
25acb54acf7154702c8999c965ba612d5f63b3b16aa3c97f0d195e80d0ea1d3b
vagrant@vagrant-ubuntu-trusty-64:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25acb54acf71 ubuntu:14.04 “sleep 360” About a minute ago Up About a minute testcopy
vagrant@vagrant-ubuntu-trusty-64:~$ docker exec -ti testcopy /bin/bash
root@25acb54acf71:/# cd /root/
root@25acb54acf71:~# echo ‘I am in the container‘ > file.txt
root@25acb54acf71:~# exit
exit
vagrant@vagrant-ubuntu-trusty-64:~$ docker cp testcopy:/root/file.txt .
vagrant@vagrant-ubuntu-trusty-64:~$ cat file.txt
I am in the container
Keeping Changes Made to a Container by Committing to an Image
vagrant@vagrant-ubuntu-trusty-64:~$ docker commit 25acb54acf71 ubuntu:update
vagrant@vagrant-ubuntu-trusty-64:~$ docker diff 25acb54acf71
C /root
A /root/.bash_history
A /root/file.txt
Saving Images and Containers as Tar Files for Sharing
vagrant@vagrant-ubuntu-trusty-64:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25acb54acf71 ubuntu:14.04 “sleep 360” 2 hours ago Exited (0) 2 hours ago testcopy
vagrant@vagrant-ubuntu-trusty-64:~$ docker export 25acb54acf71 > update.tar
vagrant@vagrant-ubuntu-trusty-64:~$ ls -lh update.tar
-rw-rw-r– 1 vagrant vagrant 176M Aug 28 12:06 update.tar
Writing Your First Dockerfile
The FROM instruction tells you which image to base the new image off of. Here you choose the ubuntu:14.04 image from the Official Ubuntu repository in Docker Hub.
The ENTRYPOINT instruction tells you which command to run when a container based on this image is started. To build the image, issue a docker build . at the prompt
vagrant@vagrant-ubuntu-trusty-64:~$ vim Dockerfile
FROM ubuntu:14.04
ENTRYPOINT [“/bin/echo”]
vagrant@vagrant-ubuntu-trusty-64:~$ docker build .
Sending build context to Docker daemon 250.7MB
Step 1/2 : FROM ubuntu:14.04
—> c69811d4e993
Step 2/2 : ENTRYPOINT /bin/echo
—> Running in 6493e28293cf
—> d4d1bcf8983b
Removing intermediate container 6493e28293cf
Successfully built d4d1bcf8983b
vagrant@vagrant-ubuntu-trusty-64:~$ docker run d4d1bcf8983b Hi Docker !
Hi Docker !
vagrant@vagrant-ubuntu-trusty-64:~$ docker run d4d1bcf8983b
vagrant@vagrant-ubuntu-trusty-64:~$
vagrant@vagrant-ubuntu-trusty-64:~$ vim Dockerfile
FROM ubuntu:14.04
CMD [“/bin/echo”, “Hello added content while building image itself !”]
vagrant@vagrant-ubuntu-trusty-64:~$ docker build .
Sending build context to Docker daemon 250.7MB
Step 1/2 : FROM ubuntu:14.04
—> c69811d4e993
Step 2/2 : CMD /bin/echo Hello added content while building image itself !
—> Running in 5882ba26a61a
—> 2a54fadd69bd
Removing intermediate container 5882ba26a61a
Successfully built 2a54fadd69bd
vagrant@vagrant-ubuntu-trusty-64:~$ docker run 2a54fadd69bd
Hello added content while building image itself !
vagrant@vagrant-ubuntu-trusty-64:~$ docker build -t cookbook:hello .
Sending build context to Docker daemon 250.7MB
Step 1/2 : FROM ubuntu:14.04
—> c69811d4e993
Step 2/2 : CMD /bin/echo Hello added content while building image itself !
—> Using cache
—> 2a54fadd69bd
Successfully built 2a54fadd69bd
Successfully tagged cookbook:hello
vagrant@vagrant-ubuntu-trusty-64:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
cookbook hello 2a54fadd69bd About a minute ago 188MB
You could also use the CMD instruction in a Dockerfile. This has the advantage that you can overwrite the CMD behavior when you launch a container, by passing a new CMD as an argument to docker run .
Remember that CMD can be overwritten by an argument to docker run , while ENTRY POINT can be overwritten only by using the –entrypoint option of docker run .
Packaging a Flask Application Inside a Container
vagrant@vagrant-ubuntu-trusty-64:~$ vim hello.py
#!/usr/bin/env python
from flask import Flask
app = Flask(__name__)
@app.route(‘/hi’)
def hello_world():
return ‘Hello World!’
if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=5000)
vagrant@vagrant-ubuntu-trusty-64:~$ vim Dockerfile
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y python
RUN apt-get install -y python-pip
RUN apt-get clean all
RUN pip install flask
ADD hello.py /tmp/hello.py
EXPOSE 5000
CMD [“python”,”/tmp/hello.py”]
vagrant@vagrant-ubuntu-trusty-64:~$ docker build -t flask .
Sending build context to Docker daemon 250.7MB
Step 1/9 : FROM ubuntu:14.04
—> c69811d4e993
Step 2/9 : RUN apt-get update
—> Using cache
—> fa3d4260c858
Step 3/9 : RUN apt-get install -y python
—> Using cache
—> 66cf6b785aeb
Step 4/9 : RUN apt-get install -y python-pip
—> Using cache
—> 05f778da6ea4
Step 5/9 : RUN apt-get clean all
—> Using cache
—> 8b030994d0b9
Step 6/9 : RUN pip install flask
—> Using cache
—> 19df885ecbc6
Step 7/9 : ADD hello.py /tmp/hello.py
—> Using cache
—> ea1a4989b57f
Step 8/9 : EXPOSE 5000
—> Using cache
—> 01ef8bd8ef06
Step 9/9 : CMD python /tmp/hello.py
—> Using cache
—> 7b14cc15e557
Successfully built 7b14cc15e557
Successfully tagged flask:latest
vagrant@vagrant-ubuntu-trusty-64:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
flask latest 7b14cc15e557 About a minute ago 363MB
vagrant@vagrant-ubuntu-trusty-64:~$ docker run -t -i -P flask /bin/bash
root@69e2a2a1811b:/# ls -l /tmp/hello.py
-rw-rw-r– 1 root root 189 Aug 28 13:18 /tmp/hello.py
root@69e2a2a1811b:/# cat /tmp/hello.py
#!/usr/bin/env python
from flask import Flask
app = Flask(__name__)
@app.route(‘/hi’)
def hello_world():
return ‘Hello World!’
if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=5000)
