You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We want a simplified setup of testing different ccc branches in-app without booting a local server to test PRs of ccc-server before they merge. Essentially, we want heroku-like deploys of branches for the app to use in dev.
Rather than bundle the code as an artifact (in #749), we could set up a system where a Caddy server listens for authenticated requests, pulls a matching tag from Docker Hub, boots the image, then exits. We need to integrate several components.
Thoughts and proposal below.
Step 1: Set Up the Wildcard DNS Record
Create a wildcard DNS record for *.branch.stolaf.api.frogpond.tech. Point it to the IP address of the server where Caddy will be running.
Set up a service that Caddy can query to validate incoming requests for TLS certificates. This service should run on our server at http://localhost:3000/validate.
importKoafrom'koa'importRouterfrom'koa-router'constapp=newKoa()constrouter=newRouter()constallowedHostnames=['*.branch.stolaf.api.frogpond.tech']constapiKey='OUR_API_KEY'// todorouter.get('/validate',asyncctx=>{consthostname=ctx.query.hostnameconstprovidedApiKey=ctx.headers['x-api-key']if(providedApiKey!==apiKey){ctx.status=403ctx.body='Invalid Request'return}if(!hostname||!allowedHostnames.includes(hostname)){ctx.status=400ctx.body='Invalid or unauthorized hostname'return}ctx.body='ok'})app.use(router.routes()).use(router.allowedMethods())app.listen(3000,()=>{console.log('Validation service running on port 3000')})
Step 4: Docker Management
Use Docker's api to manage containers.
importexpressfrom'express'importDockerfrom'dockerode'constapp=express()constdocker=newDocker()app.post('/deploy/:branch',async(req,res)=>{constbranch=req.params.branchconstimageName=`dockerhubusername/imagename:${branch}`try{conststream=awaitdocker.pull(imageName)docker.modem.followProgress(stream,async(err,output)=>{if(err)returnres.status(500).send(err)try{constcontainer=awaitdocker.createContainer({Image: imageName,name: `container-${branch}`,ExposedPorts: {"80/tcp": {}},HostConfig: {PortBindings: {"80/tcp": [{HostPort: "9000"}]}}})awaitcontainer.start()res.send(`Container for ${branch} started.`)}catch(err){res.status(500).send(err.toString())}},event=>{console.log(event)})}catch(error){res.status(500).send(error.toString())}})app.listen(9001,()=>{console.log('Deployment service running on port 9001')})
Step 5: Automate Stopping Containers
Stop and remove containers when they are no longer needed.
Step 6: Authentication
Ensure that only authorized requests can deploy new containers. We can use basic auth, JWT, or another method.
Install the jsonwebtoken and express-jwt packages.
Modify the deployment service to use JWT for authentication.
importexpressfrom'express'importDockerfrom'dockerode'importjwtfrom'jsonwebtoken'importexpressJwtfrom'express-jwt'constapp=express()constdocker=newDocker()constsecret='secret-key'app.use(expressJwt({ secret,algorithms: ['HS256']}).unless({path: ['/']}))app.post('/deploy/:branch',async(req,res)=>{constbranch=req.params.branchconstimageName=`dockerhubusername/ourimagename:${branch}`try{awaitnewPromise((resolve,reject)=>{docker.pull(imageName,(err,stream)=>{if(err)returnreject(err)docker.modem.followProgress(stream,onFinished,onProgress)functiononFinished(err,output){if(err)returnreject(err)docker.createContainer({Image: imageName,name: `container-${branch}`,ExposedPorts: {'80/tcp': {}},HostConfig: {PortBindings: {'80/tcp': [{HostPort: '9000'}]}}}).then(container=>{container.start()res.send(`Container for ${branch} started.`)resolve()}).catch(reject)}functiononProgress(event){console.log(event)}})})}catch(error){res.status(500).send(error.toString())}})app.listen(9001,()=>{console.log('Deployment service running on port 9001')})
Test the Authentication
curl -X POST http://frogpond:9001/deploy/branch \
-H "Authorization: Bearer JWT_TOKEN"
Step 7: Integration
Ensure that the Caddy server, validation service, and Docker deployment service are running and correctly configured.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
We want a simplified setup of testing different ccc branches in-app without booting a local server to test PRs of ccc-server before they merge. Essentially, we want heroku-like deploys of branches for the app to use in dev.
Rather than bundle the code as an artifact (in #749), we could set up a system where a Caddy server listens for authenticated requests, pulls a matching tag from Docker Hub, boots the image, then exits. We need to integrate several components.
Thoughts and proposal below.
Step 1: Set Up the Wildcard DNS Record
Create a wildcard DNS record for
*.branch.stolaf.api.frogpond.tech
. Point it to the IP address of the server where Caddy will be running.Step 2: Install and Configure Caddy
Follow the official instructions to install Caddy on our server.
Step 3: Create a Validation Endpoint
Set up a service that Caddy can query to validate incoming requests for TLS certificates. This service should run on our server at
http://localhost:3000/validate
.Step 4: Docker Management
Use Docker's api to manage containers.
Step 5: Automate Stopping Containers
Stop and remove containers when they are no longer needed.
Step 6: Authentication
Ensure that only authorized requests can deploy new containers. We can use basic auth, JWT, or another method.
jsonwebtoken
andexpress-jwt
packages.curl -X POST http://frogpond:9001/deploy/branch \ -H "Authorization: Bearer JWT_TOKEN"
Step 7: Integration
Ensure that the Caddy server, validation service, and Docker deployment service are running and correctly configured.
Beta Was this translation helpful? Give feedback.
All reactions