# Docker To build and deploy your application in a Docker container, you don't need to write a [configuration file](config-file.md) `amverum.yaml` at all. It's enough to write `Dockerfile`. However, for more precise configuration, you may need the `amverum.yaml` file. ![settings](../../img/docker_proc.png) When using a Dockerfile, the image build process is first initialized, running in a separate container with access to the Code folder. Once the build is complete, the image is uploaded to the repository (registry). After the image is successfully uploaded, the application deployment process is initialized, during which a container is created from the previously obtained image. ```{eval-rst} .. admonition:: Important :class: warning docker-compose.yml is not supported. Only classic Dockerfile can be used. ``` ## Configuration file For more precise configuration, you should supplement the Dockerfile with the amverum.yaml configuration file. Using the configuration file allows you to skip the build and run the application using a ready-made public image from a third-party registry. You can also specify the folder for mounting the persistent storage. ### Meta section For the Docker environment, the `meta` section can be omitted altogether. By default, it is assumed to be the following: ``` meta: environment: docker toolchain: name: docker ``` ### Build section The `build` section supports the following parameters: - `dockerfile`: path to the `Dockerfile` file relative to the source code folder (without the leading slash); this is an optional parameter: if you do not specify it, `Dockerfile` will be searched in the following places: - `amverum/Dockerfile` - `Dockerfile` - `docker/Dockerfile` - `deploy/Dockerfile` - `deployment/Dockerfile` - `skip`: skip image building; used when running pre-built Docker images. ### run section The `run` section supports the following options: - `image`: the image to run instead of the built one; usually used in combination with `build.skip: yes`; - `command`: the command to run in the specified image; useful in combination with `run.image`; this is whatever is specified in the Dockerfile's `ENTRYPOINT` or the Kubernetes Pod's `command`, usually the command name without any options; - `args`: the options for the command specified in `run.command`; this is whatever is specified in the Dockerfile's `CMD` or the Kubernetes Pod's `args`, except that the options are specified as a regular string rather than an array; - `persistenceMount`: absolute path in the container filesystem where the [persistent storage folder](../storage.md#data) should be mounted; defaults to `/data` - `containerPort`: TCP port number that the application in the container listens to; defaults to `80`. ## Recipes ### Custom application with non-standard port If your application works over HTTP protocol, but uses a port number other than 80, you can configure it with the following `amverum.yml` file: ```yaml run: containerPort: 3000 ``` ### Custom application with non-standard Dockerfile location Let's say the Dockerfile is located at `myapp/amverum.dockerfile`: ```yaml build: dockerfile: myapp/amverum.dockerfile ``` ### Ready-made Docker image If you need to run a ready-made Docker image that either runs over HTTP or does not accept incoming connections (for example, a bot), you can skip the build phase and specify the image name directly. As an example, consider deploying Dokuwiki ([https://hub.docker.com/r/linuxserver/dokuwiki](https://hub.docker.com/r/linuxserver/dokuwiki)). Dokuwiki listens on port 80, so we do not need to change this setting. But the data folder needs to be mounted at the `/config` path. The following `amverum.yml` file is obtained: ```yaml build: skip: yes run: image: lscr.io/linuxserver/dokuwiki:latest persistenceMount: /config ``` Since you don't need anything other than the `amverum.yml` file, this is the only file you need to push to the git repository created for the project. ### Application with a non-standard ENTRYPOINT If you have written an application and have not specified either `ENTRYPOINT` or `CMD` in the `Dockerfile`, or you are using a ready-made image and want to use a different application from it than the one intended by the developer, the `run.command` and `run.args` parameters will come in handy. As an example, consider an application in the Go language: ```go package main import ( "fmt" "net/http" "os" ) func main() { var port string if (len(os.Args) > 2) && (os.Args[1] == "--port") { port = fmt.Sprintf(":%v", os.Args[2]) } else { port = ":80" } http.HandleFunc("/", HelloServer) http.ListenAndServe(port, nil) } func HelloServer(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:]) } ``` `Dockerfile` for him: ```dockerfile FROM golang:1.19 WORKDIR /app COPY server.go go.mod ./ RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o server FROM alpine:latest WORKDIR /app COPY --from=0 /app/server ./ ``` To start the server, you need to call the command `/app/server --port 8080`, but for some reason this is not written in the `Dockerfile`. Let's specify the launch parameters in `amverum.yml`: ```yaml run: command: /app/server args: --port 8080 containerPort: 8080 ```