docker build -t CONTAINER_NAME .
docker run CONTAINER_NAME -p 3013:3000
docker-compose build
docker-compose up
docker-compose up -d
docker-compose start
docker-compose stop
docker-compose down
docker build -t CONTAINER_NAME .
docker run CONTAINER_NAME -p 3013:3000
docker-compose build
docker-compose up
docker-compose up -d
docker-compose start
docker-compose stop
docker-compose down
Compose is a tool for defining and running complex applications with Docker. With Compose, you define a multi-container application in a single file, then spin your application up in a single command which does everything that needs to be done to get it running.
Compose uses a YAML file to configure application's services. Then, with a single command, all the services can be started or stopped from the configuration. Some reasons you might want to use Compose :
Compose works in all environments: production, staging, development, testing as well as CI workflows.
Using Compose is basically a three-step process:
Dockerfile
so it can be reproduced anywhere.docker-compose.yml
so they can be run together in an isolated environment.docker-compose up
and Compose will start and run the entire app.A docker-compose.yml
looks like this:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Docker Compose relies on Docker Engine
. So make sure you have installed Docker Engine
before installing Docker Composer.
Instructions on installing Docker Engine
can be found in: https://gist.github.com/arsho/6249e3f0fc1d966d115c34718e1a8a0a#file-docker_installation_ubuntu_16-04-md
The following steps showed the step by step installation guideline.
Ensure that you have installed curl
before running the following command.
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
It will output like below:
docker-compose version 1.18.0, build 8dd22a9
The following steps showed the step by step guideline.
For separating the application from other projects let's first create a directory and move to that:
mkdir django_mysql
cd django_mysql
Create a Dockerfile
inside the project directory and insert the following:
FROM python:3
ENV PYTHONBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
Create a requirements.txt
file inside the project directory and insert the following:
certifi==2017.11.5
chardet==3.0.4
click==6.7
coverage==4.4.2
decorator==4.1.2
Django==2.0
django-ckeditor==5.4.0
django-constance==2.0.0
django-cors-headers==2.1.0
django-countries==5.0
django-js-asset==0.1.1
django-nose==1.4.5
django-picklefield==1.0.0
djangorestframework==3.7.6
geocoder==1.30.1
idna==2.6
mysqlclient==1.3.12
nose==1.3.7
olefile==0.44
Pillow==4.3.0
pytz==2017.3
ratelim==0.1.6
requests==2.18.4
six==1.11.0
urllib3==1.22
Markdown==2.6.11
pytz==2017.3
Create a docker-compose.yml
inside the project directory and insert the following:
version: '3'
services:
db:
image: mysql
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_USER: root
MYSQL_DATABASE: django_mysql
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
restart: always
ports:
- 8082:80
volumes:
- /sessions
In this step we are going to build docker compose:
sudo docker-compose build
The execution of the command will take some time based on internet connection speed. If you failed to build everything succesfully retry several times as network connection sometimes cause the error.
Check if the instances are running:
sudo docker-compose up
Press CTRL-C
to stop the instances for now.
To create django project inside the instance:
sudo docker-compose run web django-admin.py startproject composeexample .
In this stage we have the following directory tree:
django_mysql
├── composeexample
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── docker-compose.yml
├── Dockerfile
├── manage.py
├── requirements.txt
The files which are created by django-admin
are owned by root
. Change the ownership of the new files:
sudo chown -R $USER:$USER .
To use Django REST Framwork
to create APIs and MySQL
as database, we need to change composeexample\settings.py
to include:
ALLOWED_HOSTS = ['*']
DJANGO_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
NATIVE_APPS = [
'ridecoupon',
]
THIRD_PARTY_APPS = [
'rest_framework',
]
INSTALLED_APPS = DJANGO_APPS + NATIVE_APPS + THIRD_PARTY_APPS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_mysql',
'USER': 'root',
'PASSWORD': 'mypassword',
'HOST': 'db',
'PORT': '3306',
},
}
STATIC_URL = '/static/'
STATIC_ROOT = './static'
MEDIA_URL = '/media/'
MEDIA_ROOT = './media'
The ridecoupon
is the django app we are going to create.
We also need to update composeexample\urls.py
file to add our ridecoupon
app:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('ridecoupons/', include('ridecoupon.urls'))
]
if settings.DEBUG:
urlpatterns = urlpatterns + \
static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + \
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Run the instance in background using:
sudo docker-compose up -d
Check running processes using:
sudo docker ps
To run manage.py
we need to get logged into the container containing the django app.
For this we need to know the container ID of that container.
To get the container ID, check the running docker processes using:
sudo docker ps
This will show the container ID of all the containers. We need the container ID that has the django app.
Then, use the container ID to open a bash in that directory of manage.py
:
sudo docker exec -t -i 8f88e0935895 bash
Here 8f88e0935895
is container ID of my container. It will be different for your case.
python manage.py startapp ridecoupon
models.py
, urls.py
and other necessary files in ridecoupon
.
Then makemigrations of newly created model and migrate it:python manage.py makemigrations ridecoupon
python manage.py migrate
python manage.py createsuperuser
Username:
Email address:
Password:
python manage.py runserver
sudo docker-compose build sudo docker-compose up -d sudo docker ps CONTAINER ID IMAGE 8f88e0935895 djangomysql_web sudo docker exec -t -i 8f88e0935895 bash python manage.py makemigrations ridecoupon python manage.py migrate python manage.py createsuperuser
Open http://0.0.0.0:8000/ and see the running web application
Open http://0.0.0.0:8082/ and see the running PHPMyAdmin
.
Use
User: root
Password: mypassword
and keep the host empty.
Folder structure:
.
├── backend.py
├── Dockerfile
├── readme.md
└── requirements.txt
requirements.txt
:
Flask==1.0.2
Flask-Cors==3.0.7
Dockerfile
:
FROM python:3
ENV PYTHONBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
CMD ["python", "backend.py" ]
Build Docker file:
docker build -t flask-docker .
Run Docker:
docker run -p 5000:5000 flask-docker
* Serving Flask app "backend" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Get Docker container ID:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69cb7d5d243a flask-docker "python backend.py" 15 minutes ago Up 15 minutes 0.0.0.0:5000->5000/tcp
Get Docker container IP address:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' 69cb7d5d243a
172.17.0.2
Use this IP address in AJAX request in HTML file:
<html>
<head>
<title>Frontend</title>
</head>
<body>
<div id="data"></div>
<button type="button" id="btn">Grab data</button>
<script type="text/javascript">
document.getElementById("btn").addEventListener('click', add);
function add()
{
const api_url = "http://172.17.0.2:5000/test";
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("data").append(this.responseText);
}
};
xhttp.open("GET", api_url, true);
xhttp.send();
}
</script>
</body>
</html>
backend.py
:
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/test")
def test():
return "It's working"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
Output:
Docker is a tool for running application in an isolated environment.
Some reasons you might want to use Docker:
Container is a running instance of an image. An image is a template for creating the environment you want to snapshot out of a system at a particular time. An image includes:
Images are defined by a Dockerfile. Dockerfile is a text file with the steps to perform to create that image. It includes the following ordered instructions
Building the Dockerfile will create the image which is run in the container.
The following steps showed the step by step installation guideline. This instructions shows the way of installing Docker using the Docker repository.
apt
package index:sudo apt-get update
apt
to use a repository over HTTPS:sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Verify that you have the key with the fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
by searching for the last 8 characters of the fingerprint
sudo apt-key fingerprint 0EBFCD88
It should some information about the key file:
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <[email protected]>
sub 4096R/F273FCD8 2017-02-22
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt
package index:sudo apt-get update
sudo apt-get install docker-ce
hello-world
image:sudo docker run hello-world
It downloads a atest image and runs it in a container. When the container runs, it prints informational messages and exits.
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:66ef312bbac49c39a89aa9bcc3cb4f3c9e7de3788c944158df3ee0176d32b751
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
This section contains optional procedures for configuring Linux hosts to work better with Docker.
The docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can only access it using sudo
. The docker daemon always runs as the root user.
If you don’t want to use sudo when you use the docker command, create a Unix group called docker and add users to it. When the docker daemon starts, it makes the ownership of the Unix socket read/writable by the docker group.
Warning: The docker group grants privileges equivalent to the root user. Create the docker group:
sudo groupadd docker
Add your user to the docker group:
sudo usermod -aG docker $USER
Log out and log back in so that your group membership is re-evaluated.
Verify that you can run docker commands without sudo
.
docker run hello-world
This command downloads a test image and runs it in a container. When the container runs, it prints an informational message and exits.
Remove previous container using that name, with the command
docker rm $(docker ps -aq --filter name=CONTAINER_NAME)
To run PHP application ensure that you already installed Docker in your machine. To learn more about installation: follow this gist
The following steps showed the step by step docker setup guideline for PHP application.
mkdir test_docker_php
cd test_docker_php
test_docker_php
directory create a file name Dockerfile
and a src
folder to keep the source code.
To make this tutorial simple let's keep only a file called index.php
inside the src
directory.
The directory structure will look like this:test_docker_php
├── Dockerfile
└── src
└── index.php
Dockerfile
will download the official PHP image, copy the source code to a specific folder and expose port 80 of the container:
FROM php:7.0-apache
COPY src/ /var/www/html
EXPOSE 80
index.php
may contain some echo command like:
<?php
echo "If you can see this message it ensures that Docker container is running successfully";
?>
In this step we are going to build an image from the above Dockerfile
and give it a name, let's say test_docker_php
:
sudo docker build -t test_docker_php .
The last .
tells that Dockerfile
is in the current directory.
The execution of the command will take some time based on internet connection speed.
Let's run this Docker image by providing the port number and path of src
directory (absolute path) to reflect dynamic changes in source.
To get the present working directory's absolute path:
pwd
For my case it is: /home/..../test_docker_php/
[hide the unnecessary part from here with ....]
Now we can run the image test_docker_php
with this absolute path of src
folder:
sudo docker run -p 80:80 -v /home/..../test_docker_php/src:/var/www/html test_docker_php
After running the image the executed application can be seen at localhost
in web browser.
If you modify the content of index.php
just reload the page in the browser and it will be updated instantly.
To run static web application application ensure that you already installed Docker in your machine. To learn more about installation: follow this gist
The following steps showed the step by step docker setup guideline for PHP application.
mkdir test_docker_static
cd test_docker_static
test_docker_static
directory create a file name Dockerfile
and a src
folder to keep the source code.
To make this tutorial simple let's keep only a file called index.html
inside the src
directory.
The directory structure will look like this:test_docker_static
├── Dockerfile
└── src
└── index.html
Dockerfile
will download the official nginx image, copy the source code to a specific folder and expose port 80 of the container:
FROM nginx:stable
COPY src/ /usr/share/nginx/html
EXPOSE 80
index.html
may contain some echo command like:
<html>
<head>
<title>Docker static site</title>
</head>
<body>
<h3>Hello from static site (updated again)</h3>
</body>
</html>
In this step we are going to build an image from the above Dockerfile
and give it a name, let's say test_docker_static
:
sudo docker build -t test_docker_static .
The last .
tells that Dockerfile
is in the current directory.
The execution of the command will take some time based on internet connection speed.
Let's run this Docker image by providing the port number and path of src
directory (absolute path) to reflect dynamic changes in source.
To get the present working directory's absolute path:
pwd
For my case it is: /home/..../test_docker_static/
[hide the unnecessary part from here with ....]
Now we can run the image test_docker_static
with this absolute path of src
folder:
sudo docker run -p 80:80 -v /home/..../test_docker_static/src:/usr/share/nginx/html test_docker_static
After running the image the executed application can be seen at localhost
in web browser.
If you modify the content of index.html
just reload the page in the browser and it will be updated instantly.
Thanks for this wonderful tutorial. When I tried to execute the
python manage.py startapp ridecoupon
in the django bash, it has errors:Am I supposed to add this to
docker-compose.yml
?The traceback is as follows:
Thanks again.