We'll now look at an op to run a sample Go application. Please see the code at https://github.com/opctl/opctl/tree/master/examples/run-a-go-service The sample application we have requires a mysql database, therefore to run it locally we need to: 1. Start a MySQL database with some DB credentials 2. (optional) Seed the DB with sample data 3. Start the application and provide the MySQL DB credentials as inputs - our application will read those from environment variables
The ops to make that happen are explained below.
This op will run a MySQL database in a Docker container. It has an optional input,
doSeed, which is of type
true, it will run the
seed.sql script in a second, parallel container to seed the MySQL database in first container with a single table and a single row of data.
Note that instead of writing the
cmd inline, we could have also put the run script in a file in the op directory and referenced it.
This becomes useful for readability if the script we're running in a container is large.
Note that while we could have also built a custom docker image that contains that script and ran it, that's not a recommended practice. While the op remains portable with that approach, it is less transparent and harder to maintain, since we would have the extra step of building and pushing that image whenever we make a change to the script. Instead, we usually opt for the leanest Docker image that fulfills our use case, and include any scripts or binaries we need in the op directory.
This op will do the following, in parallel:
1. Run the mysql op, passing in the inputs needed to create it
2. run our service in the
golang container. We'll use reflex to make development easier and avoid having to restart the whole operation after every change to main.go
Now to run the service locally, we only run
opctl run dev
Notice how we can run ops in a
parallel block. Our app runs parallel to the MySQL DB container (via the
mysql op), because we need mysql running while our app runs.