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.