Broader Frontends
Author : Kazuhiro Hara
Article permalink

About the Docker Files Included with a New Vapor Project

In the Vapor talk I gave at visionOS Study Group #7, I mentioned that when you generate a project, docker-compose.yml and Dockerfile come with it. This is a follow-up on that topic.

By the way, the previous article includes the presentation materials themselves, so please take a look if you are interested.

Now, this time I will talk about Docker around Vapor.

Starting a container for a Vapor app in a local Docker environment is very easy.

First, create the Docker image. A Vapor app is built and then executed even when launched locally, but the Docker container seems to run on an Ubuntu-based environment. Therefore, it needs to be built on Ubuntu. So when starting it, the first step is to build the image. Run the following.

$ docker compose build

The project also includes a .dockerignore file with the following contents, so files built on the Mac are excluded when building the container. This also includes Swift Package files.

.build/
.swiftpm/

Once the Docker image has been created, start the service and you are done.

$ docker compose up

Looking at docker-compose.yml, only an application named app is defined. If you want to customize and build your own application in various ways, I think this is a good place to start.

version: '3.7'

x-shared_environment: &shared_environment
  LOG_LEVEL: ${LOG_LEVEL:-debug}

services:
  app:
    image: websocket-1:latest
    build:
      context: .
    environment:
      <<: *shared_environment
    ports:
      - '8080:8080'
    # user: '0' # uncomment to run as root for testing purposes even though Dockerfile defines 'vapor' user.
    command: ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]

However, if you try to build a web application that integrates with a database using Fluent, meaning you choose to use Fluent during project creation and select an RDB of your choice, a docker-compose.yml like the following is generated. It includes a database volume named db_data and database-related services.

version: '3.7'

volumes:
  db_data:

x-shared_environment: &shared_environment
  LOG_LEVEL: ${LOG_LEVEL:-debug}
  DATABASE_HOST: db
  DATABASE_NAME: vapor_database
  DATABASE_USERNAME: vapor_username
  DATABASE_PASSWORD: vapor_password

services:
  app:
    image: hello-db:latest
    build:
      context: .
    environment:
      <<: *shared_environment
    depends_on:
      - db
    ports:
      - '8080:8080'
    # user: '0' # uncomment to run as root for testing purposes even though Dockerfile defines 'vapor' user.
    command: ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]
  migrate:
    image: hello-db:latest
    build:
      context: .
    environment:
      <<: *shared_environment
    depends_on:
      - db
    command: ["migrate", "--yes"]
    deploy:
      replicas: 0
  revert:
    image: hello-db:latest
    build:
      context: .
    environment:
      <<: *shared_environment
    depends_on:
      - db
    command: ["migrate", "--revert", "--yes"]
    deploy:
      replicas: 0
  db:
    image: mysql:8
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_USER: vapor_username
      MYSQL_PASSWORD: vapor_password
      MYSQL_DATABASE: vapor_database
      MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
    ports:
      - '3306:3306'

When using it yourself, you will probably customize various parts, but having a template prepared is extremely helpful. The Docker-related documentation is below. It also explains the Dockerfile, so it is one of the documents I recommend reading.

DockerSwiftVaporXcode

Share