How to deploy anything with Meteor-Up
I have grown to love the simplicity of deploying Meteor apps with Meteor-Up.
According to the website:
Meteor Up is a production quality tool to setup servers and deploy your Meteor apps to them
Its a fantastic tool to simplify deployment in my opinion.
I’ve noticed their plugins before, but have never tried to deploy anything other than a meteor project … so I decided to give it a try.
At first I attempted to use the mup-node plugin, but I quickly realised that since my app didn’t expose a listener on a port, like a typical express app, I wouldn’t be able publish it without failing at the verification step, so I changed tactics.
My next attempt was to use another plugin from their list: the mup-docker-deploy plugin. This one allows you to deploy from a Dockerfile, which translates into almost anything you might want to deploy. To generate my Dockerfile, I was lazy and captured the commands from my first try by running mup
in verbose mode and copying the steps from the log. The command for verbose mode is:
DEBUG=mup* mup deploy --verbose
And I ended up with a Dockerfile like this:
FROM node:15.8.0
RUN mkdir -p /home/node/app || true
WORKDIR /home/node/app
ENV NODE_ENV=production
COPY ./package.json ./package.json
COPY ./package-lock.json ./package-lock.json
RUN npm install --unsafe-perm
COPY ./ ./
CMD [ "npm", "run", "start" ]
I followed the instructions from the README and configured my .deploy/mup.js file:
module.exports = {
servers: {
one: {
host: 'my-domain.name',
username: 'root',
pem: '~/.ssh/id_rsa'
}
},
app: {
name: 'my-app-name',
path: '../',
type: 'docker-image',
env: {
PORT: process.env.PORT,
},
servers: {
one: {},
},
// docker: {
// imagePort: Number(process.env.IMAGE_PORT),
// },
},
// proxy: {
// servers: {
// one: {},
// },
// domains: "my-app.my-domain.name",
// },
plugins: ['mup-docker-deploy']
}
The important bits are:
type: 'docker-image',
env: { PORT: <number> },
(an available port on the host)plugins: ['mup-docker-deploy']
(this one was not obvious from the README file)docker.imagePort
if your app exposes a port from docker to be mapped to the host port, e.g. by reverse proxy
The last challenge I had was to send the environment variables to the docker container without storing any secrets in my code.
After trying a few things, I ended up with the following solution:
In my mup.js, I added the environment variables to the env
section with their values set them from the host environment, like so:
module.exports = {
...,
app: {
...,
env: {
SERVICE_KEY: process.env.SERVICE_KEY,
SERVICE_SECRET: process.env.SERVICE_SECRET,
}
}
}
Next to my mup.js, I then added a .env file containing the secrets and added the dependency with npm i -D dotenv
.
NOTE: Remember to add .env
to your .gitignore file to exclude it from source control.
Lastly, I added a line to the top of the mup.js file:
require('dotenv').config();
module.exports = {
...
}
Doing a deploy is now as simple as running mup deploy
from the .deploy folder.