remove examples for ENV key value without '='

The `ENV key value` form can be ambiguous, for example, the following defines
a single env-variable (`ONE`) with value `"TWO= THREE=world"`:

    ENV ONE TWO= THREE=world

While we cannot deprecate/remove that syntax (as it would break existing
Dockerfiles), we should reduce exposure of the format in our examples.

Also updating some code-blocks that were missing language-hints

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2020-09-23 13:41:51 +02:00
parent 463d98bd41
commit f6adc80d9a
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
6 changed files with 313 additions and 276 deletions

View File

@ -25,13 +25,15 @@ and a `docker-compose.yml` file. (You can use either a `.yml` or `.yaml` extensi
3. Add the following content to the `Dockerfile`. 3. Add the following content to the `Dockerfile`.
```dockerfile
FROM python:3 FROM python:3
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED=1
RUN mkdir /code RUN mkdir /code
WORKDIR /code WORKDIR /code
COPY requirements.txt /code/ COPY requirements.txt /code/
RUN pip install -r requirements.txt RUN pip install -r requirements.txt
COPY . /code/ COPY . /code/
```
This `Dockerfile` starts with a [Python 3 parent image](https://hub.docker.com/r/library/python/tags/3/). This `Dockerfile` starts with a [Python 3 parent image](https://hub.docker.com/r/library/python/tags/3/).
The parent image is modified by adding a new `code` directory. The parent image is further modified The parent image is modified by adding a new `code` directory. The parent image is further modified
@ -62,8 +64,8 @@ and a `docker-compose.yml` file. (You can use either a `.yml` or `.yaml` extensi
9. Add the following configuration to the file. 9. Add the following configuration to the file.
```none ```yaml
version: '3' version: "{{ site.compose_file_v3 }}"
services: services:
db: db:
@ -102,7 +104,9 @@ In this step, you create a Django starter project by building the image from the
2. Create the Django project by running 2. Create the Django project by running
the [docker-compose run](reference/run.md) command as follows. the [docker-compose run](reference/run.md) command as follows.
sudo docker-compose run web django-admin startproject composeexample . ```console
$ sudo docker-compose run web django-admin startproject composeexample .
```
This instructs Compose to run `django-admin startproject composeexample` This instructs Compose to run `django-admin startproject composeexample`
in a container, using the `web` service's image and configuration. Because in a container, using the `web` service's image and configuration. Because
@ -116,30 +120,38 @@ the [docker-compose run](reference/run.md) command as follows.
3. After the `docker-compose` command completes, list the contents of your project. 3. After the `docker-compose` command completes, list the contents of your project.
```console
$ ls -l $ ls -l
drwxr-xr-x 2 root root composeexample drwxr-xr-x 2 root root composeexample
-rw-rw-r-- 1 user user docker-compose.yml -rw-rw-r-- 1 user user docker-compose.yml
-rw-rw-r-- 1 user user Dockerfile -rw-rw-r-- 1 user user Dockerfile
-rwxr-xr-x 1 root root manage.py -rwxr-xr-x 1 root root manage.py
-rw-rw-r-- 1 user user requirements.txt -rw-rw-r-- 1 user user requirements.txt
```
If you are running Docker on Linux, the files `django-admin` created are If you are running Docker on Linux, the files `django-admin` created are
owned by root. This happens because the container runs as the root user. owned by root. This happens because the container runs as the root user.
Change the ownership of the new files. Change the ownership of the new files.
sudo chown -R $USER:$USER . ```console
$ sudo chown -R $USER:$USER .
```
If you are running Docker on Mac or Windows, you should already If you are running Docker on Mac or Windows, you should already
have ownership of all files, including those generated by have ownership of all files, including those generated by
`django-admin`. List the files just to verify this. `django-admin`. List the files just to verify this.
```console
$ ls -l $ ls -l
total 32 total 32
-rw-r--r-- 1 user staff 145 Feb 13 23:00 Dockerfile -rw-r--r-- 1 user staff 145 Feb 13 23:00 Dockerfile
drwxr-xr-x 6 user staff 204 Feb 13 23:07 composeexample drwxr-xr-x 6 user staff 204 Feb 13 23:07 composeexample
-rw-r--r-- 1 user staff 159 Feb 13 23:02 docker-compose.yml -rw-r--r-- 1 user staff 159 Feb 13 23:02 docker-compose.yml
-rwxr-xr-x 1 user staff 257 Feb 13 23:07 manage.py -rwxr-xr-x 1 user staff 257 Feb 13 23:07 manage.py
-rw-r--r-- 1 user staff 16 Feb 13 23:01 requirements.txt -rw-r--r-- 1 user staff 16 Feb 13 23:01 requirements.txt
```
### Connect the database ### Connect the database
@ -150,6 +162,7 @@ In this section, you set up the database connection for Django.
2. Replace the `DATABASES = ...` with the following: 2. Replace the `DATABASES = ...` with the following:
```python
# settings.py # settings.py
DATABASES = { DATABASES = {
@ -162,6 +175,7 @@ In this section, you set up the database connection for Django.
'PORT': 5432, 'PORT': 5432,
} }
} }
```
These settings are determined by the These settings are determined by the
[postgres](https://hub.docker.com/_/postgres) Docker image [postgres](https://hub.docker.com/_/postgres) Docker image
@ -171,8 +185,9 @@ In this section, you set up the database connection for Django.
4. Run the [docker-compose up](reference/up.md) command from the top level directory for your project. 4. Run the [docker-compose up](reference/up.md) command from the top level directory for your project.
```none ```console
$ docker-compose up $ docker-compose up
djangosample_db_1 is up-to-date djangosample_db_1 is up-to-date
Creating djangosample_web_1 ... Creating djangosample_web_1 ...
Creating djangosample_web_1 ... done Creating djangosample_web_1 ... done
@ -203,25 +218,25 @@ In this section, you set up the database connection for Django.
> Note: > Note:
> >
> On certain platforms (Windows 10), you might need to > On certain platforms (Windows 10), you might need to edit `ALLOWED_HOSTS`
edit `ALLOWED_HOSTS` inside `settings.py` and add your Docker host name > inside `settings.py` and add your Docker host name or IP address to the list.
or IP address to the list. For demo purposes, you can set the value to: > For demo purposes, you can set the value to:
> >
> ALLOWED_HOSTS = ['*'] > ALLOWED_HOSTS = ['*']
> >
> This value is **not** safe for production usage. Refer to the > This value is **not** safe for production usage. Refer to the
[Django documentation](https://docs.djangoproject.com/en/1.11/ref/settings/#allowed-hosts) for more information. > [Django documentation](https://docs.djangoproject.com/en/1.11/ref/settings/#allowed-hosts) for more information.
5. List running containers. 5. List running containers.
In another terminal window, list the running Docker processes with the `docker container ls` command. In another terminal window, list the running Docker processes with the `docker container ls` command.
```none ```console
$ docker ps $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
def85eff5f51 django_web "python3 manage.py..." 10 minutes ago Up 9 minutes 0.0.0.0:8000->8000/tcp django_web_1
678ce61c79cc postgres "docker-entrypoint..." 20 minutes ago Up 9 minutes 5432/tcp django_db_1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
def85eff5f51 django_web "python3 manage.py..." 10 minutes ago Up 9 minutes 0.0.0.0:8000->8000/tcp django_web_1
678ce61c79cc postgres "docker-entrypoint..." 20 minutes ago Up 9 minutes 5432/tcp django_db_1
``` ```
6. Shut down services and clean up by using either of these methods: 6. Shut down services and clean up by using either of these methods:
@ -229,7 +244,7 @@ def85eff5f51 django_web "python3 manage.py..." 10 minutes ago
* Stop the application by typing `Ctrl-C` * Stop the application by typing `Ctrl-C`
in the same shell in where you started it: in the same shell in where you started it:
```none ```console
Gracefully stopping... (press Ctrl+C again to force) Gracefully stopping... (press Ctrl+C again to force)
Killing test_web_1 ... done Killing test_web_1 ... done
Killing test_db_1 ... done Killing test_db_1 ... done
@ -237,9 +252,10 @@ def85eff5f51 django_web "python3 manage.py..." 10 minutes ago
* Or, for a more elegant shutdown, switch to a different shell, and run [docker-compose down](reference/down.md) from the top level of your Django sample project directory. * Or, for a more elegant shutdown, switch to a different shell, and run [docker-compose down](reference/down.md) from the top level of your Django sample project directory.
```none ```console
vmb at mymachine in ~/sandbox/django vmb at mymachine in ~/sandbox/django
$ docker-compose down $ docker-compose down
Stopping django_web_1 ... done Stopping django_web_1 ... done
Stopping django_db_1 ... done Stopping django_db_1 ... done
Removing django_web_1 ... done Removing django_web_1 ... done

View File

@ -21,11 +21,14 @@ Define the application dependencies.
1. Create a directory for the project: 1. Create a directory for the project:
```console
$ mkdir composetest $ mkdir composetest
$ cd composetest $ cd composetest
```
2. Create a file called `app.py` in your project directory and paste this in: 2. Create a file called `app.py` in your project directory and paste this in:
```python
import time import time
import redis import redis
@ -34,7 +37,6 @@ Define the application dependencies.
app = Flask(__name__) app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379) cache = redis.Redis(host='redis', port=6379)
def get_hit_count(): def get_hit_count():
retries = 5 retries = 5
while True: while True:
@ -46,12 +48,11 @@ Define the application dependencies.
retries -= 1 retries -= 1
time.sleep(0.5) time.sleep(0.5)
@app.route('/') @app.route('/')
def hello(): def hello():
count = get_hit_count() count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count) return 'Hello World! I have been seen {} times.\n'.format(count)
```
In this example, `redis` is the hostname of the redis container on the In this example, `redis` is the hostname of the redis container on the
application's network. We use the default port for Redis, `6379`. application's network. We use the default port for Redis, `6379`.
@ -66,12 +67,13 @@ Define the application dependencies.
> cluster, this also helps handling momentary connection drops between > cluster, this also helps handling momentary connection drops between
> nodes. > nodes.
3. Create another file called `requirements.txt` in your project directory and 3. Create another file called `requirements.txt` in your project directory and
paste this in: paste this in:
```text
flask flask
redis redis
```
## Step 2: Create a Dockerfile ## Step 2: Create a Dockerfile
@ -82,16 +84,18 @@ itself.
In your project directory, create a file named `Dockerfile` and paste the In your project directory, create a file named `Dockerfile` and paste the
following: following:
FROM python:3.7-alpine ```dockerfile
WORKDIR /code FROM python:3.7-alpine
ENV FLASK_APP app.py WORKDIR /code
ENV FLASK_RUN_HOST 0.0.0.0 ENV FLASK_APP=app.py
RUN apk add --no-cache gcc musl-dev linux-headers ENV FLASK_RUN_HOST=0.0.0.0
COPY requirements.txt requirements.txt RUN apk add --no-cache gcc musl-dev linux-headers
RUN pip install -r requirements.txt COPY requirements.txt requirements.txt
EXPOSE 5000 RUN pip install -r requirements.txt
COPY . . EXPOSE 5000
CMD ["flask", "run"] COPY . .
CMD ["flask", "run"]
```
This tells Docker to: This tells Docker to:
@ -114,14 +118,16 @@ and the [Dockerfile reference](/engine/reference/builder/).
Create a file called `docker-compose.yml` in your project directory and paste Create a file called `docker-compose.yml` in your project directory and paste
the following: the following:
version: '3' ```yaml
services: version: "{{ site.compose_file_v3 }}"
services:
web: web:
build: . build: .
ports: ports:
- "5000:5000" - "5000:5000"
redis: redis:
image: "redis:alpine" image: "redis:alpine"
```
This Compose file defines two services: `web` and `redis`. This Compose file defines two services: `web` and `redis`.
@ -140,8 +146,9 @@ image pulled from the Docker Hub registry.
1. From your project directory, start up your application by running `docker-compose up`. 1. From your project directory, start up your application by running `docker-compose up`.
``` ```console
$ docker-compose up $ docker-compose up
Creating network "composetest_default" with the default driver Creating network "composetest_default" with the default driver
Creating composetest_web_1 ... Creating composetest_web_1 ...
Creating composetest_redis_1 ... Creating composetest_redis_1 ...
@ -179,7 +186,7 @@ image pulled from the Docker Hub registry.
You should see a message in your browser saying: You should see a message in your browser saying:
``` ```console
Hello World! I have been seen 1 times. Hello World! I have been seen 1 times.
``` ```
@ -189,19 +196,19 @@ image pulled from the Docker Hub registry.
The number should increment. The number should increment.
``` ```console
Hello World! I have been seen 2 times. Hello World! I have been seen 2 times.
``` ```
![hello world in browser](images/quick-hello-world-2.png) ![hello world in browser](images/quick-hello-world-2.png)
4. Switch to another terminal window, and type `docker image ls` to 4. Switch to another terminal window, and type `docker image ls` to list local images.
list local images.
Listing images at this point should return `redis` and `web`. Listing images at this point should return `redis` and `web`.
``` ```console
$ docker image ls $ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB
python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB
@ -211,16 +218,17 @@ image pulled from the Docker Hub registry.
You can inspect images with `docker inspect <tag or id>`. You can inspect images with `docker inspect <tag or id>`.
5. Stop the application, either by running `docker-compose down` 5. Stop the application, either by running `docker-compose down`
from within your project directory in the second terminal, or by from within your project directory in the second terminal, or by
hitting CTRL+C in the original terminal where you started the app. hitting CTRL+C in the original terminal where you started the app.
## Step 5: Edit the Compose file to add a bind mount ## Step 5: Edit the Compose file to add a bind mount
Edit `docker-compose.yml` in your project directory to add a Edit `docker-compose.yml` in your project directory to add a
[bind mount](../storage/bind-mounts.md) for the `web` service: [bind mount](../storage/bind-mounts.md) for the `web` service:
version: '3' ```yaml
services: version: "{{ site.compose_file_v3 }}"
services:
web: web:
build: . build: .
ports: ports:
@ -231,6 +239,7 @@ Edit `docker-compose.yml` in your project directory to add a
FLASK_ENV: development FLASK_ENV: development
redis: redis:
image: "redis:alpine" image: "redis:alpine"
```
The new `volumes` key mounts the project directory (current directory) on the The new `volumes` key mounts the project directory (current directory) on the
host to `/code` inside the container, allowing you to modify the code on the host to `/code` inside the container, allowing you to modify the code on the
@ -242,8 +251,9 @@ mode and reload the code on change. This mode should only be used in development
From your project directory, type `docker-compose up` to build the app with the updated Compose file, and run it. From your project directory, type `docker-compose up` to build the app with the updated Compose file, and run it.
``` ```console
$ docker-compose up $ docker-compose up
Creating network "composetest_default" with the default driver Creating network "composetest_default" with the default driver
Creating composetest_web_1 ... Creating composetest_web_1 ...
Creating composetest_redis_1 ... Creating composetest_redis_1 ...
@ -282,16 +292,17 @@ Because the application code is now mounted into the container using a volume,
you can make changes to its code and see the changes instantly, without having you can make changes to its code and see the changes instantly, without having
to rebuild the image. to rebuild the image.
1. Change the greeting in `app.py` and save it. For example, change the `Hello World!` message to `Hello from Docker!`: Change the greeting in `app.py` and save it. For example, change the `Hello World!`
message to `Hello from Docker!`:
``` ```python
return 'Hello from Docker! I have been seen {} times.\n'.format(count) return 'Hello from Docker! I have been seen {} times.\n'.format(count)
``` ```
2. Refresh the app in your browser. The greeting should be updated, and the Refresh the app in your browser. The greeting should be updated, and the
counter should still be incrementing. counter should still be incrementing.
![hello world in browser](images/quick-hello-world-3.png) ![hello world in browser](images/quick-hello-world-3.png)
## Step 8: Experiment with some other commands ## Step 8: Experiment with some other commands
@ -299,34 +310,44 @@ If you want to run your services in the background, you can pass the `-d` flag
(for "detached" mode) to `docker-compose up` and use `docker-compose ps` to (for "detached" mode) to `docker-compose up` and use `docker-compose ps` to
see what is currently running: see what is currently running:
$ docker-compose up -d ```console
Starting composetest_redis_1... $ docker-compose up -d
Starting composetest_web_1...
$ docker-compose ps Starting composetest_redis_1...
Name Command State Ports Starting composetest_web_1...
-------------------------------------------------------------------
composetest_redis_1 /usr/local/bin/run Up $ docker-compose ps
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
Name Command State Ports
-------------------------------------------------------------------
composetest_redis_1 /usr/local/bin/run Up
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
```
The `docker-compose run` command allows you to run one-off commands for your The `docker-compose run` command allows you to run one-off commands for your
services. For example, to see what environment variables are available to the services. For example, to see what environment variables are available to the
`web` service: `web` service:
$ docker-compose run web env ```console
$ docker-compose run web env
```
See `docker-compose --help` to see other available commands. You can also install [command completion](completion.md) for the bash and zsh shell, which also shows you available commands. See `docker-compose --help` to see other available commands. You can also install [command completion](completion.md) for the bash and zsh shell, which also shows you available commands.
If you started Compose with `docker-compose up -d`, stop If you started Compose with `docker-compose up -d`, stop
your services once you've finished with them: your services once you've finished with them:
$ docker-compose stop ```console
$ docker-compose stop
```
You can bring everything down, removing the containers entirely, with the `down` You can bring everything down, removing the containers entirely, with the `down`
command. Pass `--volumes` to also remove the data volume used by the Redis command. Pass `--volumes` to also remove the data volume used by the Redis
container: container:
$ docker-compose down --volumes ```console
$ docker-compose down --volumes
```
At this point, you have seen the basics of how Compose works. At this point, you have seen the basics of how Compose works.

View File

@ -631,7 +631,7 @@ the recipient container back to the source (ie, `MYSQL_PORT_3306_TCP`).
To make new software easier to run, you can use `ENV` to update the To make new software easier to run, you can use `ENV` to update the
`PATH` environment variable for the software your container installs. For `PATH` environment variable for the software your container installs. For
example, `ENV PATH /usr/local/nginx/bin:$PATH` ensures that `CMD ["nginx"]` example, `ENV PATH=/usr/local/nginx/bin:$PATH` ensures that `CMD ["nginx"]`
just works. just works.
The `ENV` instruction is also useful for providing required environment The `ENV` instruction is also useful for providing required environment
@ -642,10 +642,10 @@ Lastly, `ENV` can also be used to set commonly used version numbers so that
version bumps are easier to maintain, as seen in the following example: version bumps are easier to maintain, as seen in the following example:
```dockerfile ```dockerfile
ENV PG_MAJOR 9.3 ENV PG_MAJOR=9.3
ENV PG_VERSION 9.3.4 ENV PG_VERSION=9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress &&
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH ENV PATH=/usr/local/postgres-$PG_MAJOR/bin:$PATH
``` ```
Similar to having constant variables in a program (as opposed to hard-coding Similar to having constant variables in a program (as opposed to hard-coding

View File

@ -8,7 +8,7 @@ RUN sed -i 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login # SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile" ENV NOTVISIBLE="in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22 EXPOSE 22

View File

@ -30,7 +30,7 @@ RUN sed -i 's/#*PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ss
# SSH login fix. Otherwise user is kicked off after login # SSH login fix. Otherwise user is kicked off after login
RUN sed -i 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshd RUN sed -i 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile" ENV NOTVISIBLE="in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22 EXPOSE 22

View File

@ -61,8 +61,8 @@ instead.
| Variable | Dockerfile example | `docker run` Example | | Variable | Dockerfile example | `docker run` Example |
|:--------------|:--------------------------------------------------|:----------------------------------------------------| |:--------------|:--------------------------------------------------|:----------------------------------------------------|
| `HTTP_PROXY` | `ENV HTTP_PROXY "http://127.0.0.1:3001"` | `--env HTTP_PROXY="http://127.0.0.1:3001"` | | `HTTP_PROXY` | `ENV HTTP_PROXY="http://127.0.0.1:3001"` | `--env HTTP_PROXY="http://127.0.0.1:3001"` |
| `HTTPS_PROXY` | `ENV HTTPS_PROXY "https://127.0.0.1:3001"` | `--env HTTPS_PROXY="https://127.0.0.1:3001"` | | `HTTPS_PROXY` | `ENV HTTPS_PROXY="https://127.0.0.1:3001"` | `--env HTTPS_PROXY="https://127.0.0.1:3001"` |
| `FTP_PROXY` | `ENV FTP_PROXY "ftp://127.0.0.1:3001"` | `--env FTP_PROXY="ftp://127.0.0.1:3001"` | | `FTP_PROXY` | `ENV FTP_PROXY="ftp://127.0.0.1:3001"` | `--env FTP_PROXY="ftp://127.0.0.1:3001"` |
| `NO_PROXY` | `ENV NO_PROXY "*.test.example.com,.example2.com"` | `--env NO_PROXY="*.test.example.com,.example2.com"` | | `NO_PROXY` | `ENV NO_PROXY="*.test.example.com,.example2.com"` | `--env NO_PROXY="*.test.example.com,.example2.com"` |