Deploy a Laravel application to Alibaba Cloud Container Service using Docker

In this tutorial, we will deploy a Laravel application using Docker and Alibaba Cloud Container Service.

Prerequisites

Before you begin this guide you’ll need the following:

Docker installed on your local machine(if you can’t install the latest version you can use Docker Toolbox)
Composer installed on your computer

Preparing the application for the deployment:

First of all, you need a Laravel application that you can Dockerize. You can just copy my example from GitHub and push to your own git repository or you can create a new Laravel app using Composer with this command: composer create-project --prefer-dist laravel/laravel appname

We need to add some files to the root of the Laravel app:

You have to create an environment configuration file for the production environment, let’s call it .env.prod. You can copy your existing .env file, but don’t forget to modify the values(for example, set APP_ENV to production).

We will need a configuration file for the web server as well(we will use Apache), create a vhost.conf file for our virtual host.

<VirtualHost *:80>
  DocumentRoot /app/public

  <Directory "/app/public">
    AllowOverride all
    Require all granted
  </Directory>

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

To build our container we need a Dockerfile, we will use multi-stage build:

#Install the dependencies using composer

FROM composer:1.7 as build

WORKDIR /app

COPY . /app

RUN composer install

COPY .env.prod .env

#Application

FROM php:7.2-apache

RUN docker-php-ext-install mysqli pdo pdo_mysql

EXPOSE 80

COPY --from=build /app /app

COPY vhost.conf /etc/apache2/sites-available/000-default.conf

RUN chown -R www-data:www-data /app \
&& a2enmod rewrite

We also need to exclude some files and folders from the container, so you should create a .dockerignore file(You can extend this list if you want):

.git/
vendor/
node_modules/
yarn-error.log

Creating a repository in Alibaba Cloud Container Registry:

On the Alibaba Cloud Console go to Products > Elastic Computing > Container Registry

First, you need to set the registry login password.

We have to create a namespace, then we can create a repository for the application.

Make sure that you set the repository type to Private otherwise the repository will be accessible without the password. You can select the region of your repository as well.

The Container Registry supports GitHub, GitLab and Bitbucket as a code source which is really useful. If you use one of them you can choose that, but for the simplicity, we will use the Local repository option in this tutorial.

You need to build the container on your local computer and push it to the registry(if you choose a Git hosting service Container Registry will build the containers automatically, so you can skip these steps.)

Run the following command in the root of your Laravel app to build the container(You can replace test/laravel:1.0 tag with your own).

docker build -t test/laravel:1.0 .

If you click on manage at the right of your repository in the Container Registry you can find the address of your repository and a guide about how to log in to the registry and push an image to the repository.

So you have to run the following commands, but with your own region, namespace and repository:

docker login --username=user@example.com registry-intl.eu-central-1.aliyuncs.com
docker tag test/laravel:1.0 registry-intl.eu-central-1.aliyuncs.com/ma_test/laravel1:1.0
docker push registry-intl.eu-central-1.aliyuncs.com/ma_test/laravel1:1.0

When you successfully pushed the image, you will see it under the Tags tab.

Creating a VPC:

On the Alibaba Cloud Console go to Products > Networking > Virtual Private Cloud and activate VPC.

Choose your region from the top menu and create a VPC and a VSwitch.

Creating a cluster:

First you need to enable RAM(Products > Monitor and Management > Resource Access Management), then you can go to Products > Elastic Computing > Container Service.

Container Service supports both Swarm and Kubernetes, now we will use Swarm, so you should select Swarm from the left menu.

swarm

Click on Create Cluster button and configure your cluster(Don’t forget to select the same region that you selected for your VPC.).


I choose 2x(2 nodes) 1 Core 1GB ECS instances for the demo, but you can choose a different configuration if you want.

In the Login section, you need to create SSH keys or set a password. I highly recommend SSH keys, but for the simplicity, you can use passwords for now.

When you have finished with the configuration you can click on the Create button(A confirm dialog will show up with pricing information).

When the cluster creation finished you can see your cluster in the cluster list, click on Manage.

You need to log in to your private repository to access the images, so click on the Log on to Hub button. If you don’t know what is the repository’s domain name you should go to the Container Registry control panel click on Manage at the right of your repository and copy the VPC address(for example: registry-intl-vpc.eu-central-1.aliyuncs.com/ma_test/laravel1) that is your Repository Domain Name. Your username and password is the username and password of your registry.

Now the cluster nodes can pull your image from the private repository.

Deploying the application:

On the Container Service control panel click on Applications from the left menu, then click on Create Application.

Set the name and the version, check Pull Docker Image(This will ensure that you definitely end up with the latest version) then click on Create with Image button.

Select your image(in the popup you can find your images under the User tab) and a version. In the Network section, under Web Routing, click on the blue plus symbol. For the container port, type 80. For the Domain type what you would it to be called. You can set the number of instances(Scale) as well.

Click create then click on View Application List. Under Applications, you should see your new container. Click on the container, in the services tab click on the name of the container again. You will now see some information about your container. Click on the Access Endpoint URL and you will see your Laravel app’s homepage.

endpoint

Connecting the application to MySQL and Redis:

We will need an SQL database and a session database(we will use Redis), so we have to set up these services and configure the connections.

Go to Products > ApsaraDB > ApsaraDB for Redis. From the top menu select the region where your VPC is. Create an instance that fit your needs(You can use a 4G Master-Slave instance free for one month). After your instance created and you can see it in the instance list click on manage. From the left menu select Whitelist settings and modify the default value to 0.0.0.0/0 to allow connections from all machines in the VPC or you can add the private IP/IP range of your ECS instances.

From the left menu select Instance information and copy Connection Address. On your local machine open the .env.prod file and set the host and the password for Redis.

Similarly to this:

REDIS_HOST=r-4xoba5b097200b94.redis.germany.rds.aliyuncs.com
REDIS_PASSWORD=my-password
REDIS_PORT=6379

You should set the cache and session drivers to redis:
CACHE_DRIVER=redis
SESSION_DRIVER=redis

Laravel needs a package named predis to interact with Redis.

On your local machine run the following command, this will install predis and add it to the dependency list:

composer require predis/predis

We configured the Redis connection, but before we deploy a new container we will configure the MySQL connection as well.

Go to Products > ApsraraDB > ApsaraDB for RDS. From the top menu select the region where your VPC is. Create an instance that fit your needs(You can use a free instance for one month with 1 Core CPU, 1 GB Memory, 20GB storage).

After your instance created and you can see it in the instance list click on manage. From the left menu choose Security and modify the whitelist similarly as we did it with Redis. You have to create a database account and a database, grant read-write access to the user.

From the left menu select Connection Options and copy the intranet address(host).

On your local machine, you should edit the database connection settings in your .env.prod file.
Similarly to this:

DB_CONNECTION=mysql
DB_HOST=rm-4xo3wjj1wh2nwi7yn.mysql.germany.rds.aliyuncs.com
DB_PORT=3306
DB_DATABASE=laravel1
DB_USERNAME=laravel1
DB_PASSWORD=my-password

Deploying the new version of the application:

Build the container and push it to the registry:

You should run commands similar to these(replace the region, etc.):

docker build -t test/laravel:1.1 .
docker tag test/laravel:1.1 registry-intl.eu-central-1.aliyuncs.com/ma_test/laravel1:1.1
docker push registry-intl.eu-central-1.aliyuncs.com/ma_test/laravel1:1.1

Go to Container Service > Applications, you should see your application in the list, click on Update. Change the value of the version field and in the yaml file(template) change the image. For example replace registry-intl-vpc.eu-central-1.aliyuncs.com/ma_test/laravel1:1.0 with registry-intl-vpc.eu-central-1.aliyuncs.com/ma_test/laravel1:1.1 Click on OK and the container will be replaced with the new one. You can use blue-green release policy as well if you want.

Now your application can connect to Redis and MySQL. If you want to run a database migration you can click on the application, in the services tab click on the name of the application again, select a container and click on Web Terminal. You should run the following commands:

cd /app
php artisan migrate

Note: If you receive a Specified key was too long error when you trying to run the migration you can find a solution here: https://laravel-news.com/laravel-5-4-key-too-long-error

Add your domain name to the cluster:

Go to Applications in the Container Service control panel, click on update at the right of your application. In the yaml file(template) add your domain to aliyun.routing.port_80, you can separate values with semicolons, for example: aliyun.routing.port_80: laravel1;yourdomain.com

domain

Go to the cluster list in the Container Service control panel. Click on manage at the right of the cluster. Click on Load Balancer Settings, now you can see the id of the load balancer. Go to Products > Networking > Server Load Balancer, copy the IP address of your load balancer and add to your DNS records.

You can add a TLS certificate to the load balancer as well if you want.

Use Object Storage Service:

Probably you want to store files, so you need Alibaba Cloud Object Storage Service. You can create a bucket and connect your app to the service using official libraries:

https://github.com/aliyun/aliyun-oss-php-sdk-flysystem

Conclusion:

You have successfully containerized and deployed a Laravel application to Container Service and configured several Alibaba Cloud services to work together to provide a scalable and reliable infrastructure for your application. I hope this tutorial was useful for you!

2 Likes