31
янв
Docker Desktop includes Docker App, developer tools, Kubernetes, and version synchronization to production Docker Engines. Docker Desktop allows you to leverage certified images and templates and your choice of languages and tools. Development workflows leverage Docker Hub to extend your development environment to a secure repository for rapid.
The platform known as Docker has become one of the most popular ways to run a new kind of software known as containerized apps. And while Docker's mainly aimed at programmer types, there are a few reasons why everyday Mac users might want it around as well.
Containerized apps are tidy little packages of software that bundle nearly everything they need to run in a single, self-contained box.
Programmers can write an app once and know that it'll run anywhere, every time. Businesses get an efficient way to run lots of apps on a single server without straining their hardware. And users get apps that won't sprawl out and spread files into their hard drives' nooks and crannies, nor start hogging memory and slowing down the entire computer.
Docker uses emulation to ensure that the same containerized app can run on any machine where Docker's installed. And because it emulates an operating system – usually some flavor of Linux, though you can also set it up to run enterprise versions of Windows – instead of actual chip hardware, it demands a lot less memory and processing power than traditional virtual machines like Parallels or VMware Fusion.
Unlike those apps, you can't use Docker to run Windows on your Mac – though you can run at least limited versions of Linux with it. And you can use Docker to run apps that weren't originally written for the Mac.
Once you fire up the easy-to-install Docker app, it runs in the background, and you can use the Terminal or another app called Kitematic (we'll get to that later) to install and run containerized apps.
As mentioned above, Docker's mainly aimed at programmers who want to containerize existing apps or write new ones, and businesses and IT folks who want to use its industrial-grade software.
There are Docker versions of familiar desktop apps like Firefox, Chrome, Skype, Spotify, image editor GiMP, and audio editor Audacity. But most of these apps already have native Mac versions. Running them in containers only makes sense if you like the technical challenge, want to keep a single app from hogging all your system's memory, or want to ensure that any malware you might pick up while browsing the web stays stuck inside its container, unable to escape to the rest of your Mac.
As of this writing, the main reason I've found to run Docker on a Mac is Pi-hole, originally made for the Raspberry Pi. Pi-hole can automatically block Web ads across your entire home network, and Docker's the only way to get it working on a Mac without also having a Raspberry Pi.
Docker Hub keeps track of the containers you're running (or creating) and provides a one-stop shop to find new ones. Sign up for a Docker account with a unique Docker ID, your email, and a strong password.
Once you've signed up and signed in to Docker Hub, get Docker Desktop for Mac. It's got everything you'll need to run Docker in one Mac-friendly installer. Your Mac needs to be running Mac OS Sierra or later, and have at least 4GB of RAM.
Open the docker.dmg
file you downloaded, and drag the Docker app's cartoon whale icon into your Applications folder.
When you run the Docker app, a little whale icon will appear on the right side of the menubar atop your screen. It'll take a few minutes to get running, and Docker may ask your permission to use services on your computer. The app will also prompt you to enter the Docker ID and password you just created.
When containers stop appearing and disappearing atop the little whale icon in the menubar, and you see a green dot at the top of the Docker menu next to 'Docker Desktop is running,' you're all set.
Consult the Preferences in the Docker menu to control how big a chunk of your hard drive Docker's allotted, and how much of your memory and CPU it's allowed to use, among other options.
Kitematic lets you install, manage, and remove your Docker containers from a single graphical interface — a lifesaver if you're not familiar or comfortable with the Terminal. You can install, and later open, Kitematic directly from the Docker app's menu:
Follow the link in that dialog box to install Kitematic. The app may ask for — you guessed it — your Docker ID and password again, just to keep track of your containers.
From Kitematic, you can search for and install new containers, and delete, edit, stop, or restart existing ones. If a container's running, Kitematic gives you an easy way to view its log files, which aren't readily visible from the Terminal. The interface is fairly intuitive, so feel free to play around and see what you can do.
In my tests, Kitematic came in most useful for deleting troublesome containers whose installation I'd somehow botched. Just find the container in the list on the left side of the Kitematic window, click the X icon next to it, and the container's gone completely, for good. You can always reinstall a package, either from the Terminal or by searching for it in Kitematic, and try again.
Consult Docker for Mac's help files for more information about getting started, ways to test that your installation's up and running smoothly, and more things you can do with Docker. There's also a guide to teach you how to create your own containerized apps.
For less technically inclined folks, it's tough to find a good list of desktop apps that work with Docker. Docker Hub doesn't break desktop apps into their own category, but Jessie Frazelle compiled this list in 2015.
Besides Pi-hole, do you have any favorite Docker containers that might benefit everyday Mac users? Ship them our way in the comments below.
When their specialist kit failed, soldiers turned to an iPhone to get the job done.
Can’t connect to the server running in your container? Let’s see why, and how to fix it, starting with an example.
If you run a server on your machine listening on 127.0.0.1
, the “loopback” or “localhost” address:
You can then load it in your browser at http://127.0.0.1:8000.
But if you kill that and run it in a container:
If you then try to connect with your browser to http://127.0.0.1:8000 you’ll get connection refused or connection reset.
What’s going on?To understand how to solve this, you need to know a minimal amount about how Docker’s networking works.In particular, this article will cover:
docker run -p 5000:5000
does, and why our example above doesn’t work.Let’s start with our first scenario: you run a server directly inside your operating system, and then connect to it.I’m going to assume the main OS is Linux, for simplicity of explanation. Docker runs on non-Linux OSes like macOS by running a Linux virtual machine, but the practical consequences are the same.
Your operating system has multiple network “interfaces”.For example, on my computer (with output shortened for clarity):
In this output we see three network interfaces:
docker0
for now.lo
is the loopback interface, with IPv4 address 127.0.0.1: it’s your own computer, addressable in-memory without any networking hardware.wlp0s20u8
is my WiFi card, with IPv4 address 192.168.7.202
, and when I talk to computers on the Internet the packets are sent via that interface.Let’s go back to our starting, working example—you run a server listening on 127.0.0.1
, and then connect to it.We can visualize it like this:
You’ll notice the image above talks about a “Default network namespace”.So what’s that?
Docker is a system for running containers: a way to isolate processes from each other.It builds on a number of Linux kernel features, one of which is network namespaces—a way for different processes to have different network devices, IPs, firewall rules, and so on.
By default, each container run by Docker has its own network namespace, with its own IPs:
So this container has two interfaces, eth0
and lo
, each with their own IP addresses.But because this is a different network namespace, these are different interfaces than the default namespace we saw above.
To make it clear what this means, let’s run the Flask server inside a Docker container, and then diagram the results:
The resulting network setup looks like this:
Now it’s clear why there’s a connection refused: the server is listening on 127.0.0.1
inside the container’s network namespace.The browser is connecting to 127.0.0.1
in the main, default network namespace.But those are different interfaces, so no connection is made.
How do we connect the two network namespaces? Elicenser control center cubase. With Docker port-forwarding.
If we run docker run
with -p 5000:5000
, it will forward from all interfaces where the Docker daemon is running (for our purposes, the main network namespace) to the external IP address of the containter.
To break it down explicitly: -p 5000:5000
means redirecting traffic from port 5000 on all interfaces in the main network namespace to the container’s port 5000 on its external interface.-p 8080:80
would redirect traffic from port 8080 on all interfaces in the main network namespace to port 80 on the container’s external interface. Xfx radeon hd 7850 drivers. And so on.
(We’re doing port 5000 specifically because that’s where our Docker image is listening, Flask’s default port.)
So let’s run a container, and then look at a diagram to visually see what that means:
And now we see the second problem: the server is listening on 127.0.0.1
inside the container network namespace, but the port forwarding is going to the external IP, 172.17.0.2
.
Thus, a connection reset or refused.
Port forwarding can only connect to a single destination—but you can change where the server process is listening.You do this by listening on 0.0.0.0
, which means “listen on all interfaces”.
For example, you can do:
Or for a Flask application packaged with a Dockerfile
, you can do:
Note: Outside the topic under discussion, the Dockerfiles in this article are not examples of best practices, since the added complexity would obscure the main point of the article. So if you’re going to be running your Python application in production with Docker, here are two ways to apply best practices:
Now the network diagram looks like this:
Want to quickly get up to speed on Docker packaging? This article is an excerpt from my book, Just Enough DockerPackaging.
docker run -p 5000:5000
will forward from all interfaces in the main network namespace (or more accurately, the one where the Docker daemon is running) to the external IP in the container.0.0.0.0
.Docker Desktop includes Docker App, developer tools, Kubernetes, and version synchronization to production Docker Engines. Docker Desktop allows you to leverage certified images and templates and your choice of languages and tools. Development workflows leverage Docker Hub to extend your development environment to a secure repository for rapid.
The platform known as Docker has become one of the most popular ways to run a new kind of software known as containerized apps. And while Docker's mainly aimed at programmer types, there are a few reasons why everyday Mac users might want it around as well.
Containerized apps are tidy little packages of software that bundle nearly everything they need to run in a single, self-contained box.
Programmers can write an app once and know that it'll run anywhere, every time. Businesses get an efficient way to run lots of apps on a single server without straining their hardware. And users get apps that won't sprawl out and spread files into their hard drives' nooks and crannies, nor start hogging memory and slowing down the entire computer.
Docker uses emulation to ensure that the same containerized app can run on any machine where Docker's installed. And because it emulates an operating system – usually some flavor of Linux, though you can also set it up to run enterprise versions of Windows – instead of actual chip hardware, it demands a lot less memory and processing power than traditional virtual machines like Parallels or VMware Fusion.
Unlike those apps, you can't use Docker to run Windows on your Mac – though you can run at least limited versions of Linux with it. And you can use Docker to run apps that weren't originally written for the Mac.
Once you fire up the easy-to-install Docker app, it runs in the background, and you can use the Terminal or another app called Kitematic (we'll get to that later) to install and run containerized apps.
As mentioned above, Docker's mainly aimed at programmers who want to containerize existing apps or write new ones, and businesses and IT folks who want to use its industrial-grade software.
There are Docker versions of familiar desktop apps like Firefox, Chrome, Skype, Spotify, image editor GiMP, and audio editor Audacity. But most of these apps already have native Mac versions. Running them in containers only makes sense if you like the technical challenge, want to keep a single app from hogging all your system's memory, or want to ensure that any malware you might pick up while browsing the web stays stuck inside its container, unable to escape to the rest of your Mac.
As of this writing, the main reason I've found to run Docker on a Mac is Pi-hole, originally made for the Raspberry Pi. Pi-hole can automatically block Web ads across your entire home network, and Docker's the only way to get it working on a Mac without also having a Raspberry Pi.
Docker Hub keeps track of the containers you're running (or creating) and provides a one-stop shop to find new ones. Sign up for a Docker account with a unique Docker ID, your email, and a strong password.
Once you've signed up and signed in to Docker Hub, get Docker Desktop for Mac. It's got everything you'll need to run Docker in one Mac-friendly installer. Your Mac needs to be running Mac OS Sierra or later, and have at least 4GB of RAM.
Open the docker.dmg
file you downloaded, and drag the Docker app's cartoon whale icon into your Applications folder.
When you run the Docker app, a little whale icon will appear on the right side of the menubar atop your screen. It'll take a few minutes to get running, and Docker may ask your permission to use services on your computer. The app will also prompt you to enter the Docker ID and password you just created.
When containers stop appearing and disappearing atop the little whale icon in the menubar, and you see a green dot at the top of the Docker menu next to 'Docker Desktop is running,' you're all set.
Consult the Preferences in the Docker menu to control how big a chunk of your hard drive Docker's allotted, and how much of your memory and CPU it's allowed to use, among other options.
Kitematic lets you install, manage, and remove your Docker containers from a single graphical interface — a lifesaver if you're not familiar or comfortable with the Terminal. You can install, and later open, Kitematic directly from the Docker app's menu:
Follow the link in that dialog box to install Kitematic. The app may ask for — you guessed it — your Docker ID and password again, just to keep track of your containers.
From Kitematic, you can search for and install new containers, and delete, edit, stop, or restart existing ones. If a container's running, Kitematic gives you an easy way to view its log files, which aren't readily visible from the Terminal. The interface is fairly intuitive, so feel free to play around and see what you can do.
In my tests, Kitematic came in most useful for deleting troublesome containers whose installation I'd somehow botched. Just find the container in the list on the left side of the Kitematic window, click the X icon next to it, and the container's gone completely, for good. You can always reinstall a package, either from the Terminal or by searching for it in Kitematic, and try again.
Consult Docker for Mac's help files for more information about getting started, ways to test that your installation's up and running smoothly, and more things you can do with Docker. There's also a guide to teach you how to create your own containerized apps.
For less technically inclined folks, it's tough to find a good list of desktop apps that work with Docker. Docker Hub doesn't break desktop apps into their own category, but Jessie Frazelle compiled this list in 2015.
Besides Pi-hole, do you have any favorite Docker containers that might benefit everyday Mac users? Ship them our way in the comments below.
When their specialist kit failed, soldiers turned to an iPhone to get the job done.
Can’t connect to the server running in your container? Let’s see why, and how to fix it, starting with an example.
If you run a server on your machine listening on 127.0.0.1
, the “loopback” or “localhost” address:
You can then load it in your browser at http://127.0.0.1:8000.
But if you kill that and run it in a container:
If you then try to connect with your browser to http://127.0.0.1:8000 you’ll get connection refused or connection reset.
What’s going on?To understand how to solve this, you need to know a minimal amount about how Docker’s networking works.In particular, this article will cover:
docker run -p 5000:5000
does, and why our example above doesn’t work.Let’s start with our first scenario: you run a server directly inside your operating system, and then connect to it.I’m going to assume the main OS is Linux, for simplicity of explanation. Docker runs on non-Linux OSes like macOS by running a Linux virtual machine, but the practical consequences are the same.
Your operating system has multiple network “interfaces”.For example, on my computer (with output shortened for clarity):
In this output we see three network interfaces:
docker0
for now.lo
is the loopback interface, with IPv4 address 127.0.0.1: it’s your own computer, addressable in-memory without any networking hardware.wlp0s20u8
is my WiFi card, with IPv4 address 192.168.7.202
, and when I talk to computers on the Internet the packets are sent via that interface.Let’s go back to our starting, working example—you run a server listening on 127.0.0.1
, and then connect to it.We can visualize it like this:
You’ll notice the image above talks about a “Default network namespace”.So what’s that?
Docker is a system for running containers: a way to isolate processes from each other.It builds on a number of Linux kernel features, one of which is network namespaces—a way for different processes to have different network devices, IPs, firewall rules, and so on.
By default, each container run by Docker has its own network namespace, with its own IPs:
So this container has two interfaces, eth0
and lo
, each with their own IP addresses.But because this is a different network namespace, these are different interfaces than the default namespace we saw above.
To make it clear what this means, let’s run the Flask server inside a Docker container, and then diagram the results:
The resulting network setup looks like this:
Now it’s clear why there’s a connection refused: the server is listening on 127.0.0.1
inside the container’s network namespace.The browser is connecting to 127.0.0.1
in the main, default network namespace.But those are different interfaces, so no connection is made.
How do we connect the two network namespaces? Elicenser control center cubase. With Docker port-forwarding.
If we run docker run
with -p 5000:5000
, it will forward from all interfaces where the Docker daemon is running (for our purposes, the main network namespace) to the external IP address of the containter.
To break it down explicitly: -p 5000:5000
means redirecting traffic from port 5000 on all interfaces in the main network namespace to the container’s port 5000 on its external interface.-p 8080:80
would redirect traffic from port 8080 on all interfaces in the main network namespace to port 80 on the container’s external interface. Xfx radeon hd 7850 drivers. And so on.
(We’re doing port 5000 specifically because that’s where our Docker image is listening, Flask’s default port.)
So let’s run a container, and then look at a diagram to visually see what that means:
And now we see the second problem: the server is listening on 127.0.0.1
inside the container network namespace, but the port forwarding is going to the external IP, 172.17.0.2
.
Thus, a connection reset or refused.
Port forwarding can only connect to a single destination—but you can change where the server process is listening.You do this by listening on 0.0.0.0
, which means “listen on all interfaces”.
For example, you can do:
Or for a Flask application packaged with a Dockerfile
, you can do:
Note: Outside the topic under discussion, the Dockerfiles in this article are not examples of best practices, since the added complexity would obscure the main point of the article. So if you’re going to be running your Python application in production with Docker, here are two ways to apply best practices:
Now the network diagram looks like this:
Want to quickly get up to speed on Docker packaging? This article is an excerpt from my book, Just Enough DockerPackaging.
docker run -p 5000:5000
will forward from all interfaces in the main network namespace (or more accurately, the one where the Docker daemon is running) to the external IP in the container.0.0.0.0
.Docker Desktop includes Docker App, developer tools, Kubernetes, and version synchronization to production Docker Engines. Docker Desktop allows you to leverage certified images and templates and your choice of languages and tools. Development workflows leverage Docker Hub to extend your development environment to a secure repository for rapid.
The platform known as Docker has become one of the most popular ways to run a new kind of software known as containerized apps. And while Docker's mainly aimed at programmer types, there are a few reasons why everyday Mac users might want it around as well.
Containerized apps are tidy little packages of software that bundle nearly everything they need to run in a single, self-contained box.
Programmers can write an app once and know that it'll run anywhere, every time. Businesses get an efficient way to run lots of apps on a single server without straining their hardware. And users get apps that won't sprawl out and spread files into their hard drives' nooks and crannies, nor start hogging memory and slowing down the entire computer.
Docker uses emulation to ensure that the same containerized app can run on any machine where Docker's installed. And because it emulates an operating system – usually some flavor of Linux, though you can also set it up to run enterprise versions of Windows – instead of actual chip hardware, it demands a lot less memory and processing power than traditional virtual machines like Parallels or VMware Fusion.
Unlike those apps, you can't use Docker to run Windows on your Mac – though you can run at least limited versions of Linux with it. And you can use Docker to run apps that weren't originally written for the Mac.
Once you fire up the easy-to-install Docker app, it runs in the background, and you can use the Terminal or another app called Kitematic (we'll get to that later) to install and run containerized apps.
As mentioned above, Docker's mainly aimed at programmers who want to containerize existing apps or write new ones, and businesses and IT folks who want to use its industrial-grade software.
There are Docker versions of familiar desktop apps like Firefox, Chrome, Skype, Spotify, image editor GiMP, and audio editor Audacity. But most of these apps already have native Mac versions. Running them in containers only makes sense if you like the technical challenge, want to keep a single app from hogging all your system's memory, or want to ensure that any malware you might pick up while browsing the web stays stuck inside its container, unable to escape to the rest of your Mac.
As of this writing, the main reason I've found to run Docker on a Mac is Pi-hole, originally made for the Raspberry Pi. Pi-hole can automatically block Web ads across your entire home network, and Docker's the only way to get it working on a Mac without also having a Raspberry Pi.
Docker Hub keeps track of the containers you're running (or creating) and provides a one-stop shop to find new ones. Sign up for a Docker account with a unique Docker ID, your email, and a strong password.
Once you've signed up and signed in to Docker Hub, get Docker Desktop for Mac. It's got everything you'll need to run Docker in one Mac-friendly installer. Your Mac needs to be running Mac OS Sierra or later, and have at least 4GB of RAM.
Open the docker.dmg
file you downloaded, and drag the Docker app's cartoon whale icon into your Applications folder.
When you run the Docker app, a little whale icon will appear on the right side of the menubar atop your screen. It'll take a few minutes to get running, and Docker may ask your permission to use services on your computer. The app will also prompt you to enter the Docker ID and password you just created.
When containers stop appearing and disappearing atop the little whale icon in the menubar, and you see a green dot at the top of the Docker menu next to 'Docker Desktop is running,' you're all set.
Consult the Preferences in the Docker menu to control how big a chunk of your hard drive Docker's allotted, and how much of your memory and CPU it's allowed to use, among other options.
Kitematic lets you install, manage, and remove your Docker containers from a single graphical interface — a lifesaver if you're not familiar or comfortable with the Terminal. You can install, and later open, Kitematic directly from the Docker app's menu:
Follow the link in that dialog box to install Kitematic. The app may ask for — you guessed it — your Docker ID and password again, just to keep track of your containers.
From Kitematic, you can search for and install new containers, and delete, edit, stop, or restart existing ones. If a container's running, Kitematic gives you an easy way to view its log files, which aren't readily visible from the Terminal. The interface is fairly intuitive, so feel free to play around and see what you can do.
In my tests, Kitematic came in most useful for deleting troublesome containers whose installation I'd somehow botched. Just find the container in the list on the left side of the Kitematic window, click the X icon next to it, and the container's gone completely, for good. You can always reinstall a package, either from the Terminal or by searching for it in Kitematic, and try again.
Consult Docker for Mac's help files for more information about getting started, ways to test that your installation's up and running smoothly, and more things you can do with Docker. There's also a guide to teach you how to create your own containerized apps.
For less technically inclined folks, it's tough to find a good list of desktop apps that work with Docker. Docker Hub doesn't break desktop apps into their own category, but Jessie Frazelle compiled this list in 2015.
Besides Pi-hole, do you have any favorite Docker containers that might benefit everyday Mac users? Ship them our way in the comments below.
When their specialist kit failed, soldiers turned to an iPhone to get the job done.
Can’t connect to the server running in your container? Let’s see why, and how to fix it, starting with an example.
If you run a server on your machine listening on 127.0.0.1
, the “loopback” or “localhost” address:
You can then load it in your browser at http://127.0.0.1:8000.
But if you kill that and run it in a container:
If you then try to connect with your browser to http://127.0.0.1:8000 you’ll get connection refused or connection reset.
What’s going on?To understand how to solve this, you need to know a minimal amount about how Docker’s networking works.In particular, this article will cover:
docker run -p 5000:5000
does, and why our example above doesn’t work.Let’s start with our first scenario: you run a server directly inside your operating system, and then connect to it.I’m going to assume the main OS is Linux, for simplicity of explanation. Docker runs on non-Linux OSes like macOS by running a Linux virtual machine, but the practical consequences are the same.
Your operating system has multiple network “interfaces”.For example, on my computer (with output shortened for clarity):
In this output we see three network interfaces:
docker0
for now.lo
is the loopback interface, with IPv4 address 127.0.0.1: it’s your own computer, addressable in-memory without any networking hardware.wlp0s20u8
is my WiFi card, with IPv4 address 192.168.7.202
, and when I talk to computers on the Internet the packets are sent via that interface.Let’s go back to our starting, working example—you run a server listening on 127.0.0.1
, and then connect to it.We can visualize it like this:
You’ll notice the image above talks about a “Default network namespace”.So what’s that?
Docker is a system for running containers: a way to isolate processes from each other.It builds on a number of Linux kernel features, one of which is network namespaces—a way for different processes to have different network devices, IPs, firewall rules, and so on.
By default, each container run by Docker has its own network namespace, with its own IPs:
So this container has two interfaces, eth0
and lo
, each with their own IP addresses.But because this is a different network namespace, these are different interfaces than the default namespace we saw above.
To make it clear what this means, let’s run the Flask server inside a Docker container, and then diagram the results:
The resulting network setup looks like this:
Now it’s clear why there’s a connection refused: the server is listening on 127.0.0.1
inside the container’s network namespace.The browser is connecting to 127.0.0.1
in the main, default network namespace.But those are different interfaces, so no connection is made.
How do we connect the two network namespaces? Elicenser control center cubase. With Docker port-forwarding.
If we run docker run
with -p 5000:5000
, it will forward from all interfaces where the Docker daemon is running (for our purposes, the main network namespace) to the external IP address of the containter.
To break it down explicitly: -p 5000:5000
means redirecting traffic from port 5000 on all interfaces in the main network namespace to the container’s port 5000 on its external interface.-p 8080:80
would redirect traffic from port 8080 on all interfaces in the main network namespace to port 80 on the container’s external interface. Xfx radeon hd 7850 drivers. And so on.
(We’re doing port 5000 specifically because that’s where our Docker image is listening, Flask’s default port.)
So let’s run a container, and then look at a diagram to visually see what that means:
And now we see the second problem: the server is listening on 127.0.0.1
inside the container network namespace, but the port forwarding is going to the external IP, 172.17.0.2
.
Thus, a connection reset or refused.
Port forwarding can only connect to a single destination—but you can change where the server process is listening.You do this by listening on 0.0.0.0
, which means “listen on all interfaces”.
For example, you can do:
Or for a Flask application packaged with a Dockerfile
, you can do:
Note: Outside the topic under discussion, the Dockerfiles in this article are not examples of best practices, since the added complexity would obscure the main point of the article. So if you’re going to be running your Python application in production with Docker, here are two ways to apply best practices:
Now the network diagram looks like this:
Want to quickly get up to speed on Docker packaging? This article is an excerpt from my book, Just Enough DockerPackaging.
docker run -p 5000:5000
will forward from all interfaces in the main network namespace (or more accurately, the one where the Docker daemon is running) to the external IP in the container.0.0.0.0
.