Video Transcript
Deploying Databases to Cycle
Hello everyone, thank you for joining me. In today's video we're going to be deploying databases to Cycle. For this example we'll deploy a basic MongoDB and MySQL setup as containers in an environment.
Importing the images
The first thing we want to do is get our images. Head over to Sources — we're going to pull both of these from Docker Hub.
- MongoDB: I'll pull
mongo:latest - MySQL: I'll pull
mysql:5.7
I don't love always pulling the latest tag because sometimes maintainers make changes I'm not expecting. I'll be reading from the MySQL documentation page, but in case we miss something I'm going to pin to 5.7.
If you're wondering where to find these image names and versions: go to Docker Hub, search for the image you want, and you'll see a summary of the tags as well as a tag navigation panel where you can filter and sort. There's also a nice section showing which tags are synonymous with latest — useful if you want to know what latest actually resolves to right now.
With our two images imported, let's create a new environment. I'll call it Production and create it.
Deploying MongoDB
First container up — MongoDB.
Container type and deployment strategy
Database containers are always stateful, so we'll select the stateful field.
For deployment strategy, with databases I generally use manual or highly available, depending on how I plan on treating each volume. The caveat is that each individual container instance gets its own volume. So if you're looking to do something like clustering or replication across multiple nodes, what you'll most likely want to do is create multiple separate containers with one instance each.
I like manual because if I do need to spin up a new instance, I can do it in a very granular way and have the most flexibility.
Server constraints
If I wanted to constrain which servers qualified for this container's deployment, I could use tags. I'm on our Dev cluster so the tags here are very QA-centric, so I won't use them now — but if you had a specific database server or set of database servers, you could add db tags (or whatever you want) and constrain instances to those servers.
Volumes
Cycle has identified both volumes the image defines. A few things to know:
- Volume size is a limit, not an allocation. Set it to how big you think the volume might eventually grow.
- It can be increased later, so make your best guess.
- Don't go too small — 1 GB is usually too tight. We've set the default to 5 GB. Make it as big as you think it might end up being, knowing that it won't immediately consume that disk space.
For this:
- Config DB: small
- Data DB: 15 GB (this is where the actual data lives)
Networking
Set public network to disable. We don't want to expose a database container to public networking — we just want other containers in the environment to talk to it. If you do have to take the public approach there are ways to do it, but the most secure option is to disable public networking.
Click Deploy.
Initial configuration
When setting up databases, take a quick look at the Docker Hub page — they're usually pretty explicit about values you need to set on first start. If you don't set them, the container might not start correctly or could initialize with values you're not expecting.
For MongoDB, we need to initialize a root username and password. Head to Config → Runtime, enable it, and set:
- Username:
user - Password:
example123
Save it.
Since none of the other containers in this environment are started yet, I'll just start all of them. You'll see Discovery come online first, then the image copies over to the server.
Note: The first time a container instance starts, the image has to copy from image storage to the server, so the first start takes a few moments longer. Subsequent restarts and stop/start actions will be much faster.
Once the copy completes, the container moves to running and then through its initial configuration. Once that's done, MongoDB is up — and if I had another container, I could connect to it for database interactions.
Deploying MySQL
Same flow as MongoDB:
- Stateful: yes
- Deployment strategy: manual
- Image: mysql:5.7 (from recent images)
- Volume: 15 GB
- Public networking: disabled
For MySQL, we need to set MYSQL_ROOT_PASSWORD. It also supports MYSQL_RANDOM_ROOT_PASSWORD for auto-generation, but I'll just set one explicitly.
Save and start. Once it logs "ready for connections," we're good.
Remote access via SFTP
One neat feature on Cycle is the Volumes tab — alongside configuration information, there's a Remote Access section.
For this demo I'll enable it with a raw password (call it super_safe_one). For production you can use SHA or MD5 hashes instead. Save.
Heads up: SFTP must be enabled at the server level too. Go to the server's Configure tab (which used to live under Settings, for those of you who've been around a while) and allow SFTP.
Over on the Instances tab, you'll now see an SFTP icon. Cycle exposes the credentials directly, and you can open the connection straight from the browser. Brave sometimes takes two clicks; other browsers handle it on the first try.
From there I can drag and drop a sample database — or a backup, or any files I want to push to a stateful instance. To turn off access, just disable the remote access toggle and the connection drops.
Override commands (the IPv6 fix)
One thing to know: MongoDB doesn't run on IPv6 by default — it binds to IPv4 only. If I try to talk to this container from another container in the environment, it'll fail because the container is reachable on its IPv6 address but Mongo isn't listening there.
There's a really clean workaround using overrides before you build a more official image.
Go to Config → Runtime → Overrides and set:
- Command path:
mongod(the executable) - Args: include
--ipv6and--bind_ip_all
Save the container.
Verifying it worked
To check, set the instance to SSH only, reset, and grab your SSH credentials. Install net-tools:
apt install net-tools
Then:
netstat -tlnp
Before the override, you'd see Mongo bound to IPv4 only. After the override, you'll see it bound to both IPv4 and IPv6 — which is what we want. A connection from any sibling container will now succeed regardless of which address space it comes in on.
Recap
We covered:
- Importing images from Docker Hub as Cycle sources
- Setting up stateful container deployments
- Deployment strategy choices and when to pick which
- Volume sizing (limits, not allocations)
- Disabling public networking for security
- Setting initial database credentials via runtime config
- Enabling remote access to volumes via SFTP
- Using command overrides to fix runtime issues like IPv6 binding
If you're running a database in production, I'd suggest baking these overrides into a custom image — it's straightforward and gives you a cleaner deployment story.
Thanks so much for joining. Like and subscribe for more.