bitbucket 部署
Over 100,000 GitHub repos have leaked API or cryptographic keys - ZDNet
超过100,000个GitHub存储库泄露了API或加密密钥-ZDNet
Hands up if this has happened to you. You're reading a well-written article on one of countless topics, and you get to the line that goes something like this:
如果这发生在您身上,请举起手来。 您正在阅读关于许多主题之一的写得很好的文章,并且您会得到如下内容:
// DO NOT DO THIS IN A PRODUCTION APP
const API_KEY = '<api-key-displayed-in-plain-text>'
Ok, so how should you be doing this? Unfortunately, there isn't a one-size-fits-all approach to securing your secrets. Different programming languages deployed in different environments all handle secrets in their own way.
好的,那你应该怎么做呢? 不幸的是,没有一种千篇一律的方法来保护您的秘密。 部署在不同环境中的不同编程语言都以自己的方式处理机密。
Suffice it to say that you should never store secrets in your code or repository. Secrets should be passed into your app through environment variables at the last possible moment.
可以说您永远不要在代码或存储库中存储机密。 机密应该在最后可能的时候通过环境变量传递到您的应用程序中。
Bitbucket管道-连续交付 (Bitbucket Pipelines - Continuous Delivery)
I have been using Bitbucket Pipelines since it was in Alpha and I have to say, it's fantastic. It has to be the quickest and easiest way to setup continuous delivery right from your repo.
自从它在Alpha以来,我就一直在使用Bitbucket Pipelines ,我不得不说,这太棒了。 它必须是从回购中设置连续交付的最快,最简单的方法。
Pipelines are configured with YAML files and can be very simple or extremely complex depending on your needs.
管道使用YAML文件进行配置,根据您的需要,管道可以非常简单或极其复杂。
管道配置 (Pipelines Configuration)
I like to break up my build jobs into steps for a couple of reasons:
我喜欢将构建工作分解为几个步骤,原因如下:
- If a step fails, you can re-run individual steps. 如果某个步骤失败,则可以重新运行各个步骤。
- Each step is isolated from the others. Only your base repo and any "artifacts" you declare will be passed to the next step. 每个步骤都与其他步骤隔离。 只有您的基本仓库和您声明的任何“工件”都将传递到下一步。
Here is a 3-step bitbucket-pipelines.yml file that takes a create-react-app site, packages it as a Docker image and deploys it to a Kubernetes cluster:
这是一个三步的bitbucket-pipelines.yml文件,该文件带有一个create-react-app站点,将其打包为Docker映像并将其部署到Kubernetes集群:
options:
# Enable docker for the Pipeline
docker: true
pipelines:
branches:
master:
- step:
name: Build app for Production (create-react-app)
image: mhart/alpine-node:10
caches:
- node
script:
# Install Dependencies
- npm install
# Run our Tests
- npm run test
# Package App for Production
- npm run build
artifacts:
# Pass the "build" Directory to the Next Step
- build/**
- step:
name: Build Docker Image
script:
# NOTE: Set $DOCKER_HUB_USERNAME and $DOCKER_HUB_PASSWORD as environment SECRETS in Bitbucket repository settings
# Use $BITBUCKET_COMMIT to tag our docker image
- export IMAGE_NAME=<docker-username>/<docker-image>:$BITBUCKET_COMMIT
# Build the Docker image (this will use the Dockerfile in the root of the repo)
- docker build -t $IMAGE_NAME .
# Authenticate with the Docker Hub registry
- docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD
# Push the new Docker image to the Docker registry
- docker push $IMAGE_NAME
- step:
# trigger: manual
name: Deploy to Kubernetes
image: atlassian/pipelines-kubectl
script:
# NOTE: $KUBECONFIG is secret stored as a base64 encoded string
# Base64 decode our kubeconfig file into a temporary kubeconfig.yml file (this will be destroyed automatically after this step runs)
- echo $KUBECONFIG | base64 -d > kubeconfig.yml
# Tell our Kubernetes deployment to use the new Docker image tag
- kubectl --kubeconfig=kubeconfig.yml --namespace=<namespace> set image deployment/<deployment-name> <deployment-name>=<docker-username>/<docker-image>:$BITBUCKET_COMMIT
bitbucket-pipelines.yml
bitbucket-pipelines.yml
FROM mhart/alpine-node:10
WORKDIR /app
EXPOSE 5000
# Install http server
RUN yarn global add serve
# Bundle app source
COPY build /app/build
# Run serve
CMD [ "serve", "-n", "-s", "build" ]
Dockerfile
Docker文件
Here's the important part of all that:
这是所有重要的部分:
- echo $KUBECONFIG | base64 -d > kubeconfig.yml
Our kubeconfig file is stored as a Base64 encoded string in a Bitbucket secret named $KUBECONFIG
.
我们的kubeconfig文件作为Base64编码的字符串存储在名为$KUBECONFIG
的Bitbucket密钥中。
Bitbucket secrets are stored encrypted, and decrypted when you call the variable in pipelines.
当您在管道中调用变量时,Bitbucket机密将以加密方式存储和解密。
We decode the $KUBECONFIG
variable and store it in a temporary file called kubeconfig.yml which is automatically deleted as soon as this step completes.
我们解码$KUBECONFIG
变量并将其存储在名为kubeconfig.yml的临时文件中,此步骤完成后会自动将其删除。
分解 (Breaking it Down)
第1步 (Step 1)
- Install dependencies 安装依赖项
- Run tests 运行测试
- Build 建立
- Pass build directory to Step 2 将构建目录传递到步骤2
第2步 (Step 2)
- Name Docker image 命名Docker映像
- Build Docker image 构建Docker映像
- Push image to Docker Hub 将映像推送到Docker Hub
第三步 (Step 3)
- Decode kubeconfig 解码kubeconfig
- Set deployment image 设置部署映像
建立绩效 (Build Performance)
This entire build takes less than 1 minute 40 seconds and using Alpine Node the Docker image is just 29 MB.
整个构建过程耗时不到1分钟40秒,使用Alpine Node的Docker映像仅为29 MB。
结论 (Conclusion)
Securing your secrets isn't hard, but it starts with knowing where to look.
保护您的秘密并不难,但是首先要知道在哪里寻找。
Some tips for securing secrets in different Node.js environments:
在不同的Node.js环境中保护机密的一些技巧:
- Node.js (Development): use .env files and .gitignore to keep .env files out of your repository. Node.js(开发):使用.env文件和.gitignore将.env文件保留在存储库之外。
- Node.js (Production): use Kubernetes Secrets, Docker Secrets and pass as environment variables into the container. Node.js(生产):使用Kubernetes Secrets,Docker Secrets并将其作为环境变量传递到容器中。
记住这一规则: (Remember this one rule:)
- Don't store secrets in your code, your repository or your docker image. 不要将机密存储在代码,存储库或Docker映像中。
Happy coding!
编码愉快!
Originally published at Tueri.io
最初发表于Tueri.io
bitbucket 部署