mirror of https://github.com/docker/docs.git
parent
92adc0503b
commit
6e94c0157a
|
@ -23,13 +23,13 @@
|
|||
</a>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-lg-12">
|
||||
<a href="/engine/examples/dotnetcore/">
|
||||
<a href="/languages/dotnet/">
|
||||
Dockerize a .Net Core application
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-lg-12">
|
||||
<a href="/compose/aspnet-mssql-compose/" target="_blank">
|
||||
Dockerize an ASP.NET Core application with SQL Server on Linux
|
||||
<a href="https://github.com/docker/awesome-compose/tree/master/aspnet-mssql" target="_blank">
|
||||
ASP.NET Core application with SQL Server
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -200,6 +200,7 @@
|
|||
"https://hub.docker.com/_/couchbase/":
|
||||
- /samples/couchbase
|
||||
- /samples/library/couchbase
|
||||
- /samples/couchdb_data_volumes
|
||||
"https://hub.docker.com/_/couchdb/":
|
||||
- /samples/couchdb
|
||||
- /samples/library/couchdb
|
||||
|
|
|
@ -137,10 +137,6 @@ command=/usr/sbin/sshd -D
|
|||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
#
|
||||
# example Dockerfile for https://docs.docker.com/examples/postgresql_service/
|
||||
#
|
||||
|
||||
FROM ubuntu
|
||||
|
||||
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
|
||||
|
|
|
@ -28,8 +28,8 @@ most benefits from Docker.
|
|||
- [Docker for Java developers lab](https://github.com/docker/labs/tree/master/developer-tools/java/){: target="_blank" rel="noopener" class="_"}
|
||||
- [Port a node.js app to Docker lab](https://github.com/docker/labs/tree/master/developer-tools/nodejs/porting){: target="_blank" rel="noopener" class="_"}
|
||||
- [Ruby on Rails app on Docker lab](https://github.com/docker/labs/tree/master/developer-tools/ruby){: target="_blank" rel="noopener" class="_"}
|
||||
- [Dockerize a .Net Core application](../samples/dotnetcore.md){: target="_blank" rel="noopener" class="_"}
|
||||
- [Dockerize an ASP.NET Core application with SQL Server on Linux](../samples/aspnet-mssql-compose.md){: target="_blank" rel="noopener" class="_"} using Docker Compose
|
||||
- [Dockerize a .Net Core application](../language/dotnet/index.md){: target="_blank" rel="noopener" class="_"}
|
||||
- [ASP.NET Core application with SQL Server](https://github.com/docker/awesome-compose/tree/master/aspnet-mssql){: target="_blank" rel="noopener" class="_"} using Docker Compose
|
||||
|
||||
## Advanced development with the SDK or API
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#
|
||||
# Build: docker build -t apt-cacher .
|
||||
# Run: docker run -d -p 3142:3142 --name apt-cacher-run apt-cacher
|
||||
#
|
||||
# and then you can run containers with:
|
||||
# docker run -t -i --rm -e http_proxy http://dockerhost:3142/ debian bash
|
||||
#
|
||||
FROM ubuntu
|
||||
|
||||
VOLUME ["/var/cache/apt-cacher-ng"]
|
||||
RUN apt-get update && apt-get install -y apt-cacher-ng
|
||||
|
||||
EXPOSE 3142
|
||||
CMD chmod 777 /var/cache/apt-cacher-ng && /etc/init.d/apt-cacher-ng start && tail -f /var/log/apt-cacher-ng/*
|
|
@ -1,144 +0,0 @@
|
|||
---
|
||||
description: Installing and running an apt-cacher-ng service
|
||||
keywords: docker, example, package installation, networking, debian, ubuntu
|
||||
title: Dockerize an apt-cacher-ng service
|
||||
redirect_from:
|
||||
- /engine/examples/apt-cacher-ng/
|
||||
---
|
||||
|
||||
> **Note**:
|
||||
> - **If you don't like sudo** then see
|
||||
> [*Giving non-root access*](../engine/install/linux-postinstall.md#manage-docker-as-a-non-root-user).
|
||||
> - **If you're using macOS or docker via TCP** then you shouldn't use sudo.
|
||||
|
||||
When you have multiple Docker servers, or build unrelated Docker
|
||||
containers which can't make use of the Docker build cache, it can be
|
||||
useful to have a caching proxy for your packages. This container makes
|
||||
the second download of any package almost instant.
|
||||
|
||||
Use the following Dockerfile:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Build: docker build -t apt-cacher .
|
||||
# Run: docker run -d -p 3142:3142 --name apt-cacher-run apt-cacher
|
||||
#
|
||||
# and then you can run containers with:
|
||||
# docker run -t -i --rm -e http_proxy http://dockerhost:3142/ debian bash
|
||||
#
|
||||
# Here, `dockerhost` is the IP address or FQDN of a host running the Docker daemon
|
||||
# which acts as an APT proxy server.
|
||||
FROM ubuntu
|
||||
|
||||
VOLUME ["/var/cache/apt-cacher-ng"]
|
||||
RUN apt-get update && apt-get install -y apt-cacher-ng
|
||||
|
||||
EXPOSE 3142
|
||||
CMD chmod 777 /var/cache/apt-cacher-ng && /etc/init.d/apt-cacher-ng start && tail -f /var/log/apt-cacher-ng/*
|
||||
```
|
||||
|
||||
To build the image using:
|
||||
|
||||
```console
|
||||
$ docker build -t eg_apt_cacher_ng .
|
||||
```
|
||||
|
||||
Then run it, mapping the exposed port to one on the host
|
||||
|
||||
```console
|
||||
$ docker run -d -p 3142:3142 --name test_apt_cacher_ng eg_apt_cacher_ng
|
||||
```
|
||||
|
||||
To see the logfiles that are `tailed` in the default command, you can
|
||||
use:
|
||||
|
||||
```console
|
||||
$ docker logs -f test_apt_cacher_ng
|
||||
```
|
||||
|
||||
To get your Debian-based containers to use the proxy, you have
|
||||
following options. Replace `dockerhost` with the
|
||||
IP address or FQDN of the host running the `test_apt_cacher_ng`
|
||||
container.
|
||||
|
||||
1. Add an apt Proxy setting
|
||||
`echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/apt.conf.d/01proxy`
|
||||
2. Set an environment variable:
|
||||
`http_proxy=http://dockerhost:3142/`
|
||||
3. Change your `sources.list` entries to start with
|
||||
`http://dockerhost:3142/`
|
||||
4. Link Debian-based containers to the APT proxy container using `--link`
|
||||
5. Create a custom network of an APT proxy container with Debian-based containers.
|
||||
|
||||
**Option 1** injects the settings safely into your apt configuration in
|
||||
a local version of a common base:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu
|
||||
RUN echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/apt.conf.d/01proxy
|
||||
RUN apt-get update && apt-get install -y vim git
|
||||
|
||||
# docker build -t my_ubuntu .
|
||||
```
|
||||
|
||||
**Option 2** is good for testing, but breaks other HTTP clients
|
||||
which obey `http_proxy`, such as `curl`, `wget` and others:
|
||||
|
||||
```console
|
||||
$ docker run --rm -t -i -e http_proxy=http://dockerhost:3142/ debian bash
|
||||
```
|
||||
|
||||
**Option 3** is the least portable, but you might need to do it and you can do it
|
||||
from your `Dockerfile` too.
|
||||
|
||||
**Option 4** links Debian-containers to the proxy server using following command:
|
||||
|
||||
```console
|
||||
$ docker run -i -t --link test_apt_cacher_ng:apt_proxy -e http_proxy=http://apt_proxy:3142/ debian bash
|
||||
```
|
||||
|
||||
**Option 5** creates a custom network of APT proxy server and Debian-based containers:
|
||||
|
||||
```console
|
||||
$ docker network create mynetwork
|
||||
$ docker run -d -p 3142:3142 --network=mynetwork --name test_apt_cacher_ng eg_apt_cacher_ng
|
||||
$ docker run --rm -it --network=mynetwork -e http_proxy=http://test_apt_cacher_ng:3142/ debian bash
|
||||
```
|
||||
|
||||
Apt-cacher-ng has some tools that allow you to manage the repository,
|
||||
and they can be used by leveraging the `VOLUME`
|
||||
instruction, and the image we built to run the service:
|
||||
|
||||
```console
|
||||
$ docker run --rm -t -i --volumes-from test_apt_cacher_ng eg_apt_cacher_ng bash
|
||||
|
||||
root@f38c87f2a42d:/# /usr/lib/apt-cacher-ng/distkill.pl
|
||||
Scanning /var/cache/apt-cacher-ng, please wait...
|
||||
Found distributions:
|
||||
bla, taggedcount: 0
|
||||
1. precise-security (36 index files)
|
||||
2. wheezy (25 index files)
|
||||
3. precise-updates (36 index files)
|
||||
4. precise (36 index files)
|
||||
5. wheezy-updates (18 index files)
|
||||
|
||||
Found architectures:
|
||||
6. amd64 (36 index files)
|
||||
7. i386 (24 index files)
|
||||
|
||||
WARNING: The removal action may wipe out whole directories containing
|
||||
index files. Select d to see detailed list.
|
||||
|
||||
(Number nn: tag distribution or architecture nn; 0: exit; d: show details; r: remove tagged; q: quit): q
|
||||
```
|
||||
|
||||
Finally, clean up after your test by stopping and removing the
|
||||
container, and then removing the image.
|
||||
|
||||
```console
|
||||
$ docker container stop test_apt_cacher_ng
|
||||
$ docker container rm test_apt_cacher_ng
|
||||
$ docker image rm eg_apt_cacher_ng
|
||||
```
|
|
@ -1,215 +0,0 @@
|
|||
---
|
||||
description: Create a Docker Compose application using ASP.NET Core and SQL Server on Linux in Docker.
|
||||
keywords: dotnet, .NET, Core, example, ASP.NET Core, SQL Server, mssql
|
||||
title: "Quickstart: Compose and ASP.NET Core with SQL Server"
|
||||
redirect_from:
|
||||
- /compose/aspnet-mssql-compose/
|
||||
---
|
||||
|
||||
This quick-start guide demonstrates how to use Docker Engine on Linux and Docker
|
||||
Compose to set up and run the sample ASP.NET Core application using the
|
||||
[.NET Core SDK image](https://hub.docker.com/_/microsoft-dotnet-core-sdk)
|
||||
with the
|
||||
[SQL Server on Linux image](https://hub.docker.com/_/microsoft-mssql-server).
|
||||
You just need to have [Docker Engine](../get-docker.md)
|
||||
and [Docker Compose](../compose/install/index.md) installed on your
|
||||
platform of choice: Linux, Mac or Windows.
|
||||
|
||||
For this sample, we create a sample .NET Core Web Application using the
|
||||
`microsoft/dotnet:2.1-sdk` Docker image. After that, we create a `Dockerfile`,
|
||||
configure this app to use our SQL Server database, and then create a
|
||||
`docker-compose.yml` that defines the behavior of all of these components.
|
||||
|
||||
> **Note**: This sample is made for Docker Engine on Linux. For Windows
|
||||
> Containers, visit
|
||||
> [Docker Labs for Windows Containers](https://github.com/docker/labs/tree/master/windows).
|
||||
|
||||
1. Create a new directory for your application.
|
||||
|
||||
This directory is the context of your docker-compose project. For
|
||||
[Docker Desktop for Windows](../desktop/settings/windows.md#file-sharing) and
|
||||
[Docker Desktop for Mac](../desktop/settings/mac.md#file-sharing), you
|
||||
need to set up file sharing for the volume that you need to map.
|
||||
|
||||
2. Within your directory, use the `dotnet:2.1-sdk` Docker image to generate a
|
||||
sample web application within the container under the `/app` directory and
|
||||
into your host machine in the working directory:
|
||||
|
||||
```console
|
||||
$ docker run -v ${PWD}:/app --workdir /app mcr.microsoft.com/dotnet/sdk dotnet new mvc --auth Individual
|
||||
```
|
||||
|
||||
> **Note**: If running in Docker Desktop for Windows, make sure to use Powershell
|
||||
or specify the absolute path of your app directory.
|
||||
|
||||
3. Create a `Dockerfile` within your app directory and add the following content:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM microsoft/dotnet:2.1-sdk
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
RUN ["dotnet", "restore"]
|
||||
RUN ["dotnet", "build"]
|
||||
EXPOSE 80/tcp
|
||||
RUN chmod +x ./entrypoint.sh
|
||||
CMD /bin/bash ./entrypoint.sh
|
||||
```
|
||||
|
||||
This file defines how to build the web app image. It uses the
|
||||
[.NET Core SDK image](https://hub.docker.com/_/microsoft-dotnet-core-sdk),
|
||||
maps the volume with the generated code, restores the dependencies, builds the
|
||||
project and exposes port 80. After that, it calls an `entrypoint` script
|
||||
that we create in the next step.
|
||||
|
||||
4. The `Dockerfile` makes use of an entrypoint to your webapp Docker
|
||||
image. Create this script in a file called `entrypoint.sh` and paste the
|
||||
contents below.
|
||||
|
||||
> **Note**: Make sure to use UNIX line delimiters. The script doesn't work if
|
||||
> you use Windows-based delimiters (Carriage return and line feed).
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
run_cmd="dotnet run --server.urls http://*:80"
|
||||
|
||||
until dotnet ef database update; do
|
||||
>&2 echo "SQL Server is starting up"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
>&2 echo "SQL Server is up - executing command"
|
||||
exec $run_cmd
|
||||
```
|
||||
|
||||
This script restores the database after it starts up, and then runs
|
||||
the application. This allows some time for the SQL Server database image to
|
||||
start up.
|
||||
|
||||
5. Create a `docker-compose.yml` file. Write the following in the file, and
|
||||
make sure to replace the password in the `SA_PASSWORD` environment variable
|
||||
under `db` below. This file defines the way the images interact as
|
||||
independent services.
|
||||
|
||||
> **Note**: The SQL Server container requires a secure password to startup:
|
||||
> Minimum length 8 characters, including uppercase and lowercase letters,
|
||||
> base 10 digits and/or non-alphanumeric symbols.
|
||||
|
||||
```yaml
|
||||
version: "{{ site.compose_file_v3 }}"
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "8000:80"
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: "mcr.microsoft.com/mssql/server"
|
||||
environment:
|
||||
SA_PASSWORD: "Your_password123"
|
||||
ACCEPT_EULA: "Y"
|
||||
```
|
||||
|
||||
This file defines the `web` and `db` micro-services, their relationship, the
|
||||
ports they are using, and their specific environment variables.
|
||||
|
||||
> **Note**: You may receive an error if you choose the wrong Compose file
|
||||
> version. Be sure to choose a version that is compatible with your system.
|
||||
|
||||
6. Go to `Startup.cs` and locate the function called `ConfigureServices` (Hint:
|
||||
it should be under line 42). Replace the entire function to use the following
|
||||
code (watch out for the brackets!).
|
||||
|
||||
> **Note**: Make sure to update the `Password` field in the `connection`
|
||||
> variable below to the one you defined in the `docker-compose.yml` file.
|
||||
|
||||
```csharp
|
||||
<...>
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// Database connection string.
|
||||
// Make sure to update the Password value below from "Your_password123" to your actual password.
|
||||
var connection = @"Server=db;Database=master;User=sa;Password=Your_password123;";
|
||||
|
||||
// This line uses 'UseSqlServer' in the 'options' parameter
|
||||
// with the connection string defined above.
|
||||
services.AddDbContext<ApplicationDbContext>(
|
||||
options => options.UseSqlServer(connection));
|
||||
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.AddMvc();
|
||||
|
||||
// Add application services.
|
||||
services.AddTransient<IEmailSender, AuthMessageSender>();
|
||||
services.AddTransient<ISmsSender, AuthMessageSender>();
|
||||
}
|
||||
<...>
|
||||
```
|
||||
|
||||
7. Go to `app.csproj`. You see a line like:
|
||||
|
||||
```
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.2" />
|
||||
```
|
||||
|
||||
The generated project uses sqlite by default. To use SQL Server, add this line to
|
||||
`app.csproj`:
|
||||
|
||||
```
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.2" />
|
||||
```
|
||||
|
||||
The Sqlite dependency was at version 1.1.2 at the time of this writing. Use the same
|
||||
version for the SQL Server dependency.
|
||||
|
||||
8. Ready! You can now run the `docker-compose build` command.
|
||||
|
||||
```console
|
||||
$ docker-compose build
|
||||
```
|
||||
|
||||
9. Make sure you allocate at least 2GB of memory to Docker Engine. Here is how
|
||||
to do it on
|
||||
[Docker Desktop for Mac](../desktop/settings/mac.md#advanced) and
|
||||
[Docker Desktop for Windows](../desktop/settings/windows.md#advanced).
|
||||
This is necessary to run the SQL Server on Linux container.
|
||||
|
||||
10. Run the `docker-compose up` command. After a few seconds, you should be able
|
||||
to open [localhost:8000](http://localhost:8000) and see the ASP.NET core
|
||||
sample website. The application is listening on port 80 by default, but we
|
||||
mapped it to port 8000 in the `docker-compose.yml`.
|
||||
|
||||
```console
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
Go ahead and try out the website! This sample uses the SQL Server
|
||||
database image in the back-end for authentication.
|
||||
|
||||
Ready! You now have an ASP.NET Core application running against SQL Server in
|
||||
Docker Compose! This sample made use of some of the most popular Microsoft
|
||||
products for Linux. To learn more about Windows Containers, check out
|
||||
[Docker Labs for Windows Containers](https://github.com/docker/labs/tree/master/windows)
|
||||
to try out .NET Framework and more SQL Server tutorials.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Build your app using SQL Server](https://www.microsoft.com/en-us/sql-server/developer-get-started/?utm_medium=Referral&utm_source=docs.docker.com)
|
||||
- [SQL Server on Docker Hub](https://hub.docker.com/r/microsoft/mssql-server/)
|
||||
- [ASP.NET Core](https://www.asp.net/core)
|
||||
- [ASP.NET Core Docker image](https://hub.docker.com/r/microsoft/aspnetcore/) on DockerHub
|
||||
|
||||
## More Compose documentation
|
||||
|
||||
- [Docker Compose overview](../compose/index.md)
|
||||
- [Install Docker Compose](../compose/install/index.md)
|
||||
- [Getting Started with Docker Compose](../compose/gettingstarted.md)
|
||||
- [Docker Compose Command line reference](../compose/reference/index.md)
|
||||
- [Compose file reference](../compose/compose-file/index.md)
|
||||
- [Awesome Compose samples](https://github.com/docker/awesome-compose/){:target="_blank" rel="noopener" class="_"}
|
Binary file not shown.
Before Width: | Height: | Size: 143 KiB |
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
description: Sharing data between 2 couchdb databases
|
||||
keywords: docker, example, package installation, networking, couchdb, data volumes
|
||||
title: Dockerize a CouchDB service
|
||||
redirect_from:
|
||||
- /engine/examples/couchdb_data_volumes/
|
||||
---
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> **If you don't like sudo** then see [*Giving non-root access*](../engine/install/linux-postinstall.md#manage-docker-as-a-non-root-user)
|
||||
|
||||
Here's an example of using data volumes to share the same data between
|
||||
two CouchDB containers. This could be used for hot upgrades, testing
|
||||
different versions of CouchDB on the same data, etc.
|
||||
|
||||
## Create first database
|
||||
|
||||
We're marking `/var/lib/couchdb` as a data volume.
|
||||
|
||||
```console
|
||||
$ COUCH1=$(docker run -d -p 5984 -v /var/lib/couchdb shykes/couchdb:2013-05-03)
|
||||
```
|
||||
|
||||
## Add data to the first database
|
||||
|
||||
We're assuming your Docker host is reachable at `localhost`. If not,
|
||||
replace `localhost` with the public IP of your Docker host.
|
||||
|
||||
```console
|
||||
$ HOST=localhost
|
||||
$ URL="http://$HOST:$(docker port $COUCH1 5984 | grep -o '[1-9][0-9]*$')/_utils/"
|
||||
$ echo "Navigate to $URL in your browser, and use the couch interface to add data"
|
||||
```
|
||||
|
||||
## Create second database
|
||||
|
||||
This time, we're requesting shared access to `$COUCH1`'s volumes.
|
||||
|
||||
```console
|
||||
$ COUCH2=$(docker run -d -p 5984 --volumes-from $COUCH1 shykes/couchdb:2013-05-03)
|
||||
```
|
||||
|
||||
## Browse data on the second database
|
||||
|
||||
```console
|
||||
$ HOST=localhost
|
||||
$ URL="http://$HOST:$(docker port $COUCH2 5984 | grep -o '[1-9][0-9]*$')/_utils/"
|
||||
$ echo "Navigate to $URL in your browser. You should see the same data as in the first database"'!'
|
||||
```
|
||||
|
||||
Congratulations, you are now running two Couchdb containers, completely
|
||||
isolated from each other *except* for their data.
|
|
@ -2,6 +2,10 @@
|
|||
title: .NET samples
|
||||
description: Docker samples for .NET.
|
||||
service: .net
|
||||
redirect_from:
|
||||
- /samples/dotnetcore/
|
||||
- /compose/aspnet-mssql-compose/
|
||||
- /samples/aspnet-mssql-compose/
|
||||
---
|
||||
|
||||
{% include_relative samples-body.md %}
|
|
@ -1,130 +0,0 @@
|
|||
---
|
||||
description: Create a Docker image by layering your ASP.NET Core app on debian for Linux Containers or with Windows Nano Server containers using a Dockerfile.
|
||||
keywords: dockerize, dockerizing, dotnet, .NET, Core, article, example, platform, installation, containers, images, image, dockerfile, build, asp.net, asp.net core
|
||||
title: Dockerize an ASP.NET Core application
|
||||
redirect_from:
|
||||
- /engine/examples/dotnetcore/
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
This example demonstrates how to dockerize an ASP.NET Core application.
|
||||
|
||||
## Why build ASP.NET Core?
|
||||
|
||||
- [Open-source](https://github.com/aspnet/home)
|
||||
- Develop and run your ASP.NET Core apps cross-platform on Windows, MacOS, and
|
||||
Linux
|
||||
- Great for modern cloud-based apps, such as web apps, IoT apps, and mobile
|
||||
backends
|
||||
- Designed to provide an optimized development framework for apps that are
|
||||
deployed to the cloud or run on-premises
|
||||
- Modular components with minimal overhead retain flexibility while
|
||||
constructing your solutions
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This example assumes you already have an ASP.NET Core app
|
||||
on your machine. If you are new to ASP.NET you can follow a
|
||||
[simple tutorial](https://www.asp.net/get-started) to initialize a project or
|
||||
clone our [ASP.NET Docker Sample](https://github.com/dotnet/dotnet-docker/tree/master/samples/aspnetapp).
|
||||
|
||||
## Create a Dockerfile for an ASP.NET Core application
|
||||
|
||||
### Method 1:
|
||||
|
||||
1. Create a `Dockerfile` in your project folder.
|
||||
2. Add the text below to your `Dockerfile` for either Linux or
|
||||
[Windows Containers](https://docs.microsoft.com/virtualization/windowscontainers/about/).
|
||||
The tags below are multi-arch meaning they pull either Windows or
|
||||
Linux containers depending on what mode is set in
|
||||
Docker Desktop for Windows. Read more on
|
||||
[switching containers](../desktop/faqs/windowsfaqs.md#how-do-i-switch-between-windows-and-linux-containers).
|
||||
3. The `Dockerfile` assumes that your application is called `aspnetapp`. Change
|
||||
the `Dockerfile` to use the DLL file of your project.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
|
||||
WORKDIR /app
|
||||
|
||||
# Copy csproj and restore as distinct layers
|
||||
COPY *.csproj ./
|
||||
RUN dotnet restore
|
||||
|
||||
# Copy everything else and build
|
||||
COPY ../engine/examples ./
|
||||
RUN dotnet publish -c Release -o out
|
||||
|
||||
# Build runtime image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0
|
||||
WORKDIR /app
|
||||
COPY --from=build-env /app/out .
|
||||
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
|
||||
```
|
||||
|
||||
4. To make your [build context](../build/building/context.md) as small as
|
||||
possible add a [`.dockerignore` file](../engine/reference/builder.md#dockerignore-file)
|
||||
to your project folder and copy the following into it.
|
||||
|
||||
```dockerignore
|
||||
bin/
|
||||
obj/
|
||||
```
|
||||
|
||||
### Method 2 (build app outside Docker container):
|
||||
|
||||
1. Create a `Dockerfile` in your project folder.
|
||||
2. Add the text below to your `Dockerfile` for either Linux or
|
||||
[Windows Containers](https://docs.microsoft.com/virtualization/windowscontainers/about/).
|
||||
The tags below are multi-arch meaning they pull either Windows or
|
||||
Linux containers depending on what mode is set in
|
||||
Docker Desktop for Windows. Read more on
|
||||
[switching containers](../desktop/faqs/windowsfaqs.md#how-do-i-switch-between-windows-and-linux-containers).
|
||||
3. The `Dockerfile` assumes that your application is called `aspnetapp`. Change the `Dockerfile` to use the DLL file of your project. This method assumes that your project is already built and it copies the build artifacts from the publish folder. Refer to the Microsoft documentation on [Containerize a .Net Core app](https://docs.microsoft.com/en-us/dotnet/core/docker/build-container?tabs=windows#create-the-dockerfile){: target="blank" rel="noopener" class=“"}.
|
||||
|
||||
The `docker build` step here will be much faster than method 1, as all the artifacts are built outside of the `docker build` step and the size of the base image is much smaller compared to the build base image.
|
||||
|
||||
This method is preferred for CI tools like Jenkins, Azure DevOps, GitLab CI, etc. as you can use the same artifacts in multiple deployment models if Docker isn't the only deployment model being used. Additionally, you'll be able to run unit tests and publish code coverage reports, or use custom plugins on the artifacts built by the CI.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:5.0
|
||||
COPY bin/Release/netcoreapp3.1/publish/ App/
|
||||
WORKDIR /App
|
||||
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
|
||||
```
|
||||
|
||||
4. To make your [build context](../build/building/context.md) as small as
|
||||
possible add a [`.dockerignore`file](../engine/reference/builder.md#dockerignore-file)
|
||||
to your project folder.
|
||||
|
||||
## Build and run the Docker image
|
||||
|
||||
1. Open a command prompt and navigate to your project folder.
|
||||
2. Use the following commands to build and run your Docker image:
|
||||
|
||||
```console
|
||||
$ docker build -t aspnetapp .
|
||||
$ docker run -d -p 8080:80 --name myapp aspnetapp
|
||||
```
|
||||
|
||||
## View the web page running from a container
|
||||
|
||||
* Go to [localhost:8080](http://localhost:8080) to access your app in a web browser.
|
||||
* If you are using the Nano Windows Container
|
||||
and have not updated to the Windows Creator Update there is a bug affecting how
|
||||
[Windows 10 talks to Containers via "NAT"](https://github.com/Microsoft/Virtualization-Documentation/issues/181#issuecomment-252671828)
|
||||
(Network Address Translation). You must hit the IP of the container
|
||||
directly. You can get the IP address of your container with the following
|
||||
steps:
|
||||
1. Run `docker inspect -f "{% raw %}{{ .NetworkSettings.Networks.nat.IPAddress }}{% endraw %}" myapp`
|
||||
2. Copy the container IP address and paste into your browser.
|
||||
(For example, `172.16.240.197`)
|
||||
|
||||
## Further reading
|
||||
|
||||
- [ASP.NET Core](https://docs.microsoft.com/aspnet/core/)
|
||||
- [Microsoft ASP.NET Core on Docker Hub](https://hub.docker.com/_/microsoft-dotnet-sdk/)
|
||||
- [Building Docker Images for ASP.NET Core](https://docs.microsoft.com/aspnet/core/host-and-deploy/docker/building-net-docker-images)
|
||||
- [Docker Tools for Visual Studio](https://docs.microsoft.com/dotnet/articles/core/docker/visual-studio-tools-for-docker)
|
|
@ -5,6 +5,8 @@ redirect_from:
|
|||
- /en/latest/examples/
|
||||
- /engine/examples/
|
||||
- /examples/
|
||||
- /samples/runnning_riak_service/
|
||||
- /samples/apt-cacher-ng/
|
||||
---
|
||||
|
||||
Learn how to containerize different types of services by walking through Official Docker samples.
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
title: PostgreSQL samples
|
||||
description: Docker samples for PostgreSQL.
|
||||
service: postgresql
|
||||
redirect_from:
|
||||
- /engine/examples/postgresql_service/
|
||||
- /samples/postgresql_service/
|
||||
---
|
||||
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
#
|
||||
# example Dockerfile for https://docs.docker.com/examples/postgresql_service/
|
||||
#
|
||||
|
||||
FROM ubuntu
|
||||
|
||||
# Add the PostgreSQL PGP key to verify their Debian packages.
|
||||
# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
||||
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
|
||||
|
||||
# Add PostgreSQL's repository. It contains the most recent stable release
|
||||
# of PostgreSQL, ``9.3``.
|
||||
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
|
||||
# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
|
||||
# There are some warnings (in red) that show up during the build. You can hide
|
||||
# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
|
||||
|
||||
# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
|
||||
# after each ``apt-get``
|
||||
|
||||
# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
|
||||
USER postgres
|
||||
|
||||
# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and
|
||||
# then create a database `docker` owned by the ``docker`` role.
|
||||
# Note: here we use ``&&\`` to run commands one after the other - the ``\``
|
||||
# allows the RUN command to span multiple lines.
|
||||
RUN /etc/init.d/postgresql start &&\
|
||||
psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
|
||||
createdb -O docker docker
|
||||
|
||||
# Adjust PostgreSQL configuration so that remote connections to the
|
||||
# database are possible.
|
||||
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
|
||||
|
||||
# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
|
||||
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
|
||||
|
||||
# Expose the PostgreSQL port
|
||||
EXPOSE 5432
|
||||
|
||||
# Add VOLUMEs to allow backup of config, logs and databases
|
||||
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
|
||||
|
||||
# Set the default command to run when starting the container
|
||||
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
|
|
@ -1,156 +0,0 @@
|
|||
---
|
||||
description: Running and installing a PostgreSQL service
|
||||
keywords: docker, example, package installation, postgresql
|
||||
title: Dockerize PostgreSQL
|
||||
redirect_from:
|
||||
- /engine/examples/postgresql_service/
|
||||
---
|
||||
|
||||
## Install PostgreSQL on Docker
|
||||
|
||||
Assuming there is no Docker image that suits your needs on the [Docker
|
||||
Hub](https://hub.docker.com), you can create one yourself.
|
||||
|
||||
Start by creating a new `Dockerfile`:
|
||||
|
||||
> **Note**:
|
||||
This PostgreSQL setup is for development-only purposes. Refer to the
|
||||
PostgreSQL documentation to fine-tune these settings so that it is
|
||||
suitably secure.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:16.04
|
||||
|
||||
# Add the PostgreSQL PGP key to verify their Debian packages.
|
||||
# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
||||
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
|
||||
|
||||
# Add PostgreSQL's repository. It contains the most recent stable release
|
||||
# of PostgreSQL.
|
||||
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
|
||||
# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
|
||||
# There are some warnings (in red) that show up during the build. You can hide
|
||||
# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
|
||||
|
||||
# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
|
||||
# after each ``apt-get``
|
||||
|
||||
# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
|
||||
USER postgres
|
||||
|
||||
# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and
|
||||
# then create a database `docker` owned by the ``docker`` role.
|
||||
# Note: here we use ``&&\`` to run commands one after the other - the ``\``
|
||||
# allows the RUN command to span multiple lines.
|
||||
RUN /etc/init.d/postgresql start &&\
|
||||
psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
|
||||
createdb -O docker docker
|
||||
|
||||
# Adjust PostgreSQL configuration so that remote connections to the
|
||||
# database are possible.
|
||||
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
|
||||
|
||||
# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
|
||||
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
|
||||
|
||||
# Expose the PostgreSQL port
|
||||
EXPOSE 5432
|
||||
|
||||
# Add VOLUMEs to allow backup of config, logs and databases
|
||||
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
|
||||
|
||||
# Set the default command to run when starting the container
|
||||
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
|
||||
```
|
||||
|
||||
Build an image from the Dockerfile and assign it a name.
|
||||
|
||||
```console
|
||||
$ docker build -t eg_postgresql .
|
||||
```
|
||||
|
||||
Run the PostgreSQL server container (in the foreground):
|
||||
|
||||
```console
|
||||
$ docker run --rm -P --name pg_test eg_postgresql
|
||||
```
|
||||
|
||||
There are two ways to connect to the PostgreSQL server. We can use
|
||||
[*Link Containers*](../network/links.md),
|
||||
or we can access it from our host (or the network).
|
||||
|
||||
> **Note**: The `--rm` removes the container and its image when
|
||||
the container exits successfully.
|
||||
|
||||
### Use container linking
|
||||
|
||||
Containers can be linked to another container's ports directly using
|
||||
`--link remote_name:local_alias` in the client's
|
||||
`docker run`. This sets a number of environment
|
||||
variables that can then be used to connect:
|
||||
|
||||
```console
|
||||
$ docker run --rm -t -i --link pg_test:pg eg_postgresql bash
|
||||
|
||||
postgres@7ef98b1b7243:/$ psql -h $PG_PORT_5432_TCP_ADDR -p $PG_PORT_5432_TCP_PORT -d docker -U docker --password
|
||||
```
|
||||
|
||||
### Connect from your host system
|
||||
|
||||
Assuming you have the postgresql-client installed, you can use the
|
||||
host-mapped port to test as well. You need to use `docker ps`
|
||||
to find out what local host port the container is mapped to
|
||||
first:
|
||||
|
||||
```console
|
||||
$ docker ps
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
5e24362f27f6 eg_postgresql:latest /usr/lib/postgresql/ About an hour ago Up About an hour 0.0.0.0:49153->5432/tcp pg_test
|
||||
|
||||
$ psql -h localhost -p 49153 -d docker -U docker --password
|
||||
```
|
||||
|
||||
### Test the database
|
||||
|
||||
Once you have authenticated and have a `docker =#`
|
||||
prompt, you can create a table and populate it.
|
||||
|
||||
```sql
|
||||
psql (9.3.1)
|
||||
Type "help" for help.
|
||||
|
||||
$ docker=# CREATE TABLE cities (
|
||||
docker(# name varchar(80),
|
||||
docker(# location point
|
||||
docker(# );
|
||||
CREATE TABLE
|
||||
$ docker=# INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
|
||||
INSERT 0 1
|
||||
$ docker=# select * from cities;
|
||||
name | location
|
||||
---------------+-----------
|
||||
San Francisco | (-194,53)
|
||||
(1 row)
|
||||
```
|
||||
|
||||
### Use the container volumes
|
||||
|
||||
You can use the defined volumes to inspect the PostgreSQL log files and
|
||||
to backup your configuration and data:
|
||||
|
||||
```console
|
||||
$ docker run --rm --volumes-from pg_test -t -i busybox sh
|
||||
|
||||
/ # ls
|
||||
bin etc lib linuxrc mnt proc run sys usr
|
||||
dev home lib64 media opt root sbin tmp var
|
||||
/ # ls /etc/postgresql/9.3/main/
|
||||
environment pg_hba.conf postgresql.conf
|
||||
pg_ctl.conf pg_ident.conf start.conf
|
||||
/tmp # ls /var/log
|
||||
ldconfig postgresql
|
||||
```
|
|
@ -1,30 +0,0 @@
|
|||
# Riak
|
||||
#
|
||||
# VERSION 0.1.1
|
||||
|
||||
# Use the Ubuntu parent image provided by dotCloud
|
||||
FROM ubuntu:trusty
|
||||
|
||||
# Install Riak repository before we do apt-get update, so that update happens
|
||||
# in a single step
|
||||
RUN apt-get install -q -y curl && \
|
||||
curl -fsSL https://packagecloud.io/install/repositories/basho/riak/script.deb | sudo bash
|
||||
|
||||
# Install and setup project dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y supervisor riak=2.0.5-1
|
||||
|
||||
RUN mkdir -p /var/log/supervisor
|
||||
|
||||
RUN locale-gen en_US en_US.UTF-8
|
||||
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
# Configure Riak to accept connections from any host
|
||||
RUN sed -i "s|listener.http.internal = 127.0.0.1:8098|listener.http.internal = 0.0.0.0:8098|" /etc/riak/riak.conf
|
||||
RUN sed -i "s|listener.protobuf.internal = 127.0.0.1:8087|listener.protobuf.internal = 0.0.0.0:8087|" /etc/riak/riak.conf
|
||||
|
||||
# Expose Riak Protocol Buffers and HTTP interfaces
|
||||
EXPOSE 8087 8098
|
||||
|
||||
CMD ["/usr/bin/supervisord"]
|
|
@ -1,122 +0,0 @@
|
|||
---
|
||||
description: Build a Docker image with Riak pre-installed
|
||||
keywords: docker, example, package installation, networking, riak
|
||||
title: Dockerize a Riak service
|
||||
redirect_from:
|
||||
- /engine/examples/running_riak_service/
|
||||
---
|
||||
|
||||
The goal of this example is to show you how to build a Docker image with
|
||||
Riak pre-installed.
|
||||
|
||||
## Create a Dockerfile
|
||||
|
||||
Create an empty file called `Dockerfile`:
|
||||
|
||||
```console
|
||||
$ touch Dockerfile
|
||||
```
|
||||
|
||||
Next, define the parent image you want to use to build your image on top
|
||||
of. We use [Ubuntu](https://hub.docker.com/_/ubuntu/) (tag:
|
||||
`trusty`), which is available on [Docker Hub](https://hub.docker.com):
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
# Riak
|
||||
#
|
||||
# VERSION 0.1.1
|
||||
|
||||
# Use the Ubuntu parent image provided by dotCloud
|
||||
FROM ubuntu:trusty
|
||||
```
|
||||
|
||||
After that, we install the curl which is used to download the repository setup
|
||||
script and we download the setup script and run it.
|
||||
|
||||
```dockerfile
|
||||
# Install Riak repository before we do apt-get update, so that update happens
|
||||
# in a single step
|
||||
RUN apt-get install -q -y curl && \
|
||||
curl -fsSL https://packagecloud.io/install/repositories/basho/riak/script.deb | sudo bash
|
||||
```
|
||||
|
||||
Then we install and setup a few dependencies:
|
||||
|
||||
- `supervisor` is used manage the Riak processes
|
||||
- `riak=2.0.5-1` is the Riak package coded to version 2.0.5
|
||||
|
||||
```dockerfile
|
||||
# Install and setup project dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y supervisor riak=2.0.5-1
|
||||
|
||||
RUN mkdir -p /var/log/supervisor
|
||||
|
||||
RUN locale-gen en_US en_US.UTF-8
|
||||
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
```
|
||||
|
||||
After that, we modify Riak's configuration:
|
||||
|
||||
```dockerfile
|
||||
# Configure Riak to accept connections from any host
|
||||
RUN sed -i "s|listener.http.internal = 127.0.0.1:8098|listener.http.internal = 0.0.0.0:8098|" /etc/riak/riak.conf
|
||||
RUN sed -i "s|listener.protobuf.internal = 127.0.0.1:8087|listener.protobuf.internal = 0.0.0.0:8087|" /etc/riak/riak.conf
|
||||
```
|
||||
|
||||
Then, we expose the Riak Protocol Buffers and HTTP interfaces:
|
||||
|
||||
```dockerfile
|
||||
# Expose Riak Protocol Buffers and HTTP interfaces
|
||||
EXPOSE 8087 8098
|
||||
```
|
||||
|
||||
Finally, run `supervisord` so that Riak is started:
|
||||
|
||||
```dockerfile
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
|
||||
## Create a supervisord configuration file
|
||||
|
||||
Create an empty file called `supervisord.conf`. Make
|
||||
sure it's at the same directory level as your `Dockerfile`:
|
||||
|
||||
```console
|
||||
$ touch supervisord.conf
|
||||
```
|
||||
|
||||
Populate it with the following program definitions:
|
||||
|
||||
```ini
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:riak]
|
||||
command=bash -c "/usr/sbin/riak console"
|
||||
numprocs=1
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=riak
|
||||
environment=HOME="/var/lib/riak"
|
||||
stdout_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
stderr_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
```
|
||||
|
||||
## Build the Docker image for Riak
|
||||
|
||||
Now you can build a Docker image for Riak:
|
||||
|
||||
```console
|
||||
$ docker build -t "<yourname>/riak" .
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
Riak is a distributed database. Many production deployments consist of
|
||||
[at least five nodes](
|
||||
https://riak.com/why-your-riak-cluster-should-have-at-least-five-nodes/).
|
||||
See the [docker-riak](https://github.com/hectcastro/docker-riak) project
|
||||
details on how to deploy a Riak cluster using Docker and Pipework.
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
description: Installing and running an SSHd service on Docker
|
||||
keywords: docker, example, package installation, networking
|
||||
title: Dockerize an SSH service
|
||||
redirect_from:
|
||||
- /engine/examples/running_ssh_service/
|
||||
---
|
||||
|
||||
Running sshd inside a container is discouraged, however, it might be still useful
|
||||
for certain use cases such as port forwarding.
|
||||
|
||||
See [https://github.com/linuxserver/docker-openssh-server](https://github.com/linuxserver/docker-openssh-server)
|
||||
for an example of Dockerized SSH service.
|
|
@ -1,12 +0,0 @@
|
|||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:riak]
|
||||
command=bash -c "/usr/sbin/riak console"
|
||||
numprocs=1
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=riak
|
||||
environment=HOME="/var/lib/riak"
|
||||
stdout_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
stderr_logfile=/var/log/supervisor/%(program_name)s.log
|
Loading…
Reference in New Issue