skip to content
TJ Miller

Linking Vessel Projects Together

/ 3 min read

Vessel is a fantastic project put together by Chris Fidao under the Shipping Docker label. (if you’re looking to get started with Docker you should really check out Shipping Docker) One of the things I love about Vessel is that its tightly focused and will jump-start local Laravel development with Docker in minutes.

I’m not going to go into detail about how to get started with Vessel in this article, go check out the docs.

Diving In

Let’s say we have two Laravel projects that we need to communicate together at a server level. For the purpose of this article, we’ll have a web app that needs to consume a back-end service user account service.

Vessel will generate a docker-compose.yml file that looks like:

version: '2'
services:
app:
build:
context: ./docker/app
dockerfile: Dockerfile
image: vessel/app
ports:
- "${APP_PORT}:80"
environment:
CONTAINER_ENV: "${APP_ENV}"
XDEBUG_HOST: "${XDEBUG_HOST}"
WWWUSER: "${WWWUSER}"
volumes:
- .:/var/www/html
networks:
- vessel
node:
build:
context: ./docker/node
dockerfile: Dockerfile
args:
uid: "${WWWUSER}"
image: vessel/node
user: node
volumes:
- .:/var/www/html
networks:
- vessel
mysql:
image: mysql:5.7
ports:
- "${MYSQL_PORT}:3306"
environment:
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
volumes:
- vesselmysql:/var/lib/mysql
# - ./docker/mysql/conf.d:/etc/mysql/conf.d
# - ./docker/mysql/logs:/var/log/mysql
networks:
- vessel
redis:
image: redis:alpine
volumes:
- vesselredis:/data
networks:
- vessel
networks:
vessel:
driver: "bridge"
volumes:
vesselmysql:
driver: "local"
vesselredis:
driver: "local"

In order to link the two projects together, we will need to create a docker network that both projects can use to communicate through.

Now we need to update both projects docker-compose.yml to use the new network.

We will need to add:

  • The superapp network to the list of project networks (line 56,57 note the external: true)
  • The superapp network to the app services (line 19)
  • Add a container_name parameter to the app services (line 4, this will make it much easier to target the service using Dockers internal DNS)

Web App Compose File

version: '2'
services:
app:
container_name: superwebapp
build:
context: ./docker/app
dockerfile: Dockerfile
image: vessel/app
ports:
- "${APP_PORT}:80"
environment:
CONTAINER_ENV: "${APP_ENV}"
XDEBUG_HOST: "${XDEBUG_HOST}"
WWWUSER: "${WWWUSER}"
volumes:
- .:/var/www/html
networks:
- vessel
- superapp
node:
build:
context: ./docker/node
dockerfile: Dockerfile
args:
uid: "${WWWUSER}"
image: vessel/node
user: node
volumes:
- .:/var/www/html
networks:
- vessel
mysql:
image: mysql:5.7
ports:
- "${MYSQL_PORT}:3306"
environment:
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
volumes:
- vesselmysql:/var/lib/mysql
# - ./docker/mysql/conf.d:/etc/mysql/conf.d
# - ./docker/mysql/logs:/var/log/mysql
networks:
- vessel
redis:
image: redis:alpine
volumes:
- vesselredis:/data
networks:
- vessel
networks:
vessel:
driver: "bridge"
superapp:
external: true
volumes:
vesselmysql:
driver: "local"
vesselredis:
driver: "local"

User Account Service Compose File

version: '2'
services:
app:
container_name: superaccountservice
build:
context: ./docker/app
dockerfile: Dockerfile
image: vessel/app
ports:
- "${APP_PORT}:80"
environment:
CONTAINER_ENV: "${APP_ENV}"
XDEBUG_HOST: "${XDEBUG_HOST}"
WWWUSER: "${WWWUSER}"
volumes:
- .:/var/www/html
networks:
- vessel
- superapp
node:
build:
context: ./docker/node
dockerfile: Dockerfile
args:
uid: "${WWWUSER}"
image: vessel/node
user: node
volumes:
- .:/var/www/html
networks:
- vessel
mysql:
image: mysql:5.7
ports:
- "${MYSQL_PORT}:3306"
environment:
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
volumes:
- vesselmysql:/var/lib/mysql
# - ./docker/mysql/conf.d:/etc/mysql/conf.d
# - ./docker/mysql/logs:/var/log/mysql
networks:
- vessel
redis:
image: redis:alpine
volumes:
- vesselredis:/data
networks:
- vessel
networks:
vessel:
driver: "bridge"
superapp:
external: true
volumes:
vesselmysql:
driver: "local"
vesselredis:
driver: "local"

With this configuration, you will be able to target the account service using the value of the container_name field.

For example, you could test this configuration, from your web app project root, by running docker-compose exec app curl superaccountservice you should get a response from the user account service.

I would also recommend adding some sort of environmental configuration option to your .env to make it easy to configure the account services root host e.g. ACCOUNT_SERVICE_HOST=http://superaccountservice. This way you can easily update the host in production vs development.

Big thanks to Chris Fidao for putting the Vessel project together!

Subscribe

For more thoughts, links, project and personal updates.